C++ Reference

C++ Reference: Graph

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