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