C++ Reference

C++ Reference: Graph

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