C++ Reference

C++ Reference: Graph

graph.h
Go to the documentation of this file.
1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //
15 //
16 // This file defines a generic graph interface on which most algorithms can be
17 // built and provides a few efficient implementations with a fast construction
18 // time. Its design is based on the experience acquired by the Operations
19 // Research team in their various graph algorithm implementations.
20 //
21 // The main ideas are:
22 // - Graph nodes and arcs are represented by integers.
23 // - Node or arc annotations (weight, cost, ...) are not part of the graph
24 // class, they can be stored outside in one or more arrays and can be easily
25 // retrieved using a node or arc as an index.
26 //
27 // Terminology:
28 // - An arc of a graph is directed and going from a tail node to a head node.
29 // - Some implementations also store 'reverse' arcs and can be used for
30 // undirected graph or flow-like algorithm.
31 // - A node or arc index is 'valid' if it represents a node or arc of
32 // the graph. The validity ranges are always [0, num_nodes()) for nodes and
33 // [0, num_arcs()) for forward arcs. Reverse arcs are elements of
34 // [-num_arcs(), 0) and are also considered valid by the implementations that
35 // store them.
36 //
37 // Provided implementations:
38 // - ListGraph<> for the simplest api. Also aliased to util::Graph.
39 // - StaticGraph<> for performance, but require calling Build(), see below
40 // - CompleteGraph<> if you need a fully connected graph
41 // - CompleteBipartiteGraph<> if you need a fully connected bipartite graph
42 // - ReverseArcListGraph<> to add reverse arcs to ListGraph<>
43 // - ReverseArcStaticGraph<> to add reverse arcs to StaticGraph<>
44 // - ReverseArcMixedGraph<> for a smaller memory footprint
45 //
46 // Utility classes & functions:
47 // - Permute() to permute an array according to a given permutation.
48 // - SVector<> vector with index range [-size(), size()) for ReverseArcGraph.
49 //
50 // Basic usage:
51 // typedef ListGraph<> Graph; // Choose a graph implementation.
52 // Graph graph;
53 // for (...) {
54 // graph.AddArc(tail, head);
55 // }
56 // ...
57 // for (int node = 0; node < graph.num_nodes(); ++node) {
58 // for (const int arc : graph.OutgoingArcs(node)) {
59 // head = graph.Head(arc);
60 // tail = node; // or graph.Tail(arc) which is fast but not as much.
61 // }
62 // }
63 //
64 // Iteration over the arcs touching a node:
65 //
66 // - OutgoingArcs(node): All the forward arcs leaving the node.
67 // - IncomingArcs(node): All the forward arcs arriving at the node.
68 //
69 // And two more involved ones:
70 //
71 // - OutgoingOrOppositeIncomingArcs(node): This returns both the forward arcs
72 // leaving the node (i.e. OutgoingArcs(node)) and the reverse arcs leaving the
73 // node (i.e. the opposite arcs of the ones returned by IncomingArcs(node)).
74 // - OppositeIncomingArcs(node): This returns the reverse arcs leaving the node.
75 //
76 // Note on iteration efficiency: When re-indexing the arcs it is not possible to
77 // have both the outgoing arcs and the incoming ones form a consecutive range.
78 //
79 // It is however possible to do so for the outgoing arcs and the opposite
80 // incoming arcs. It is why the OutgoingOrOppositeIncomingArcs() and
81 // OutgoingArcs() iterations are more efficient than the IncomingArcs() one.
82 //
83 // If you know the graph size in advance, this already set the number of nodes,
84 // reserve space for the arcs and check in DEBUG mode that you don't go over the
85 // bounds:
86 // Graph graph(num_nodes, arc_capacity);
87 //
88 // Storing and using node annotations:
89 // vector<bool> is_visited(graph.num_nodes(), false);
90 // ...
91 // for (int node = 0; node < graph.num_nodes(); ++node) {
92 // if (!is_visited[node]) ...
93 // }
94 //
95 // Storing and using arc annotations:
96 // vector<int> weights;
97 // for (...) {
98 // graph.AddArc(tail, head);
99 // weights.push_back(arc_weight);
100 // }
101 // ...
102 // for (const int arc : graph.OutgoingArcs(node)) {
103 // ... weights[arc] ...;
104 // }
105 //
106 // More efficient version:
107 // typedef StaticGraph<> Graph;
108 // Graph graph(num_nodes, arc_capacity); // Optional, but help memory usage.
109 // vector<int> weights;
110 // weights.reserve(arc_capacity); // Optional, but help memory usage.
111 // for (...) {
112 // graph.AddArc(tail, head);
113 // weights.push_back(arc_weight);
114 // }
115 // ...
116 // vector<Graph::ArcIndex> permutation;
117 // graph.Build(&permutation); // A static graph must be Build() before usage.
118 // Permute(permutation, &weights); // Build() may permute the arc index.
119 // ...
120 //
121 // Encoding an undirected graph: If you don't need arc annotation, then the best
122 // is to add two arcs for each edge (one in each direction) to a directed graph.
123 // Otherwise you can do the following.
124 //
125 // typedef ReverseArc... Graph;
126 // Graph graph;
127 // for (...) {
128 // graph.AddArc(tail, head); // or graph.AddArc(head, tail) but not both.
129 // edge_annotations.push_back(value);
130 // }
131 // ...
132 // for (const Graph::NodeIndex node : graph.AllNodes()) {
133 // for (const Graph::ArcIndex arc :
134 // graph.OutgoingOrOppositeIncomingArcs(node)) {
135 // destination = graph.Head(arc);
136 // annotation = edge_annotations[arc < 0 ? graph.OppositeArc(arc) : arc];
137 // }
138 // }
139 //
140 //
141 // Note: The graphs are primarily designed to be constructed first and then used
142 // because it covers most of the use cases. It is possible to extend the
143 // interface with more dynamicity (like removing arcs), but this is not done at
144 // this point. Note that a "dynamic" implementation will break some assumptions
145 // we make on what node or arc are valid and also on the indices returned by
146 // AddArc(). Some arguments for simplifying the interface at the cost of
147 // dynamicity are:
148 //
149 // - It is always possible to construct a static graph from a dynamic one
150 // before calling a complex algo.
151 // - If you really need a dynamic graph, maybe it is better to compute a graph
152 // property incrementally rather than calling an algorithm that starts from
153 // scratch each time.
154 
155 #ifndef UTIL_GRAPH_GRAPH_H_
156 #define UTIL_GRAPH_GRAPH_H_
157 
158 #include <algorithm>
159 #include <cstddef>
160 #include <cstdint>
161 #include <cstdlib>
162 #include <limits>
163 #include <new>
164 #include <vector>
165 
166 #include "absl/debugging/leak_check.h"
167 #include "ortools/base/integral_types.h"
168 #include "ortools/base/logging.h"
169 #include "ortools/base/macros.h"
170 #include "ortools/graph/iterators.h"
171 
172 namespace util {
173 
174 // Forward declaration.
175 template <typename T>
176 class SVector;
177 
178 // Base class of all Graphs implemented here. The default value for the graph
179 // index types is int32_t since allmost all graphs that fit into memory do not
180 // need bigger indices.
181 //
182 // Note: The type can be unsigned, except for the graphs with reverse arcs
183 // where the ArcIndexType must be signed, but not necessarly the NodeIndexType.
184 template <typename NodeIndexType = int32_t, typename ArcIndexType = int32_t,
185  bool HasReverseArcs = false>
186 class BaseGraph {
187  public:
188  // Typedef so you can use Graph::NodeIndex and Graph::ArcIndex to be generic
189  // but also to improve the readability of your code. We also recommend
190  // that you define a typedef ... Graph; for readability.
191  typedef NodeIndexType NodeIndex;
192  typedef ArcIndexType ArcIndex;
193 
195  : num_nodes_(0),
196  node_capacity_(0),
197  num_arcs_(0),
198  arc_capacity_(0),
199  const_capacities_(false) {}
200  virtual ~BaseGraph() {}
201 
202  // Returns the number of valid nodes in the graph.
203  NodeIndexType num_nodes() const { return num_nodes_; }
204 
205  // Returns the number of valid arcs in the graph.
206  ArcIndexType num_arcs() const { return num_arcs_; }
207 
208  // Allows nice range-based for loop:
209  // for (const NodeIndex node : graph.AllNodes()) { ... }
210  // for (const ArcIndex arc : graph.AllForwardArcs()) { ... }
213 
214  // Returns true if the given node is a valid node of the graph.
215  bool IsNodeValid(NodeIndexType node) const {
216  return node >= 0 && node < num_nodes_;
217  }
218 
219  // Returns true if the given arc is a valid arc of the graph.
220  // Note that the arc validity range changes for graph with reverse arcs.
221  bool IsArcValid(ArcIndexType arc) const {
222  return (HasReverseArcs ? -num_arcs_ : 0) <= arc && arc < num_arcs_;
223  }
224 
225  // Capacity reserved for future nodes, always >= num_nodes_.
226  NodeIndexType node_capacity() const;
227 
228  // Capacity reserved for future arcs, always >= num_arcs_.
229  ArcIndexType arc_capacity() const;
230 
231  // Changes the graph capacities. The functions will fail in debug mode if:
232  // - const_capacities_ is true.
233  // - A valid node does not fall into the new node range.
234  // - A valid arc does not fall into the new arc range.
235  // In non-debug mode, const_capacities_ is ignored and nothing will happen
236  // if the new capacity value for the arcs or the nodes is too small.
237  virtual void ReserveNodes(NodeIndexType bound) {
238  DCHECK(!const_capacities_);
239  DCHECK_GE(bound, num_nodes_);
240  if (bound <= num_nodes_) return;
241  node_capacity_ = bound;
242  }
243  virtual void ReserveArcs(ArcIndexType bound) {
244  DCHECK(!const_capacities_);
245  DCHECK_GE(bound, num_arcs_);
246  if (bound <= num_arcs_) return;
247  arc_capacity_ = bound;
248  }
249  void Reserve(NodeIndexType node_capacity, ArcIndexType arc_capacity) {
252  }
253 
254  // FreezeCapacities() makes any future attempt to change the graph capacities
255  // crash in DEBUG mode.
257 
258  // Constants that will never be a valid node or arc.
259  // They are the maximum possible node and arc capacity.
260  static const NodeIndexType kNilNode;
261  static const ArcIndexType kNilArc;
262 
263  // TODO(user): remove the public functions below. They are just here during
264  // the transition from the old ebert_graph api to this new graph api.
265  template <typename A, typename B>
266  void GroupForwardArcsByFunctor(const A& a, B* b) {
267  LOG(FATAL) << "Not supported";
268  }
269  ArcIndexType max_end_arc_index() const { return arc_capacity_; }
270 
271  protected:
272  // Functions commented when defined because they are implementation details.
273  void ComputeCumulativeSum(std::vector<ArcIndexType>* v);
275  std::vector<ArcIndexType>* start,
276  std::vector<ArcIndexType>* permutation);
277 
278  NodeIndexType num_nodes_;
279  NodeIndexType node_capacity_;
280  ArcIndexType num_arcs_;
281  ArcIndexType arc_capacity_;
283 };
284 
285 // Basic graph implementation without reverse arc. This class also serves as a
286 // documentation for the generic graph interface (minus the part related to
287 // reverse arcs).
288 //
289 // This implementation uses a linked list and compared to StaticGraph:
290 // - Is a bit faster to construct (if the arcs are not ordered by tail).
291 // - Does not require calling Build().
292 // - Has slower outgoing arc iteration.
293 // - Uses more memory: ArcIndexType * node_capacity()
294 // + (ArcIndexType + NodeIndexType) * arc_capacity().
295 // - Has an efficient Tail() but need an extra NodeIndexType/arc memory for it.
296 // - Never changes the initial arc index returned by AddArc().
297 //
298 template <typename NodeIndexType = int32_t, typename ArcIndexType = int32_t>
299 class ListGraph : public BaseGraph<NodeIndexType, ArcIndexType, false> {
301  using Base::arc_capacity_;
303  using Base::node_capacity_;
304  using Base::num_arcs_;
305  using Base::num_nodes_;
306 
307  public:
308  using Base::IsArcValid;
310 
311  // Reserve space for the graph at construction and do not allow it to grow
312  // beyond that, see FreezeCapacities(). This constructor also makes any nodes
313  // in [0, num_nodes) valid.
314  ListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity) {
315  this->Reserve(num_nodes, arc_capacity);
316  this->FreezeCapacities();
317  this->AddNode(num_nodes - 1);
318  }
319 
320  // If node is not a valid node, sets num_nodes_ to node + 1 so that the given
321  // node becomes valid. It will fail in DEBUG mode if the capacities are fixed
322  // and the new node is out of range.
323  void AddNode(NodeIndexType node);
324 
325  // Adds an arc to the graph and returns its current index which will always
326  // be num_arcs() - 1. It will also automatically call AddNode(tail)
327  // and AddNode(head). It will fail in DEBUG mode if the capacities
328  // are fixed and this cause the graph to grow beyond them.
329  //
330  // Note: Self referencing arcs and duplicate arcs are supported.
331  ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head);
332 
333  // Some graph implementations need to be finalized with Build() before they
334  // can be used. After Build() is called, the arc indices (which had been the
335  // return values of previous AddArc() calls) may change: the new index of
336  // former arc #i will be stored in permutation[i] if #i is smaller than
337  // permutation.size() or will be unchanged otherwise. If you don't care about
338  // these, just call the simple no-output version Build().
339  //
340  // Note that some implementations become immutable after calling Build().
341  void Build() { Build(nullptr); }
342  void Build(std::vector<ArcIndexType>* permutation);
343 
344  // Do not use directly.
345  class OutgoingArcIterator;
346  class OutgoingHeadIterator;
347 
348  // Graph jargon: the "degree" of a node is its number of arcs. The out-degree
349  // is the number of outgoing arcs. The in-degree is the number of incoming
350  // arcs, and is only available for some graph implementations, below.
351  //
352  // ListGraph<>::OutDegree() works in O(degree).
353  ArcIndexType OutDegree(NodeIndexType node) const;
354 
355  // Allows to iterate over the forward arcs that verify Tail(arc) == node.
356  // This is meant to be used as:
357  // for (const ArcIndex arc : graph.OutgoingArcs(node)) { ... }
359 
360  // Advanced usage. Same as OutgoingArcs(), but allows to restart the iteration
361  // from an already known outgoing arc of the given node.
363  NodeIndexType node, ArcIndexType from) const;
364 
365  // This loops over the heads of the OutgoingArcs(node). It is just a more
366  // convenient way to achieve this. Moreover this interface is used by some
367  // graph algorithms.
368  BeginEndWrapper<OutgoingHeadIterator> operator[](NodeIndexType node) const;
369 
370  // Returns the tail/head of a valid arc.
371  NodeIndexType Tail(ArcIndexType arc) const;
372  NodeIndexType Head(ArcIndexType arc) const;
373 
374  void ReserveNodes(NodeIndexType bound) override;
375  void ReserveArcs(ArcIndexType bound) override;
376 
377  private:
378  std::vector<ArcIndexType> start_;
379  std::vector<ArcIndexType> next_;
380  std::vector<NodeIndexType> head_;
381  std::vector<NodeIndexType> tail_;
382 };
383 
384 // Most efficient implementation of a graph without reverse arcs:
385 // - Build() needs to be called after the arc and node have been added.
386 // - The graph is really compact memory wise:
387 // ArcIndexType * node_capacity() + 2 * NodeIndexType * arc_capacity(),
388 // but when Build() is called it uses a temporary extra space of
389 // ArcIndexType * arc_capacity().
390 // - The construction is really fast.
391 //
392 // NOTE(user): if the need arises for very-well compressed graphs, we could
393 // shave NodeIndexType * arc_capacity() off the permanent memory requirement
394 // with a similar class that doesn't support Tail(), i.e.
395 // StaticGraphWithoutTail<>. This almost corresponds to a past implementation
396 // of StaticGraph<> @CL 116144340.
397 template <typename NodeIndexType = int32_t, typename ArcIndexType = int32_t>
398 class StaticGraph : public BaseGraph<NodeIndexType, ArcIndexType, false> {
400  using Base::arc_capacity_;
402  using Base::node_capacity_;
403  using Base::num_arcs_;
404  using Base::num_nodes_;
405 
406  public:
407  using Base::IsArcValid;
408  StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
409  StaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
410  : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
411  this->Reserve(num_nodes, arc_capacity);
412  this->FreezeCapacities();
413  this->AddNode(num_nodes - 1);
414  }
415 
416  // Do not use directly. See instead the arc iteration functions below.
417  class OutgoingArcIterator;
418 
419  NodeIndexType Head(ArcIndexType arc) const;
420  NodeIndexType Tail(ArcIndexType arc) const;
421  ArcIndexType OutDegree(NodeIndexType node) const; // Work in O(1).
424  NodeIndexType node, ArcIndexType from) const;
425 
426  // This loops over the heads of the OutgoingArcs(node). It is just a more
427  // convenient way to achieve this. Moreover this interface is used by some
428  // graph algorithms.
429  BeginEndWrapper<NodeIndexType const*> operator[](NodeIndexType node) const;
430 
431  void ReserveNodes(NodeIndexType bound) override;
432  void ReserveArcs(ArcIndexType bound) override;
433  void AddNode(NodeIndexType node);
434  ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head);
435 
436  void Build() { Build(nullptr); }
437  void Build(std::vector<ArcIndexType>* permutation);
438 
439  private:
440  ArcIndexType DirectArcLimit(NodeIndexType node) const {
441  DCHECK(is_built_);
442  DCHECK(Base::IsNodeValid(node));
443  return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
444  }
445 
446  bool is_built_;
447  bool arc_in_order_;
448  NodeIndexType last_tail_seen_;
449  std::vector<ArcIndexType> start_;
450  std::vector<NodeIndexType> head_;
451  std::vector<NodeIndexType> tail_;
452 };
453 
454 // Extends the ListGraph by also storing the reverse arcs.
455 // This class also documents the Graph interface related to reverse arc.
456 // - NodeIndexType can be unsigned, but ArcIndexType must be signed.
457 // - It has most of the same advantanges and disadvantages as ListGraph.
458 // - It takes 2 * ArcIndexType * node_capacity()
459 // + 2 * (ArcIndexType + NodeIndexType) * arc_capacity() memory.
460 template <typename NodeIndexType = int32_t, typename ArcIndexType = int32_t>
462  : public BaseGraph<NodeIndexType, ArcIndexType, true> {
464  using Base::arc_capacity_;
466  using Base::node_capacity_;
467  using Base::num_arcs_;
468  using Base::num_nodes_;
469 
470  public:
471  using Base::IsArcValid;
473  ReverseArcListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity) {
474  this->Reserve(num_nodes, arc_capacity);
475  this->FreezeCapacities();
476  this->AddNode(num_nodes - 1);
477  }
478 
479  // Returns the opposite arc of a given arc. That is the reverse arc of the
480  // given forward arc or the forward arc of a given reverse arc.
481  ArcIndexType OppositeArc(ArcIndexType arc) const;
482 
483  // Do not use directly. See instead the arc iteration functions below.
484  class OutgoingOrOppositeIncomingArcIterator;
485  class OppositeIncomingArcIterator;
486  class IncomingArcIterator;
487  class OutgoingArcIterator;
488  class OutgoingHeadIterator;
489 
490  // ReverseArcListGraph<>::OutDegree() and ::InDegree() work in O(degree).
491  ArcIndexType OutDegree(NodeIndexType node) const;
492  ArcIndexType InDegree(NodeIndexType node) const;
493 
494  // Arc iterations functions over the arcs touching a node (see the top-level
495  // comment for the different types). To be used as follows:
496  // for (const Graph::ArcIndex arc : IterationFunction(node)) { ... }
497  //
498  // The StartingFrom() version are similar, but restart the iteration from a
499  // given arc position (which must be valid in the iteration context).
503  OutgoingOrOppositeIncomingArcs(NodeIndexType node) const;
505  NodeIndexType node) const;
507  NodeIndexType node, ArcIndexType from) const;
509  NodeIndexType node, ArcIndexType from) const;
512  ArcIndexType from) const;
514  NodeIndexType node, ArcIndexType from) const;
515 
516  // This loops over the heads of the OutgoingArcs(node). It is just a more
517  // convenient way to achieve this. Moreover this interface is used by some
518  // graph algorithms.
519  BeginEndWrapper<OutgoingHeadIterator> operator[](NodeIndexType node) const;
520 
521  NodeIndexType Head(ArcIndexType arc) const;
522  NodeIndexType Tail(ArcIndexType arc) const;
523 
524  void ReserveNodes(NodeIndexType bound) override;
525  void ReserveArcs(ArcIndexType bound) override;
526  void AddNode(NodeIndexType node);
527  ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head);
528 
529  void Build() { Build(nullptr); }
530  void Build(std::vector<ArcIndexType>* permutation);
531 
532  private:
533  std::vector<ArcIndexType> start_;
534  std::vector<ArcIndexType> reverse_start_;
535  SVector<ArcIndexType> next_;
537 };
538 
539 // StaticGraph with reverse arc.
540 // - NodeIndexType can be unsigned, but ArcIndexType must be signed.
541 // - It has most of the same advantanges and disadvantages as StaticGraph.
542 // - It takes 2 * ArcIndexType * node_capacity()
543 // + 2 * (ArcIndexType + NodeIndexType) * arc_capacity() memory.
544 // - If the ArcIndexPermutation is needed, then an extra ArcIndexType *
545 // arc_capacity() is needed for it.
546 // - The reverse arcs from a node are sorted by head (so we could add a log()
547 // time lookup function).
548 template <typename NodeIndexType = int32_t, typename ArcIndexType = int32_t>
550  : public BaseGraph<NodeIndexType, ArcIndexType, true> {
552  using Base::arc_capacity_;
554  using Base::node_capacity_;
555  using Base::num_arcs_;
556  using Base::num_nodes_;
557 
558  public:
559  using Base::IsArcValid;
560  ReverseArcStaticGraph() : is_built_(false) {}
561  ReverseArcStaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
562  : is_built_(false) {
563  this->Reserve(num_nodes, arc_capacity);
564  this->FreezeCapacities();
565  this->AddNode(num_nodes - 1);
566  }
567 
568  // Deprecated.
569  class OutgoingOrOppositeIncomingArcIterator;
570  class OppositeIncomingArcIterator;
571  class IncomingArcIterator;
572  class OutgoingArcIterator;
573 
574  // ReverseArcStaticGraph<>::OutDegree() and ::InDegree() work in O(1).
575  ArcIndexType OutDegree(NodeIndexType node) const;
576  ArcIndexType InDegree(NodeIndexType node) const;
577 
581  OutgoingOrOppositeIncomingArcs(NodeIndexType node) const;
583  NodeIndexType node) const;
585  NodeIndexType node, ArcIndexType from) const;
587  NodeIndexType node, ArcIndexType from) const;
590  ArcIndexType from) const;
592  NodeIndexType node, ArcIndexType from) const;
593 
594  // This loops over the heads of the OutgoingArcs(node). It is just a more
595  // convenient way to achieve this. Moreover this interface is used by some
596  // graph algorithms.
597  BeginEndWrapper<NodeIndexType const*> operator[](NodeIndexType node) const;
598 
599  ArcIndexType OppositeArc(ArcIndexType arc) const;
600  // TODO(user): support Head() and Tail() before Build(), like StaticGraph<>.
601  NodeIndexType Head(ArcIndexType arc) const;
602  NodeIndexType Tail(ArcIndexType arc) const;
603 
604  void ReserveArcs(ArcIndexType bound) override;
605  void AddNode(NodeIndexType node);
606  ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head);
607 
608  void Build() { Build(nullptr); }
609  void Build(std::vector<ArcIndexType>* permutation);
610 
611  private:
612  ArcIndexType DirectArcLimit(NodeIndexType node) const {
613  DCHECK(is_built_);
614  DCHECK(Base::IsNodeValid(node));
615  return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
616  }
617  ArcIndexType ReverseArcLimit(NodeIndexType node) const {
618  DCHECK(is_built_);
619  DCHECK(Base::IsNodeValid(node));
620  return node + 1 < num_nodes_ ? reverse_start_[node + 1] : 0;
621  }
622 
623  bool is_built_;
624  std::vector<ArcIndexType> start_;
625  std::vector<ArcIndexType> reverse_start_;
626  SVector<NodeIndexType> head_;
627  SVector<ArcIndexType> opposite_;
628 };
629 
630 // This graph is a mix between the ReverseArcListGraph and the
631 // ReverseArcStaticGraph. It uses less memory:
632 // - It takes 2 * ArcIndexType * node_capacity()
633 // + (2 * NodeIndexType + ArcIndexType) * arc_capacity() memory.
634 // - If the ArcIndexPermutation is needed, then an extra ArcIndexType *
635 // arc_capacity() is needed for it.
636 template <typename NodeIndexType = int32_t, typename ArcIndexType = int32_t>
638  : public BaseGraph<NodeIndexType, ArcIndexType, true> {
640  using Base::arc_capacity_;
642  using Base::node_capacity_;
643  using Base::num_arcs_;
644  using Base::num_nodes_;
645 
646  public:
647  using Base::IsArcValid;
648  ReverseArcMixedGraph() : is_built_(false) {}
649  ReverseArcMixedGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
650  : is_built_(false) {
651  this->Reserve(num_nodes, arc_capacity);
652  this->FreezeCapacities();
653  this->AddNode(num_nodes - 1);
654  }
655 
656  // Deprecated.
657  class OutgoingOrOppositeIncomingArcIterator;
658  class OppositeIncomingArcIterator;
659  class IncomingArcIterator;
660  class OutgoingArcIterator;
661 
662  ArcIndexType OutDegree(NodeIndexType node) const; // O(1)
663  ArcIndexType InDegree(NodeIndexType node) const; // O(in-degree)
664 
668  OutgoingOrOppositeIncomingArcs(NodeIndexType node) const;
670  NodeIndexType node) const;
672  NodeIndexType node, ArcIndexType from) const;
674  NodeIndexType node, ArcIndexType from) const;
677  ArcIndexType from) const;
679  NodeIndexType node, ArcIndexType from) const;
680 
681  // This loops over the heads of the OutgoingArcs(node). It is just a more
682  // convenient way to achieve this. Moreover this interface is used by some
683  // graph algorithms.
684  BeginEndWrapper<NodeIndexType const*> operator[](NodeIndexType node) const;
685 
686  ArcIndexType OppositeArc(ArcIndexType arc) const;
687  // TODO(user): support Head() and Tail() before Build(), like StaticGraph<>.
688  NodeIndexType Head(ArcIndexType arc) const;
689  NodeIndexType Tail(ArcIndexType arc) const;
690 
691  void ReserveArcs(ArcIndexType bound) override;
692  void AddNode(NodeIndexType node);
693  ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head);
694 
695  void Build() { Build(nullptr); }
696  void Build(std::vector<ArcIndexType>* permutation);
697 
698  private:
699  ArcIndexType DirectArcLimit(NodeIndexType node) const {
700  DCHECK(is_built_);
701  DCHECK(Base::IsNodeValid(node));
702  return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
703  }
704 
705  bool is_built_;
706  std::vector<ArcIndexType> start_;
707  std::vector<ArcIndexType> reverse_start_;
708  std::vector<ArcIndexType> next_;
709  SVector<NodeIndexType> head_;
710 };
711 
712 // Permutes the elements of array_to_permute: element #i will be moved to
713 // position permutation[i]. permutation must be either empty (in which case
714 // nothing happens), or a permutation of [0, permutation.size()).
715 //
716 // The algorithm is fast but need extra memory for a copy of the permuted part
717 // of array_to_permute.
718 //
719 // TODO(user): consider slower but more memory efficient implementations that
720 // follow the cycles of the permutation and use a bitmap to indicate what has
721 // been permuted or to mark the beginning of each cycle.
722 
723 // Some compiler do not know typeof(), so we have to use this extra function
724 // internally.
725 template <class IntVector, class Array, class ElementType>
726 void PermuteWithExplicitElementType(const IntVector& permutation,
727  Array* array_to_permute,
728  ElementType unused) {
729  std::vector<ElementType> temp(permutation.size());
730  for (int i = 0; i < permutation.size(); ++i) {
731  temp[i] = (*array_to_permute)[i];
732  }
733  for (int i = 0; i < permutation.size(); ++i) {
734  (*array_to_permute)[permutation[i]] = temp[i];
735  }
736 }
737 
738 template <class IntVector, class Array>
739 void Permute(const IntVector& permutation, Array* array_to_permute) {
740  if (permutation.empty()) {
741  return;
742  }
743  PermuteWithExplicitElementType(permutation, array_to_permute,
744  (*array_to_permute)[0]);
745 }
746 
747 // We need a specialization for vector<bool>, because the default code uses
748 // (*array_to_permute)[0] as ElementType, which isn't 'bool' in that case.
749 template <class IntVector>
750 void Permute(const IntVector& permutation,
751  std::vector<bool>* array_to_permute) {
752  if (permutation.empty()) {
753  return;
754  }
755  bool unused = false;
756  PermuteWithExplicitElementType(permutation, array_to_permute, unused);
757 }
758 
759 // A vector-like class where valid indices are in [- size_, size_) and reserved
760 // indices for future growth are in [- capacity_, capacity_). It is used to hold
761 // arc related information for graphs with reverse arcs.
762 // It supports only up to 2^31-1 elements, for compactness. If you ever need
763 // more, consider using templates for the size/capacity integer types.
764 //
765 // Sample usage:
766 //
767 // SVector<int> v;
768 // v.grow(left_value, right_value);
769 // v.resize(10);
770 // v.clear();
771 // v.swap(new_v);
772 // std:swap(v[i], v[~i]);
773 template <typename T>
774 class SVector {
775  public:
776  SVector() : base_(nullptr), size_(0), capacity_(0) {}
777 
779 
780  // Copy constructor and assignment operator.
781  SVector(const SVector& other) : SVector() { *this = other; }
782  SVector& operator=(const SVector& other) {
783  if (capacity_ < other.size_) {
785  // NOTE(user): Alternatively, our capacity could inherit from the other
786  // vector's capacity, which can be (much) greater than its size.
787  capacity_ = other.size_;
788  base_ = Allocate(capacity_);
789  CHECK(base_ != nullptr);
790  base_ += capacity_;
791  } else { // capacity_ >= other.size
792  clear();
793  }
794  // Perform the actual copy of the payload.
795  size_ = other.size_;
796  for (int i = -size_; i < size_; ++i) {
797  new (base_ + i) T(other.base_[i]);
798  }
799  return *this;
800  }
801 
802  // Move constructor and move assignment operator.
803  SVector(SVector&& other) : SVector() { swap(other); }
805  // NOTE(user): We could just swap() and let the other's destruction take
806  // care of the clean-up, but it is probably less bug-prone to perform the
807  // destruction immediately.
809  swap(other);
810  return *this;
811  }
812 
813  T& operator[](int n) {
814  DCHECK_LT(n, size_);
815  DCHECK_GE(n, -size_);
816  return base_[n];
817  }
818 
819  const T& operator[](int n) const {
820  DCHECK_LT(n, size_);
821  DCHECK_GE(n, -size_);
822  return base_[n];
823  }
824 
825  void resize(int n) {
826  reserve(n);
827  for (int i = -n; i < -size_; ++i) {
828  new (base_ + i) T();
829  }
830  for (int i = size_; i < n; ++i) {
831  new (base_ + i) T();
832  }
833  for (int i = -size_; i < -n; ++i) {
834  base_[i].~T();
835  }
836  for (int i = n; i < size_; ++i) {
837  base_[i].~T();
838  }
839  size_ = n;
840  }
841 
842  void clear() { resize(0); }
843 
844  T* data() const { return base_; }
845 
846  void swap(SVector<T>& x) {
847  std::swap(base_, x.base_);
848  std::swap(size_, x.size_);
849  std::swap(capacity_, x.capacity_);
850  }
851 
852  void reserve(int n) {
853  DCHECK_GE(n, 0);
854  DCHECK_LE(n, max_size());
855  if (n > capacity_) {
856  const int new_capacity = std::min(n, max_size());
857  T* new_storage = Allocate(new_capacity);
858  CHECK(new_storage != nullptr);
859  T* new_base = new_storage + new_capacity;
860  // TODO(user): in C++17 we could use std::uninitialized_move instead
861  // of this loop.
862  for (int i = -size_; i < size_; ++i) {
863  new (new_base + i) T(std::move(base_[i]));
864  }
865  int saved_size = size_;
867  size_ = saved_size;
868  base_ = new_base;
869  capacity_ = new_capacity;
870  }
871  }
872 
873  // NOTE(user): This doesn't currently support movable-only objects, but we
874  // could fix that.
875  void grow(const T& left = T(), const T& right = T()) {
876  if (size_ == capacity_) {
877  // We have to copy the elements because they are allowed to be element of
878  // *this.
879  T left_copy(left); // NOLINT
880  T right_copy(right); // NOLINT
881  reserve(NewCapacity(1));
882  new (base_ + size_) T(right_copy);
883  new (base_ - size_ - 1) T(left_copy);
884  ++size_;
885  } else {
886  new (base_ + size_) T(right);
887  new (base_ - size_ - 1) T(left);
888  ++size_;
889  }
890  }
891 
892  int size() const { return size_; }
893 
894  int capacity() const { return capacity_; }
895 
896  int max_size() const { return std::numeric_limits<int>::max(); }
897 
899  if (base_ == nullptr) return;
900  clear();
901  if (capacity_ > 0) {
902  free(base_ - capacity_);
903  }
904  capacity_ = 0;
905  base_ = nullptr;
906  }
907 
908  private:
909  T* Allocate(int capacity) const {
910  return absl::IgnoreLeak(
911  static_cast<T*>(malloc(2LL * capacity * sizeof(T))));
912  }
913 
914  int NewCapacity(int delta) {
915  // TODO(user): check validity.
916  double candidate = 1.3 * static_cast<double>(capacity_);
917  if (candidate > static_cast<double>(max_size())) {
918  candidate = static_cast<double>(max_size());
919  }
920  int new_capacity = static_cast<int>(candidate);
921  if (new_capacity > capacity_ + delta) {
922  return new_capacity;
923  }
924  return capacity_ + delta;
925  }
926 
927  T* base_; // Pointer to the element of index 0.
928  int size_; // Valid index are [- size_, size_).
929  int capacity_; // Reserved index are [- capacity_, capacity_).
930 };
931 
932 // BaseGraph implementation ----------------------------------------------------
933 
934 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
935 IntegerRange<NodeIndexType>
937  return IntegerRange<NodeIndexType>(0, num_nodes_);
938 }
939 
940 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
943  return IntegerRange<ArcIndexType>(0, num_arcs_);
944 }
945 
946 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
947 const NodeIndexType
949  std::numeric_limits<NodeIndexType>::max();
950 
951 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
952 const ArcIndexType
954  std::numeric_limits<ArcIndexType>::max();
955 
956 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
957 NodeIndexType
959  // TODO(user): Is it needed? remove completely? return the real capacities
960  // at the cost of having a different implementation for each graphs?
961  return node_capacity_ > num_nodes_ ? node_capacity_ : num_nodes_;
962 }
963 
964 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
965 ArcIndexType
967  // TODO(user): Same questions as the ones in node_capacity().
968  return arc_capacity_ > num_arcs_ ? arc_capacity_ : num_arcs_;
969 }
970 
971 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
972 void BaseGraph<NodeIndexType, ArcIndexType,
973  HasReverseArcs>::FreezeCapacities() {
974  // TODO(user): Only define this in debug mode at the cost of having a lot
975  // of ifndef NDEBUG all over the place? remove the function completely ?
976  const_capacities_ = true;
977  node_capacity_ = std::max(node_capacity_, num_nodes_);
978  arc_capacity_ = std::max(arc_capacity_, num_arcs_);
979 }
980 
981 // Computes the cummulative sum of the entry in v. We only use it with
982 // in/out degree distribution, hence the Check() at the end.
983 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
985  ComputeCumulativeSum(std::vector<ArcIndexType>* v) {
986  ArcIndexType sum = 0;
987  for (int i = 0; i < num_nodes_; ++i) {
988  ArcIndexType temp = (*v)[i];
989  (*v)[i] = sum;
990  sum += temp;
991  }
992  DCHECK(sum == num_arcs_);
993 }
994 
995 // Given the tail of arc #i in (*head)[i] and the head of arc #i in (*head)[~i]
996 // - Reorder the arc by increasing tail.
997 // - Put the head of the new arc #i in (*head)[i].
998 // - Put in start[i] the index of the first arc with tail >= i.
999 // - Update "permutation" to reflect the change, unless it is NULL.
1000 template <typename NodeIndexType, typename ArcIndexType, bool HasReverseArcs>
1003  std::vector<ArcIndexType>* start,
1004  std::vector<ArcIndexType>* permutation) {
1005  // Computes the outgoing degree of each nodes and check if we need to permute
1006  // something or not. Note that the tails are currently stored in the positive
1007  // range of the SVector head.
1008  start->assign(num_nodes_, 0);
1009  int last_tail_seen = 0;
1010  bool permutation_needed = false;
1011  for (int i = 0; i < num_arcs_; ++i) {
1012  NodeIndexType tail = (*head)[i];
1013  if (!permutation_needed) {
1014  permutation_needed = tail < last_tail_seen;
1015  last_tail_seen = tail;
1016  }
1017  (*start)[tail]++;
1018  }
1019  ComputeCumulativeSum(start);
1020 
1021  // Abort early if we do not need the permutation: we only need to put the
1022  // heads in the positive range.
1023  if (!permutation_needed) {
1024  for (int i = 0; i < num_arcs_; ++i) {
1025  (*head)[i] = (*head)[~i];
1026  }
1027  if (permutation != nullptr) {
1028  permutation->clear();
1029  }
1030  return;
1031  }
1032 
1033  // Computes the forward arc permutation.
1034  // Note that this temporarily alters the start vector.
1035  std::vector<ArcIndexType> perm(num_arcs_);
1036  for (int i = 0; i < num_arcs_; ++i) {
1037  perm[i] = (*start)[(*head)[i]]++;
1038  }
1039 
1040  // Restore in (*start)[i] the index of the first arc with tail >= i.
1041  for (int i = num_nodes_ - 1; i > 0; --i) {
1042  (*start)[i] = (*start)[i - 1];
1043  }
1044  (*start)[0] = 0;
1045 
1046  // Permutes the head into their final position in head.
1047  // We do not need the tails anymore at this point.
1048  for (int i = 0; i < num_arcs_; ++i) {
1049  (*head)[perm[i]] = (*head)[~i];
1050  }
1051  if (permutation != nullptr) {
1052  permutation->swap(perm);
1053  }
1054 }
1055 
1056 // ---------------------------------------------------------------------------
1057 // Macros to wrap old style iteration into the new range-based for loop style.
1058 // ---------------------------------------------------------------------------
1059 
1060 // The parameters are:
1061 // - c: the class name.
1062 // - t: the iteration type (Outgoing, Incoming, OutgoingOrOppositeIncoming
1063 // or OppositeIncoming).
1064 // - e: the "end" ArcIndexType.
1065 #define DEFINE_RANGE_BASED_ARC_ITERATION(c, t, e) \
1066  template <typename NodeIndexType, typename ArcIndexType> \
1067  BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1068  c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1069  return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node), \
1070  t##ArcIterator(*this, node, e)); \
1071  } \
1072  template <typename NodeIndexType, typename ArcIndexType> \
1073  BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1074  c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1075  NodeIndexType node, ArcIndexType from) const { \
1076  return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node, from), \
1077  t##ArcIterator(*this, node, e)); \
1078  }
1079 
1080 // Adapt our old iteration style to support range-based for loops. Add typedefs
1081 // required by std::iterator_traits.
1082 #define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1083  using iterator_category = std::input_iterator_tag; \
1084  using difference_type = ptrdiff_t; \
1085  using pointer = const ArcIndexType*; \
1086  using reference = const ArcIndexType&; \
1087  using value_type = ArcIndexType; \
1088  bool operator!=(const iterator_class_name& other) const { \
1089  return this->index_ != other.index_; \
1090  } \
1091  bool operator==(const iterator_class_name& other) const { \
1092  return this->index_ == other.index_; \
1093  } \
1094  ArcIndexType operator*() const { return this->Index(); } \
1095  void operator++() { this->Next(); }
1096 
1097 // ListGraph implementation ----------------------------------------------------
1098 
1100 
1101 template <typename NodeIndexType, typename ArcIndexType>
1106  OutgoingHeadIterator(*this, node),
1107  OutgoingHeadIterator(*this, node, Base::kNilArc));
1108 }
1109 
1110 template <typename NodeIndexType, typename ArcIndexType>
1112  ArcIndexType arc) const {
1113  DCHECK(IsArcValid(arc));
1114  return tail_[arc];
1115 }
1116 
1117 template <typename NodeIndexType, typename ArcIndexType>
1119  ArcIndexType arc) const {
1120  DCHECK(IsArcValid(arc));
1121  return head_[arc];
1122 }
1123 
1124 template <typename NodeIndexType, typename ArcIndexType>
1126  NodeIndexType node) const {
1127  ArcIndexType degree(0);
1128  for (auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1129  return degree;
1130 }
1131 
1132 template <typename NodeIndexType, typename ArcIndexType>
1134  if (node < num_nodes_) return;
1135  DCHECK(!const_capacities_ || node < node_capacity_);
1136  num_nodes_ = node + 1;
1137  start_.resize(num_nodes_, Base::kNilArc);
1138 }
1139 
1140 template <typename NodeIndexType, typename ArcIndexType>
1142  NodeIndexType tail, NodeIndexType head) {
1143  DCHECK_GE(tail, 0);
1144  DCHECK_GE(head, 0);
1145  AddNode(tail > head ? tail : head);
1146  head_.push_back(head);
1147  tail_.push_back(tail);
1148  next_.push_back(start_[tail]);
1149  start_[tail] = num_arcs_;
1150  DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1151  return num_arcs_++;
1152 }
1153 
1154 template <typename NodeIndexType, typename ArcIndexType>
1156  Base::ReserveNodes(bound);
1157  if (bound <= num_nodes_) return;
1158  start_.reserve(bound);
1159 }
1160 
1161 template <typename NodeIndexType, typename ArcIndexType>
1163  Base::ReserveArcs(bound);
1164  if (bound <= num_arcs_) return;
1165  head_.reserve(bound);
1166  tail_.reserve(bound);
1167  next_.reserve(bound);
1168 }
1169 
1170 template <typename NodeIndexType, typename ArcIndexType>
1172  std::vector<ArcIndexType>* permutation) {
1173  if (permutation != nullptr) {
1174  permutation->clear();
1175  }
1176 }
1177 
1178 template <typename NodeIndexType, typename ArcIndexType>
1179 class ListGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1180  public:
1181  OutgoingArcIterator(const ListGraph& graph, NodeIndexType node)
1182  : graph_(graph), index_(graph.start_[node]) {
1183  DCHECK(graph.IsNodeValid(node));
1184  }
1185  OutgoingArcIterator(const ListGraph& graph, NodeIndexType node,
1186  ArcIndexType arc)
1187  : graph_(graph), index_(arc) {
1188  DCHECK(graph.IsNodeValid(node));
1189  DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node);
1190  }
1191  bool Ok() const { return index_ != Base::kNilArc; }
1192  ArcIndexType Index() const { return index_; }
1193  void Next() {
1194  DCHECK(Ok());
1195  index_ = graph_.next_[index_];
1196  }
1197 
1199 
1200  private:
1201  const ListGraph& graph_;
1202  ArcIndexType index_;
1203 };
1204 
1205 template <typename NodeIndexType, typename ArcIndexType>
1206 class ListGraph<NodeIndexType, ArcIndexType>::OutgoingHeadIterator {
1207  public:
1208  using iterator_category = std::input_iterator_tag;
1209  using difference_type = ptrdiff_t;
1210  using pointer = const NodeIndexType*;
1211  using reference = const NodeIndexType&;
1212  using value_type = NodeIndexType;
1213 
1214  OutgoingHeadIterator(const ListGraph& graph, NodeIndexType node)
1215  : graph_(graph), index_(graph.start_[node]) {
1216  DCHECK(graph.IsNodeValid(node));
1217  }
1218  OutgoingHeadIterator(const ListGraph& graph, NodeIndexType node,
1219  ArcIndexType arc)
1220  : graph_(graph), index_(arc) {
1221  DCHECK(graph.IsNodeValid(node));
1222  DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node);
1223  }
1224  bool Ok() const { return index_ != Base::kNilArc; }
1225  NodeIndexType Index() const { return graph_.Head(index_); }
1226  void Next() {
1227  DCHECK(Ok());
1228  index_ = graph_.next_[index_];
1229  }
1230 
1232  const typename ListGraph<
1233  NodeIndexType, ArcIndexType>::OutgoingHeadIterator& other) const {
1234  return index_ != other.index_;
1235  }
1236  NodeIndexType operator*() const { return Index(); }
1237  void operator++() { Next(); }
1238 
1239  private:
1240  const ListGraph& graph_;
1241  ArcIndexType index_;
1242 };
1243 
1244 // StaticGraph implementation --------------------------------------------------
1245 
1246 DEFINE_RANGE_BASED_ARC_ITERATION(StaticGraph, Outgoing, DirectArcLimit(node));
1247 
1248 template <typename NodeIndexType, typename ArcIndexType>
1252  head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1253 }
1254 
1255 template <typename NodeIndexType, typename ArcIndexType>
1257  NodeIndexType node) const {
1258  return DirectArcLimit(node) - start_[node];
1259 }
1260 
1261 template <typename NodeIndexType, typename ArcIndexType>
1263  NodeIndexType bound) {
1264  Base::ReserveNodes(bound);
1265  if (bound <= num_nodes_) return;
1266  start_.reserve(bound);
1267 }
1268 
1269 template <typename NodeIndexType, typename ArcIndexType>
1271  Base::ReserveArcs(bound);
1272  if (bound <= num_arcs_) return;
1273  head_.reserve(bound);
1274  tail_.reserve(bound);
1275 }
1276 
1277 template <typename NodeIndexType, typename ArcIndexType>
1279  if (node < num_nodes_) return;
1280  DCHECK(!const_capacities_ || node < node_capacity_) << node;
1281  num_nodes_ = node + 1;
1282  start_.resize(num_nodes_, 0);
1283 }
1284 
1285 template <typename NodeIndexType, typename ArcIndexType>
1287  NodeIndexType tail, NodeIndexType head) {
1288  DCHECK_GE(tail, 0);
1289  DCHECK_GE(head, 0);
1290  DCHECK(!is_built_);
1291  AddNode(tail > head ? tail : head);
1292  if (arc_in_order_) {
1293  if (tail >= last_tail_seen_) {
1294  start_[tail]++;
1295  last_tail_seen_ = tail;
1296  } else {
1297  arc_in_order_ = false;
1298  }
1299  }
1300  tail_.push_back(tail);
1301  head_.push_back(head);
1302  DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1303  return num_arcs_++;
1304 }
1305 
1306 template <typename NodeIndexType, typename ArcIndexType>
1308  ArcIndexType arc) const {
1309  DCHECK(IsArcValid(arc));
1310  return tail_[arc];
1311 }
1312 
1313 template <typename NodeIndexType, typename ArcIndexType>
1315  ArcIndexType arc) const {
1316  DCHECK(IsArcValid(arc));
1317  return head_[arc];
1318 }
1319 
1320 // Implementation details: A reader may be surprised that we do many passes
1321 // into the data where things could be done in one pass. For instance, during
1322 // construction, we store the edges first, and then do a second pass at the
1323 // end to compute the degree distribution.
1324 //
1325 // This is because it is a lot more efficient cache-wise to do it this way.
1326 // This was determined by various experiments, but can also be understood:
1327 // - during repetitive call to AddArc() a client usually accesses various
1328 // areas of memory, and there is no reason to polute the cache with
1329 // possibly random access to degree[i].
1330 // - When the degrees are needed, we compute them in one go, maximizing the
1331 // chance of cache hit during the computation.
1332 template <typename NodeIndexType, typename ArcIndexType>
1334  std::vector<ArcIndexType>* permutation) {
1335  DCHECK(!is_built_);
1336  if (is_built_) return;
1337  is_built_ = true;
1338  node_capacity_ = num_nodes_;
1339  arc_capacity_ = num_arcs_;
1340  this->FreezeCapacities();
1341 
1342  // If Arc are in order, start_ already contains the degree distribution.
1343  if (arc_in_order_) {
1344  if (permutation != nullptr) {
1345  permutation->clear();
1346  }
1347  this->ComputeCumulativeSum(&start_);
1348  return;
1349  }
1350 
1351  // Computes outgoing degree of each nodes. We have to clear start_, since
1352  // at least the first arc was processed with arc_in_order_ == true.
1353  start_.assign(num_nodes_, 0);
1354  for (int i = 0; i < num_arcs_; ++i) {
1355  start_[tail_[i]]++;
1356  }
1357  this->ComputeCumulativeSum(&start_);
1358 
1359  // Computes the forward arc permutation.
1360  // Note that this temporarily alters the start_ vector.
1361  std::vector<ArcIndexType> perm(num_arcs_);
1362  for (int i = 0; i < num_arcs_; ++i) {
1363  perm[i] = start_[tail_[i]]++;
1364  }
1365 
1366  // We use "tail_" (which now contains rubbish) to permute "head_" faster.
1367  CHECK_EQ(tail_.size(), num_arcs_);
1368  tail_.swap(head_);
1369  for (int i = 0; i < num_arcs_; ++i) {
1370  head_[perm[i]] = tail_[i];
1371  }
1372 
1373  if (permutation != nullptr) {
1374  permutation->swap(perm);
1375  }
1376 
1377  // Restore in start_[i] the index of the first arc with tail >= i.
1378  for (int i = num_nodes_ - 1; i > 0; --i) {
1379  start_[i] = start_[i - 1];
1380  }
1381  start_[0] = 0;
1382 
1383  // Recompute the correct tail_ vector
1384  for (const NodeIndexType node : Base::AllNodes()) {
1385  for (const ArcIndexType arc : OutgoingArcs(node)) {
1386  tail_[arc] = node;
1387  }
1388  }
1389 }
1390 
1391 template <typename NodeIndexType, typename ArcIndexType>
1392 class StaticGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1393  public:
1394  OutgoingArcIterator(const StaticGraph& graph, NodeIndexType node)
1395  : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
1396  OutgoingArcIterator(const StaticGraph& graph, NodeIndexType node,
1397  ArcIndexType arc)
1398  : index_(arc), limit_(graph.DirectArcLimit(node)) {
1399  DCHECK_GE(arc, graph.start_[node]);
1400  }
1401 
1402  bool Ok() const { return index_ < limit_; }
1403  ArcIndexType Index() const { return index_; }
1404  void Next() {
1405  DCHECK(Ok());
1406  index_++;
1407  }
1408 
1409  // Note(user): we lose a bit by returning a BeginEndWrapper<> on top of
1410  // this iterator rather than a simple IntegerRange<> on the arc indices.
1411  // On my computer: around 420M arcs/sec instead of 440M arcs/sec.
1412  //
1413  // However, it is slightly more consistent to do it this way, and we don't
1414  // have two different codes depending on the way a client iterates on the
1415  // arcs.
1417 
1418  private:
1419  ArcIndexType index_;
1420  const ArcIndexType limit_;
1421 };
1422 
1423 // ReverseArcListGraph implementation ------------------------------------------
1424 
1428  OutgoingOrOppositeIncoming, Base::kNilArc);
1430  Base::kNilArc);
1431 
1432 template <typename NodeIndexType, typename ArcIndexType>
1434  NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1436  NodeIndexType node) const {
1438  OutgoingHeadIterator(*this, node),
1439  OutgoingHeadIterator(*this, node, Base::kNilArc));
1440 }
1441 
1442 template <typename NodeIndexType, typename ArcIndexType>
1444  NodeIndexType node) const {
1445  ArcIndexType degree(0);
1446  for (auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1447  return degree;
1448 }
1449 
1450 template <typename NodeIndexType, typename ArcIndexType>
1452  NodeIndexType node) const {
1453  ArcIndexType degree(0);
1454  for (auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1455  return degree;
1456 }
1457 
1458 template <typename NodeIndexType, typename ArcIndexType>
1460  ArcIndexType arc) const {
1461  DCHECK(IsArcValid(arc));
1462  return ~arc;
1463 }
1464 
1465 template <typename NodeIndexType, typename ArcIndexType>
1467  ArcIndexType arc) const {
1468  DCHECK(IsArcValid(arc));
1469  return head_[arc];
1470 }
1471 
1472 template <typename NodeIndexType, typename ArcIndexType>
1474  ArcIndexType arc) const {
1475  return head_[OppositeArc(arc)];
1476 }
1477 
1478 template <typename NodeIndexType, typename ArcIndexType>
1480  NodeIndexType bound) {
1481  Base::ReserveNodes(bound);
1482  if (bound <= num_nodes_) return;
1483  start_.reserve(bound);
1484  reverse_start_.reserve(bound);
1485 }
1486 
1487 template <typename NodeIndexType, typename ArcIndexType>
1489  ArcIndexType bound) {
1490  Base::ReserveArcs(bound);
1491  if (bound <= num_arcs_) return;
1492  head_.reserve(bound);
1493  next_.reserve(bound);
1494 }
1495 
1496 template <typename NodeIndexType, typename ArcIndexType>
1498  NodeIndexType node) {
1499  if (node < num_nodes_) return;
1500  DCHECK(!const_capacities_ || node < node_capacity_);
1501  num_nodes_ = node + 1;
1502  start_.resize(num_nodes_, Base::kNilArc);
1503  reverse_start_.resize(num_nodes_, Base::kNilArc);
1504 }
1505 
1506 template <typename NodeIndexType, typename ArcIndexType>
1508  NodeIndexType tail, NodeIndexType head) {
1509  DCHECK_GE(tail, 0);
1510  DCHECK_GE(head, 0);
1511  AddNode(tail > head ? tail : head);
1512  head_.grow(tail, head);
1513  next_.grow(reverse_start_[head], start_[tail]);
1514  start_[tail] = num_arcs_;
1515  reverse_start_[head] = ~num_arcs_;
1516  DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1517  return num_arcs_++;
1518 }
1519 
1520 template <typename NodeIndexType, typename ArcIndexType>
1522  std::vector<ArcIndexType>* permutation) {
1523  if (permutation != nullptr) {
1524  permutation->clear();
1525  }
1526 }
1527 
1528 template <typename NodeIndexType, typename ArcIndexType>
1529 class ReverseArcListGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1530  public:
1531  OutgoingArcIterator(const ReverseArcListGraph& graph, NodeIndexType node)
1532  : graph_(graph), index_(graph.start_[node]) {
1533  DCHECK(graph.IsNodeValid(node));
1534  }
1535  OutgoingArcIterator(const ReverseArcListGraph& graph, NodeIndexType node,
1536  ArcIndexType arc)
1537  : graph_(graph), index_(arc) {
1538  DCHECK(graph.IsNodeValid(node));
1539  DCHECK(arc == Base::kNilArc || arc >= 0);
1540  DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node);
1541  }
1542  bool Ok() const { return index_ != Base::kNilArc; }
1543  ArcIndexType Index() const { return index_; }
1544  void Next() {
1545  DCHECK(Ok());
1546  index_ = graph_.next_[index_];
1547  }
1548 
1550 
1551  private:
1552  const ReverseArcListGraph& graph_;
1553  ArcIndexType index_;
1554 };
1555 
1556 template <typename NodeIndexType, typename ArcIndexType>
1557 class ReverseArcListGraph<NodeIndexType,
1558  ArcIndexType>::OppositeIncomingArcIterator {
1559  public:
1561  NodeIndexType node)
1562  : graph_(graph), index_(graph.reverse_start_[node]) {
1563  DCHECK(graph.IsNodeValid(node));
1564  }
1566  NodeIndexType node, ArcIndexType arc)
1567  : graph_(graph), index_(arc) {
1568  DCHECK(graph.IsNodeValid(node));
1569  DCHECK(arc == Base::kNilArc || arc < 0);
1570  DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node);
1571  }
1572 
1573  bool Ok() const { return index_ != Base::kNilArc; }
1574  ArcIndexType Index() const { return index_; }
1575  void Next() {
1576  DCHECK(Ok());
1577  index_ = graph_.next_[index_];
1578  }
1579 
1581 
1582  protected:
1584  ArcIndexType index_;
1585 };
1586 
1587 template <typename NodeIndexType, typename ArcIndexType>
1588 class ReverseArcListGraph<NodeIndexType, ArcIndexType>::IncomingArcIterator
1589  : public OppositeIncomingArcIterator {
1590  public:
1591  IncomingArcIterator(const ReverseArcListGraph& graph, NodeIndexType node)
1592  : OppositeIncomingArcIterator(graph, node) {}
1593  IncomingArcIterator(const ReverseArcListGraph& graph, NodeIndexType node,
1594  ArcIndexType arc)
1596  graph, node,
1597  arc == Base::kNilArc ? Base::kNilArc : graph.OppositeArc(arc)) {}
1598 
1599  // We overwrite OppositeIncomingArcIterator::Index() here.
1600  ArcIndexType Index() const {
1601  return this->index_ == Base::kNilArc
1602  ? Base::kNilArc
1603  : this->graph_.OppositeArc(this->index_);
1604  }
1605 
1607 };
1608 
1609 template <typename NodeIndexType, typename ArcIndexType>
1610 class ReverseArcListGraph<NodeIndexType,
1611  ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
1612  public:
1614  NodeIndexType node)
1615  : graph_(graph), index_(graph.reverse_start_[node]), node_(node) {
1616  DCHECK(graph.IsNodeValid(node));
1617  if (index_ == Base::kNilArc) index_ = graph.start_[node];
1618  }
1620  NodeIndexType node, ArcIndexType arc)
1621  : graph_(graph), index_(arc), node_(node) {
1622  DCHECK(graph.IsNodeValid(node));
1623  DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node);
1624  }
1625 
1626  bool Ok() const { return index_ != Base::kNilArc; }
1627  ArcIndexType Index() const { return index_; }
1628  void Next() {
1629  DCHECK(Ok());
1630  if (index_ < 0) {
1631  index_ = graph_.next_[index_];
1632  if (index_ == Base::kNilArc) {
1633  index_ = graph_.start_[node_];
1634  }
1635  } else {
1636  index_ = graph_.next_[index_];
1637  }
1638  }
1639 
1641 
1642  private:
1643  const ReverseArcListGraph& graph_;
1644  ArcIndexType index_;
1645  const NodeIndexType node_;
1646 };
1647 
1648 template <typename NodeIndexType, typename ArcIndexType>
1649 class ReverseArcListGraph<NodeIndexType, ArcIndexType>::OutgoingHeadIterator {
1650  public:
1651  OutgoingHeadIterator(const ReverseArcListGraph& graph, NodeIndexType node)
1652  : graph_(&graph), index_(graph.start_[node]) {
1653  DCHECK(graph.IsNodeValid(node));
1654  }
1655  OutgoingHeadIterator(const ReverseArcListGraph& graph, NodeIndexType node,
1656  ArcIndexType arc)
1657  : graph_(&graph), index_(arc) {
1658  DCHECK(graph.IsNodeValid(node));
1659  DCHECK(arc == Base::kNilArc || arc >= 0);
1660  DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node);
1661  }
1662  bool Ok() const { return index_ != Base::kNilArc; }
1663  ArcIndexType Index() const { return graph_->Head(index_); }
1664  void Next() {
1665  DCHECK(Ok());
1666  index_ = graph_->next_[index_];
1667  }
1668 
1670 
1671  private:
1672  const ReverseArcListGraph* graph_;
1673  ArcIndexType index_;
1674 };
1675 
1676 // ReverseArcStaticGraph implementation ----------------------------------------
1677 
1679  DirectArcLimit(node));
1681  ReverseArcLimit(node));
1683  OutgoingOrOppositeIncoming,
1684  DirectArcLimit(node));
1686  ReverseArcLimit(node));
1687 
1688 template <typename NodeIndexType, typename ArcIndexType>
1690  NodeIndexType node) const {
1691  return DirectArcLimit(node) - start_[node];
1692 }
1693 
1694 template <typename NodeIndexType, typename ArcIndexType>
1696  NodeIndexType node) const {
1697  return ReverseArcLimit(node) - reverse_start_[node];
1698 }
1699 
1700 template <typename NodeIndexType, typename ArcIndexType>
1703  NodeIndexType node) const {
1705  head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1706 }
1707 
1708 template <typename NodeIndexType, typename ArcIndexType>
1710  ArcIndexType arc) const {
1711  DCHECK(is_built_);
1712  DCHECK(IsArcValid(arc));
1713  return opposite_[arc];
1714 }
1715 
1716 template <typename NodeIndexType, typename ArcIndexType>
1718  ArcIndexType arc) const {
1719  DCHECK(is_built_);
1720  DCHECK(IsArcValid(arc));
1721  return head_[arc];
1722 }
1723 
1724 template <typename NodeIndexType, typename ArcIndexType>
1726  ArcIndexType arc) const {
1727  DCHECK(is_built_);
1728  return head_[OppositeArc(arc)];
1729 }
1730 
1731 template <typename NodeIndexType, typename ArcIndexType>
1733  ArcIndexType bound) {
1734  Base::ReserveArcs(bound);
1735  if (bound <= num_arcs_) return;
1736  head_.reserve(bound);
1737 }
1738 
1739 template <typename NodeIndexType, typename ArcIndexType>
1741  NodeIndexType node) {
1742  if (node < num_nodes_) return;
1743  DCHECK(!const_capacities_ || node < node_capacity_);
1744  num_nodes_ = node + 1;
1745 }
1746 
1747 template <typename NodeIndexType, typename ArcIndexType>
1749  NodeIndexType tail, NodeIndexType head) {
1750  DCHECK_GE(tail, 0);
1751  DCHECK_GE(head, 0);
1752  AddNode(tail > head ? tail : head);
1753 
1754  // We inverse head and tail here because it is more convenient this way
1755  // during build time, see Build().
1756  head_.grow(head, tail);
1757  DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1758  return num_arcs_++;
1759 }
1760 
1761 template <typename NodeIndexType, typename ArcIndexType>
1763  std::vector<ArcIndexType>* permutation) {
1764  DCHECK(!is_built_);
1765  if (is_built_) return;
1766  is_built_ = true;
1767  node_capacity_ = num_nodes_;
1768  arc_capacity_ = num_arcs_;
1769  this->FreezeCapacities();
1770  this->BuildStartAndForwardHead(&head_, &start_, permutation);
1771 
1772  // Computes incoming degree of each nodes.
1773  reverse_start_.assign(num_nodes_, 0);
1774  for (int i = 0; i < num_arcs_; ++i) {
1775  reverse_start_[head_[i]]++;
1776  }
1777  this->ComputeCumulativeSum(&reverse_start_);
1778 
1779  // Computes the reverse arcs of the forward arcs.
1780  // Note that this sort the reverse arcs with the same tail by head.
1781  opposite_.reserve(num_arcs_);
1782  for (int i = 0; i < num_arcs_; ++i) {
1783  // TODO(user): the 0 is wasted here, but minor optimisation.
1784  opposite_.grow(0, reverse_start_[head_[i]]++ - num_arcs_);
1785  }
1786 
1787  // Computes in reverse_start_ the start index of the reverse arcs.
1788  for (int i = num_nodes_ - 1; i > 0; --i) {
1789  reverse_start_[i] = reverse_start_[i - 1] - num_arcs_;
1790  }
1791  if (num_nodes_ != 0) {
1792  reverse_start_[0] = -num_arcs_;
1793  }
1794 
1795  // Fill reverse arc information.
1796  for (int i = 0; i < num_arcs_; ++i) {
1797  opposite_[opposite_[i]] = i;
1798  }
1799  for (const NodeIndexType node : Base::AllNodes()) {
1800  for (const ArcIndexType arc : OutgoingArcs(node)) {
1801  head_[opposite_[arc]] = node;
1802  }
1803  }
1804 }
1805 
1806 template <typename NodeIndexType, typename ArcIndexType>
1807 class ReverseArcStaticGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1808  public:
1809  OutgoingArcIterator(const ReverseArcStaticGraph& graph, NodeIndexType node)
1810  : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
1811  OutgoingArcIterator(const ReverseArcStaticGraph& graph, NodeIndexType node,
1812  ArcIndexType arc)
1813  : index_(arc), limit_(graph.DirectArcLimit(node)) {
1814  DCHECK_GE(arc, graph.start_[node]);
1815  }
1816 
1817  bool Ok() const { return index_ < limit_; }
1818  ArcIndexType Index() const { return index_; }
1819  void Next() {
1820  DCHECK(Ok());
1821  index_++;
1822  }
1823 
1824  // TODO(user): we lose a bit by returning a BeginEndWrapper<> on top of this
1825  // iterator rather than a simple IntegerRange on the arc indices.
1827 
1828  private:
1829  ArcIndexType index_;
1830  const ArcIndexType limit_;
1831 };
1832 
1833 template <typename NodeIndexType, typename ArcIndexType>
1834 class ReverseArcStaticGraph<NodeIndexType,
1835  ArcIndexType>::OppositeIncomingArcIterator {
1836  public:
1838  NodeIndexType node)
1839  : graph_(graph),
1840  limit_(graph.ReverseArcLimit(node)),
1841  index_(graph.reverse_start_[node]) {
1842  DCHECK(graph.IsNodeValid(node));
1843  DCHECK_LE(index_, limit_);
1844  }
1846  NodeIndexType node, ArcIndexType arc)
1847  : graph_(graph), limit_(graph.ReverseArcLimit(node)), index_(arc) {
1848  DCHECK(graph.IsNodeValid(node));
1849  DCHECK_GE(index_, graph.reverse_start_[node]);
1850  DCHECK_LE(index_, limit_);
1851  }
1852 
1853  bool Ok() const { return index_ < limit_; }
1854  ArcIndexType Index() const { return index_; }
1855  void Next() {
1856  DCHECK(Ok());
1857  index_++;
1858  }
1859 
1861 
1862  protected:
1864  const ArcIndexType limit_;
1865  ArcIndexType index_;
1866 };
1867 
1868 template <typename NodeIndexType, typename ArcIndexType>
1869 class ReverseArcStaticGraph<NodeIndexType, ArcIndexType>::IncomingArcIterator
1870  : public OppositeIncomingArcIterator {
1871  public:
1872  IncomingArcIterator(const ReverseArcStaticGraph& graph, NodeIndexType node)
1873  : OppositeIncomingArcIterator(graph, node) {}
1874  IncomingArcIterator(const ReverseArcStaticGraph& graph, NodeIndexType node,
1875  ArcIndexType arc)
1876  : OppositeIncomingArcIterator(graph, node,
1877  arc == graph.ReverseArcLimit(node)
1878  ? graph.ReverseArcLimit(node)
1879  : graph.OppositeArc(arc)) {}
1880 
1881  ArcIndexType Index() const {
1882  return this->index_ == this->limit_
1883  ? this->limit_
1884  : this->graph_.OppositeArc(this->index_);
1885  }
1886 
1888 };
1889 
1890 template <typename NodeIndexType, typename ArcIndexType>
1892  NodeIndexType, ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
1893  public:
1895  NodeIndexType node)
1896  : index_(graph.reverse_start_[node]),
1897  first_limit_(graph.ReverseArcLimit(node)),
1898  next_start_(graph.start_[node]),
1899  limit_(graph.DirectArcLimit(node)) {
1900  if (index_ == first_limit_) index_ = next_start_;
1901  DCHECK(graph.IsNodeValid(node));
1902  DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1903  }
1905  NodeIndexType node, ArcIndexType arc)
1906  : index_(arc),
1907  first_limit_(graph.ReverseArcLimit(node)),
1908  next_start_(graph.start_[node]),
1909  limit_(graph.DirectArcLimit(node)) {
1910  DCHECK(graph.IsNodeValid(node));
1911  DCHECK((index_ >= graph.reverse_start_[node] && index_ < first_limit_) ||
1912  (index_ >= next_start_));
1913  }
1914 
1915  ArcIndexType Index() const { return index_; }
1916  bool Ok() const { return index_ < limit_; }
1917  void Next() {
1918  DCHECK(Ok());
1919  index_++;
1920  if (index_ == first_limit_) {
1921  index_ = next_start_;
1922  }
1923  }
1924 
1926 
1927  private:
1928  ArcIndexType index_;
1929  const ArcIndexType first_limit_;
1930  const ArcIndexType next_start_;
1931  const ArcIndexType limit_;
1932 };
1933 
1934 // ReverseArcMixedGraph implementation -----------------------------------------
1935 
1937  DirectArcLimit(node));
1940  OutgoingOrOppositeIncoming,
1941  DirectArcLimit(node));
1943  Base::kNilArc);
1944 
1945 template <typename NodeIndexType, typename ArcIndexType>
1947  NodeIndexType node) const {
1948  return DirectArcLimit(node) - start_[node];
1949 }
1950 
1951 template <typename NodeIndexType, typename ArcIndexType>
1953  NodeIndexType node) const {
1954  ArcIndexType degree(0);
1955  for (auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1956  return degree;
1957 }
1958 
1959 template <typename NodeIndexType, typename ArcIndexType>
1962  NodeIndexType node) const {
1964  head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1965 }
1966 
1967 template <typename NodeIndexType, typename ArcIndexType>
1969  ArcIndexType arc) const {
1970  DCHECK(IsArcValid(arc));
1971  return ~arc;
1972 }
1973 
1974 template <typename NodeIndexType, typename ArcIndexType>
1976  ArcIndexType arc) const {
1977  DCHECK(is_built_);
1978  DCHECK(IsArcValid(arc));
1979  return head_[arc];
1980 }
1981 
1982 template <typename NodeIndexType, typename ArcIndexType>
1984  ArcIndexType arc) const {
1985  DCHECK(is_built_);
1986  return head_[OppositeArc(arc)];
1987 }
1988 
1989 template <typename NodeIndexType, typename ArcIndexType>
1991  ArcIndexType bound) {
1992  Base::ReserveArcs(bound);
1993  if (bound <= num_arcs_) return;
1994  head_.reserve(bound);
1995 }
1996 
1997 template <typename NodeIndexType, typename ArcIndexType>
1999  NodeIndexType node) {
2000  if (node < num_nodes_) return;
2001  DCHECK(!const_capacities_ || node < node_capacity_);
2002  num_nodes_ = node + 1;
2003 }
2004 
2005 template <typename NodeIndexType, typename ArcIndexType>
2007  NodeIndexType tail, NodeIndexType head) {
2008  DCHECK_GE(tail, 0);
2009  DCHECK_GE(head, 0);
2010  AddNode(tail > head ? tail : head);
2011 
2012  // We inverse head and tail here because it is more convenient this way
2013  // during build time, see Build().
2014  head_.grow(head, tail);
2015  DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
2016  return num_arcs_++;
2017 }
2018 
2019 template <typename NodeIndexType, typename ArcIndexType>
2021  std::vector<ArcIndexType>* permutation) {
2022  DCHECK(!is_built_);
2023  if (is_built_) return;
2024  is_built_ = true;
2025  node_capacity_ = num_nodes_;
2026  arc_capacity_ = num_arcs_;
2027  this->FreezeCapacities();
2028  this->BuildStartAndForwardHead(&head_, &start_, permutation);
2029 
2030  // Fill tails.
2031  for (const NodeIndexType node : Base::AllNodes()) {
2032  for (const ArcIndexType arc : OutgoingArcs(node)) {
2033  head_[~arc] = node;
2034  }
2035  }
2036 
2037  // Fill information for iterating over reverse arcs.
2038  reverse_start_.assign(num_nodes_, Base::kNilArc);
2039  next_.reserve(num_arcs_);
2040  for (const ArcIndexType arc : Base::AllForwardArcs()) {
2041  next_.push_back(reverse_start_[Head(arc)]);
2042  reverse_start_[Head(arc)] = -next_.size();
2043  }
2044 }
2045 
2046 template <typename NodeIndexType, typename ArcIndexType>
2047 class ReverseArcMixedGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
2048  public:
2049  OutgoingArcIterator(const ReverseArcMixedGraph& graph, NodeIndexType node)
2050  : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
2051  OutgoingArcIterator(const ReverseArcMixedGraph& graph, NodeIndexType node,
2052  ArcIndexType arc)
2053  : index_(arc), limit_(graph.DirectArcLimit(node)) {
2054  DCHECK_GE(arc, graph.start_[node]);
2055  }
2056 
2057  bool Ok() const { return index_ < limit_; }
2058  ArcIndexType Index() const { return index_; }
2059  void Next() {
2060  DCHECK(Ok());
2061  index_++;
2062  }
2063 
2064  // TODO(user): we lose a bit by returning a BeginEndWrapper<> on top of this
2065  // iterator rather than a simple IntegerRange on the arc indices.
2067 
2068  private:
2069  ArcIndexType index_;
2070  const ArcIndexType limit_;
2071 };
2072 
2073 template <typename NodeIndexType, typename ArcIndexType>
2074 class ReverseArcMixedGraph<NodeIndexType,
2075  ArcIndexType>::OppositeIncomingArcIterator {
2076  public:
2078  NodeIndexType node)
2079  : graph_(&graph) {
2080  DCHECK(graph.is_built_);
2081  DCHECK(graph.IsNodeValid(node));
2082  index_ = graph.reverse_start_[node];
2083  }
2085  NodeIndexType node, ArcIndexType arc)
2086  : graph_(&graph), index_(arc) {
2087  DCHECK(graph.is_built_);
2088  DCHECK(graph.IsNodeValid(node));
2089  DCHECK(arc == Base::kNilArc || arc < 0);
2090  DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node);
2091  }
2092  bool Ok() const { return index_ != Base::kNilArc; }
2093  ArcIndexType Index() const { return index_; }
2094  void Next() {
2095  DCHECK(Ok());
2096  index_ = graph_->next_[~index_];
2097  }
2098 
2100 
2101  protected:
2103  ArcIndexType index_;
2104 };
2105 
2106 template <typename NodeIndexType, typename ArcIndexType>
2107 class ReverseArcMixedGraph<NodeIndexType, ArcIndexType>::IncomingArcIterator
2108  : public OppositeIncomingArcIterator {
2109  public:
2110  IncomingArcIterator(const ReverseArcMixedGraph& graph, NodeIndexType node)
2111  : OppositeIncomingArcIterator(graph, node) {}
2112  IncomingArcIterator(const ReverseArcMixedGraph& graph, NodeIndexType node,
2113  ArcIndexType arc)
2115  graph, node, arc == Base::kNilArc ? arc : graph.OppositeArc(arc)) {}
2116  ArcIndexType Index() const {
2117  return this->index_ == Base::kNilArc
2118  ? Base::kNilArc
2119  : this->graph_->OppositeArc(this->index_);
2120  }
2121 
2123 };
2124 
2125 template <typename NodeIndexType, typename ArcIndexType>
2127  NodeIndexType, ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
2128  public:
2130  NodeIndexType node)
2131  : graph_(&graph) {
2132  limit_ = graph.DirectArcLimit(node); // also DCHECKs node and is_built_.
2133  index_ = graph.reverse_start_[node];
2134  restart_ = graph.start_[node];
2135  if (index_ == Base::kNilArc) {
2136  index_ = restart_;
2137  }
2138  }
2140  NodeIndexType node, ArcIndexType arc)
2141  : graph_(&graph) {
2142  limit_ = graph.DirectArcLimit(node);
2143  index_ = arc;
2144  restart_ = graph.start_[node];
2145  DCHECK(arc == Base::kNilArc || arc == limit_ || graph.Tail(arc) == node);
2146  }
2147  bool Ok() const {
2148  // Note that we always have limit_ <= Base::kNilArc.
2149  return index_ < limit_;
2150  }
2151  ArcIndexType Index() const { return index_; }
2152  void Next() {
2153  DCHECK(Ok());
2154  if (index_ < 0) {
2155  index_ = graph_->next_[graph_->OppositeArc(index_)];
2156  if (index_ == Base::kNilArc) {
2157  index_ = restart_;
2158  }
2159  } else {
2160  index_++;
2161  }
2162  }
2163 
2165 
2166  private:
2167  const ReverseArcMixedGraph* graph_;
2168  ArcIndexType index_;
2169  ArcIndexType restart_;
2170  ArcIndexType limit_;
2171 };
2172 
2173 // CompleteGraph implementation ------------------------------------------------
2174 // Nodes and arcs are implicit and not stored.
2175 
2176 template <typename NodeIndexType = int32_t, typename ArcIndexType = int32_t>
2177 class CompleteGraph : public BaseGraph<NodeIndexType, ArcIndexType, false> {
2179  using Base::arc_capacity_;
2181  using Base::node_capacity_;
2182  using Base::num_arcs_;
2183  using Base::num_nodes_;
2184 
2185  public:
2186  // Builds a complete graph with num_nodes nodes.
2187  explicit CompleteGraph(NodeIndexType num_nodes) {
2188  this->Reserve(num_nodes, num_nodes * num_nodes);
2189  this->FreezeCapacities();
2190  num_nodes_ = num_nodes;
2191  num_arcs_ = num_nodes * num_nodes;
2192  }
2193 
2194  NodeIndexType Head(ArcIndexType arc) const;
2195  NodeIndexType Tail(ArcIndexType arc) const;
2196  ArcIndexType OutDegree(NodeIndexType node) const;
2197  IntegerRange<ArcIndexType> OutgoingArcs(NodeIndexType node) const;
2199  ArcIndexType from) const;
2200  IntegerRange<NodeIndexType> operator[](NodeIndexType node) const;
2201 };
2202 
2203 template <typename NodeIndexType, typename ArcIndexType>
2205  ArcIndexType arc) const {
2206  DCHECK(this->IsArcValid(arc));
2207  return arc % num_nodes_;
2208 }
2209 
2210 template <typename NodeIndexType, typename ArcIndexType>
2212  ArcIndexType arc) const {
2213  DCHECK(this->IsArcValid(arc));
2214  return arc / num_nodes_;
2215 }
2216 
2217 template <typename NodeIndexType, typename ArcIndexType>
2219  NodeIndexType node) const {
2220  return num_nodes_;
2221 }
2222 
2223 template <typename NodeIndexType, typename ArcIndexType>
2226  NodeIndexType node) const {
2227  DCHECK_LT(node, num_nodes_);
2229  static_cast<ArcIndexType>(num_nodes_) * node,
2230  static_cast<ArcIndexType>(num_nodes_) * (node + 1));
2231 }
2232 
2233 template <typename NodeIndexType, typename ArcIndexType>
2236  NodeIndexType node, ArcIndexType from) const {
2237  DCHECK_LT(node, num_nodes_);
2239  from, static_cast<ArcIndexType>(num_nodes_) * (node + 1));
2240 }
2241 
2242 template <typename NodeIndexType, typename ArcIndexType>
2245  NodeIndexType node) const {
2246  DCHECK_LT(node, num_nodes_);
2247  return IntegerRange<NodeIndexType>(0, num_nodes_);
2248 }
2249 
2250 // CompleteBipartiteGraph implementation ---------------------------------------
2251 // Nodes and arcs are implicit and not stored.
2252 
2253 template <typename NodeIndexType = int32_t, typename ArcIndexType = int32_t>
2255  : public BaseGraph<NodeIndexType, ArcIndexType, false> {
2257  using Base::arc_capacity_;
2259  using Base::node_capacity_;
2260  using Base::num_arcs_;
2261  using Base::num_nodes_;
2262 
2263  public:
2264  // Builds a complete bipartite graph from a set of left nodes to a set of
2265  // right nodes.
2266  // Indices of left nodes of the bipartite graph range from 0 to left_nodes-1;
2267  // indices of right nodes range from left_nodes to left_nodes+right_nodes-1.
2268  CompleteBipartiteGraph(NodeIndexType left_nodes, NodeIndexType right_nodes)
2269  : left_nodes_(left_nodes), right_nodes_(right_nodes) {
2270  this->Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
2271  this->FreezeCapacities();
2272  num_nodes_ = left_nodes + right_nodes;
2273  num_arcs_ = left_nodes * right_nodes;
2274  }
2275 
2276  NodeIndexType Head(ArcIndexType arc) const;
2277  NodeIndexType Tail(ArcIndexType arc) const;
2278  ArcIndexType OutDegree(NodeIndexType node) const;
2279  IntegerRange<ArcIndexType> OutgoingArcs(NodeIndexType node) const;
2281  ArcIndexType from) const;
2282  IntegerRange<NodeIndexType> operator[](NodeIndexType node) const;
2283 
2284  // Deprecated interface.
2286  public:
2287  OutgoingArcIterator(const CompleteBipartiteGraph& graph, NodeIndexType node)
2288  : index_(graph.right_nodes_ * node),
2289  limit_(node >= graph.left_nodes_ ? index_
2290  : graph.right_nodes_ * (node + 1)) {}
2291 
2292  bool Ok() const { return index_ < limit_; }
2293  ArcIndexType Index() const { return index_; }
2294  void Next() { index_++; }
2295 
2296  private:
2297  ArcIndexType index_;
2298  const ArcIndexType limit_;
2299  };
2300 
2301  private:
2302  const NodeIndexType left_nodes_;
2303  const NodeIndexType right_nodes_;
2304 };
2305 
2306 template <typename NodeIndexType, typename ArcIndexType>
2308  ArcIndexType arc) const {
2309  DCHECK(this->IsArcValid(arc));
2310  return left_nodes_ + arc % right_nodes_;
2311 }
2312 
2313 template <typename NodeIndexType, typename ArcIndexType>
2315  ArcIndexType arc) const {
2316  DCHECK(this->IsArcValid(arc));
2317  return arc / right_nodes_;
2318 }
2319 
2320 template <typename NodeIndexType, typename ArcIndexType>
2322  NodeIndexType node) const {
2323  return (node < left_nodes_) ? right_nodes_ : 0;
2324 }
2325 
2326 template <typename NodeIndexType, typename ArcIndexType>
2329  NodeIndexType node) const {
2330  if (node < left_nodes_) {
2331  return IntegerRange<ArcIndexType>(right_nodes_ * node,
2332  right_nodes_ * (node + 1));
2333  } else {
2334  return IntegerRange<ArcIndexType>(0, 0);
2335  }
2336 }
2337 
2338 template <typename NodeIndexType, typename ArcIndexType>
2341  NodeIndexType node, ArcIndexType from) const {
2342  if (node < left_nodes_) {
2343  return IntegerRange<ArcIndexType>(from, right_nodes_ * (node + 1));
2344  } else {
2345  return IntegerRange<ArcIndexType>(0, 0);
2346  }
2347 }
2348 
2349 template <typename NodeIndexType, typename ArcIndexType>
2352  NodeIndexType node) const {
2353  if (node < left_nodes_) {
2354  return IntegerRange<NodeIndexType>(left_nodes_, left_nodes_ + right_nodes_);
2355  } else {
2356  return IntegerRange<NodeIndexType>(0, 0);
2357  }
2358 }
2359 
2360 // Defining the simplest Graph interface as Graph for convenience.
2362 
2363 } // namespace util
2364 
2365 #undef DEFINE_RANGE_BASED_ARC_ITERATION
2366 #undef DEFINE_STL_ITERATOR_FUNCTIONS
2367 
2368 #endif // UTIL_GRAPH_GRAPH_H_
ArcIndexType arc_capacity_
Definition: graph.h:281
static const NodeIndexType kNilNode
Definition: graph.h:260
IntegerRange< ArcIndex > AllForwardArcs() const
Definition: graph.h:942
void GroupForwardArcsByFunctor(const A &a, B *b)
Definition: graph.h:266
void FreezeCapacities()
Definition: graph.h:973
bool IsNodeValid(NodeIndexType node) const
Definition: graph.h:215
virtual void ReserveArcs(ArcIndexType bound)
Definition: graph.h:243
void Reserve(NodeIndexType node_capacity, ArcIndexType arc_capacity)
Definition: graph.h:249
NodeIndexType node_capacity_
Definition: graph.h:279
ArcIndexType num_arcs() const
Definition: graph.h:206
void BuildStartAndForwardHead(SVector< NodeIndexType > *head, std::vector< ArcIndexType > *start, std::vector< ArcIndexType > *permutation)
Definition: graph.h:1002
NodeIndexType num_nodes() const
Definition: graph.h:203
ArcIndexType arc_capacity() const
Definition: graph.h:966
IntegerRange< NodeIndex > AllNodes() const
Definition: graph.h:936
bool const_capacities_
Definition: graph.h:282
ArcIndexType ArcIndex
Definition: graph.h:192
NodeIndexType num_nodes_
Definition: graph.h:278
static const ArcIndexType kNilArc
Definition: graph.h:261
void ComputeCumulativeSum(std::vector< ArcIndexType > *v)
Definition: graph.h:985
ArcIndexType max_end_arc_index() const
Definition: graph.h:269
virtual ~BaseGraph()
Definition: graph.h:200
NodeIndexType node_capacity() const
Definition: graph.h:958
bool IsArcValid(ArcIndexType arc) const
Definition: graph.h:221
NodeIndexType NodeIndex
Definition: graph.h:191
ArcIndexType num_arcs_
Definition: graph.h:280
virtual void ReserveNodes(NodeIndexType bound)
Definition: graph.h:237
OutgoingArcIterator(const CompleteBipartiteGraph &graph, NodeIndexType node)
Definition: graph.h:2287
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
Definition: graph.h:2328
NodeIndexType Tail(ArcIndexType arc) const
Definition: graph.h:2314
ArcIndexType OutDegree(NodeIndexType node) const
Definition: graph.h:2321
CompleteBipartiteGraph(NodeIndexType left_nodes, NodeIndexType right_nodes)
Definition: graph.h:2268
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
Definition: graph.h:2351
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
Definition: graph.h:2340
NodeIndexType Head(ArcIndexType arc) const
Definition: graph.h:2307
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
Definition: graph.h:2225
NodeIndexType Tail(ArcIndexType arc) const
Definition: graph.h:2211
CompleteGraph(NodeIndexType num_nodes)
Definition: graph.h:2187
ArcIndexType OutDegree(NodeIndexType node) const
Definition: graph.h:2218
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
Definition: graph.h:2244
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
Definition: graph.h:2235
NodeIndexType Head(ArcIndexType arc) const
Definition: graph.h:2204
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator)
OutgoingArcIterator(const ListGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1185
OutgoingArcIterator(const ListGraph &graph, NodeIndexType node)
Definition: graph.h:1181
ArcIndexType Index() const
Definition: graph.h:1192
const NodeIndexType * pointer
Definition: graph.h:1210
NodeIndexType Index() const
Definition: graph.h:1225
const NodeIndexType & reference
Definition: graph.h:1211
bool operator!=(const typename ListGraph< NodeIndexType, ArcIndexType >::OutgoingHeadIterator &other) const
Definition: graph.h:1231
NodeIndexType operator*() const
Definition: graph.h:1236
std::input_iterator_tag iterator_category
Definition: graph.h:1208
OutgoingHeadIterator(const ListGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1218
OutgoingHeadIterator(const ListGraph &graph, NodeIndexType node)
Definition: graph.h:1214
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
Definition: graph.h:1104
ListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
Definition: graph.h:314
NodeIndexType Tail(ArcIndexType arc) const
Definition: graph.h:1111
void ReserveArcs(ArcIndexType bound) override
Definition: graph.h:1162
void ReserveNodes(NodeIndexType bound) override
Definition: graph.h:1155
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void Build()
Definition: graph.h:341
void AddNode(NodeIndexType node)
Definition: graph.h:1133
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Definition: graph.h:1141
ArcIndexType OutDegree(NodeIndexType node) const
Definition: graph.h:1125
NodeIndexType Head(ArcIndexType arc) const
Definition: graph.h:1118
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
IncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1593
IncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
Definition: graph.h:1591
OppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1565
DEFINE_STL_ITERATOR_FUNCTIONS(OppositeIncomingArcIterator)
OppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
Definition: graph.h:1560
OutgoingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
Definition: graph.h:1531
OutgoingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1535
OutgoingHeadIterator(const ReverseArcListGraph &graph, NodeIndexType node)
Definition: graph.h:1651
OutgoingHeadIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1655
OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
Definition: graph.h:1613
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator)
OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1619
ArcIndexType OppositeArc(ArcIndexType arc) const
Definition: graph.h:1459
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
Definition: graph.h:1473
void ReserveArcs(ArcIndexType bound) override
Definition: graph.h:1488
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
void ReserveNodes(NodeIndexType bound) override
Definition: graph.h:1479
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType InDegree(NodeIndexType node) const
Definition: graph.h:1451
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
Definition: graph.h:1497
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Definition: graph.h:1507
ReverseArcListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
Definition: graph.h:473
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
Definition: graph.h:1443
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
Definition: graph.h:1466
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
Definition: graph.h:1435
IncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
Definition: graph.h:2110
IncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:2112
DEFINE_STL_ITERATOR_FUNCTIONS(OppositeIncomingArcIterator)
OppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:2084
OppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
Definition: graph.h:2077
OutgoingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:2051
OutgoingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
Definition: graph.h:2049
OutgoingOrOppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
Definition: graph.h:2129
OutgoingOrOppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:2139
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator)
ArcIndexType OppositeArc(ArcIndexType arc) const
Definition: graph.h:1968
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
Definition: graph.h:1983
void ReserveArcs(ArcIndexType bound) override
Definition: graph.h:1990
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType InDegree(NodeIndexType node) const
Definition: graph.h:1952
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
Definition: graph.h:1961
void AddNode(NodeIndexType node)
Definition: graph.h:1998
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Definition: graph.h:2006
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
Definition: graph.h:1946
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
Definition: graph.h:1975
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
ReverseArcMixedGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
Definition: graph.h:649
IncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
Definition: graph.h:1872
IncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1874
OppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
Definition: graph.h:1837
OppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1845
DEFINE_STL_ITERATOR_FUNCTIONS(OppositeIncomingArcIterator)
OutgoingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1811
OutgoingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
Definition: graph.h:1809
OutgoingOrOppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
Definition: graph.h:1894
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator)
OutgoingOrOppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1904
ArcIndexType OppositeArc(ArcIndexType arc) const
Definition: graph.h:1709
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
Definition: graph.h:1725
ReverseArcStaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
Definition: graph.h:561
void ReserveArcs(ArcIndexType bound) override
Definition: graph.h:1732
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType InDegree(NodeIndexType node) const
Definition: graph.h:1695
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
Definition: graph.h:1702
void AddNode(NodeIndexType node)
Definition: graph.h:1740
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Definition: graph.h:1748
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
Definition: graph.h:1689
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
Definition: graph.h:1717
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
T * data() const
Definition: graph.h:844
SVector(const SVector &other)
Definition: graph.h:781
const T & operator[](int n) const
Definition: graph.h:819
SVector(SVector &&other)
Definition: graph.h:803
SVector & operator=(const SVector &other)
Definition: graph.h:782
void resize(int n)
Definition: graph.h:825
void clear_and_dealloc()
Definition: graph.h:898
void reserve(int n)
Definition: graph.h:852
SVector & operator=(SVector &&other)
Definition: graph.h:804
void grow(const T &left=T(), const T &right=T())
Definition: graph.h:875
void clear()
Definition: graph.h:842
int capacity() const
Definition: graph.h:894
void swap(SVector< T > &x)
Definition: graph.h:846
int max_size() const
Definition: graph.h:896
T & operator[](int n)
Definition: graph.h:813
int size() const
Definition: graph.h:892
OutgoingArcIterator(const StaticGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: graph.h:1396
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator)
OutgoingArcIterator(const StaticGraph &graph, NodeIndexType node)
Definition: graph.h:1394
ArcIndexType Index() const
Definition: graph.h:1403
NodeIndexType Tail(ArcIndexType arc) const
Definition: graph.h:1307
void ReserveArcs(ArcIndexType bound) override
Definition: graph.h:1270
void ReserveNodes(NodeIndexType bound) override
Definition: graph.h:1262
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void Build()
Definition: graph.h:436
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
Definition: graph.h:1250
void AddNode(NodeIndexType node)
Definition: graph.h:1278
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Definition: graph.h:1286
StaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
Definition: graph.h:409
ArcIndexType OutDegree(NodeIndexType node) const
Definition: graph.h:1256
NodeIndexType Head(ArcIndexType arc) const
Definition: graph.h:1314
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
ListGraph Graph
Definition: graph.h:2361
DEFINE_RANGE_BASED_ARC_ITERATION(ListGraph, Outgoing, Base::kNilArc)
void Permute(const IntVector &permutation, Array *array_to_permute)
Definition: graph.h:739
void PermuteWithExplicitElementType(const IntVector &permutation, Array *array_to_permute, ElementType unused)
Definition: graph.h:726