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