C++ Reference

C++ Reference: Graph

ebert_graph.h
Go to the documentation of this file.
1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #ifndef OR_TOOLS_GRAPH_EBERT_GRAPH_H_
15 #define OR_TOOLS_GRAPH_EBERT_GRAPH_H_
16 
17 // A few variations on a theme of the "star" graph representation by
18 // Ebert, as described in J. Ebert, "A versatile data structure for
19 // edge-oriented graph algorithms." Communications of the ACM
20 // 30(6):513-519 (June 1987).
21 // http://portal.acm.org/citation.cfm?id=214769
22 //
23 // In this file there are three representations that have much in
24 // common. The general one, called simply EbertGraph, contains both
25 // forward- and backward-star representations. The other, called
26 // ForwardEbertGraph, contains only the forward-star representation of
27 // the graph, and is appropriate for applications where the reverse
28 // arcs are not needed.
29 //
30 // The point of including all the representations in this one file is
31 // to capitalize, where possible, on the commonalities among them, and
32 // those commonalities are mostly factored out into base classes as
33 // described below. Despite the commonalities, however, each of the
34 // three representations presents a somewhat different interface
35 // because of their different underlying semantics. A quintessential
36 // example is that the AddArc() method, very natural for the
37 // EbertGraph representation, cannot exist for an inherently static
38 // representation like ForwardStaticGraph.
39 //
40 // Many clients are expected to use the interfaces to the graph
41 // objects directly, but some clients are parameterized by graph type
42 // and need a consistent interface for their underlying graph
43 // objects. For such clients, a small library of class templates is
44 // provided to give a consistent interface to clients where the
45 // underlying graph interfaces differ. Examples are the
46 // AnnotatedGraphBuildManager<> template, which provides a uniform
47 // interface for building the various types of graphs; and the
48 // TailArrayManager<> template, which provides a uniform interface for
49 // applications that need to map from arc indices to arc tail nodes,
50 // accounting for the fact that such a mapping has to be requested
51 // explicitly from the ForwardStaticGraph and ForwardStarGraph
52 // representations.
53 //
54 // There are two base class templates, StarGraphBase, and
55 // EbertGraphBase; their purpose is to hold methods and data
56 // structures that are in common among their descendants. Only classes
57 // that are leaves in the following hierarchy tree are eligible for
58 // free-standing instantiation and use by clients. The parentheses
59 // around StarGraphBase and EbertGraphBase indicate that they should
60 // not normally be instantiated by clients:
61 //
62 // (StarGraphBase) |
63 // / \ |
64 // / \ |
65 // / \ |
66 // / \ |
67 // (EbertGraphBase) ForwardStaticGraph |
68 // / \ |
69 // / \ |
70 // EbertGraph ForwardEbertGraph |
71 //
72 // In the general EbertGraph case, the graph is represented with three
73 // arrays.
74 // Let n be the number of nodes and m be the number of arcs.
75 // Let i be an integer in [0..m-1], denoting the index of an arc.
76 // * head_[i] contains the end-node of arc i,
77 // * head_[-i-1] contains the start-node of arc i.
78 // Note that in two's-complement arithmetic, -i-1 = ~i.
79 // Consequently:
80 // * head_[~i] contains the end-node of the arc reverse to arc i,
81 // * head_[i] contains the start-node of the arc reverse to arc i.
82 // Note that if arc (u, v) is defined, then the data structure also stores
83 // (v, u).
84 // Arc ~i thus denotes the arc reverse to arc i.
85 // This is what makes this representation useful for undirected graphs and for
86 // implementing algorithms like bidirectional shortest paths.
87 // Also note that the representation handles multi-graphs. If several arcs
88 // going from node u to node v are added to the graph, they will be handled as
89 // separate arcs.
90 //
91 // Now, for an integer u in [0..n-1] denoting the index of a node:
92 // * first_incident_arc_[u] denotes the first arc in the adjacency list of u.
93 // * going from an arc i, the adjacency list can be traversed using
94 // j = next_adjacent_arc_[i].
95 //
96 // The EbertGraph implementation has the following benefits:
97 // * It is able to handle both directed or undirected graphs.
98 // * Being based on indices, it is easily serializable. Only the contents
99 // of the head_ array need to be stored. Even so, serialization is
100 // currently not implemented.
101 // * The node indices and arc indices can be stored in 32 bits, while
102 // still allowing to go a bit further than the 4-gigabyte
103 // limitation (48 gigabytes for a pure graph, without capacities or
104 // costs.)
105 // * The representation can be recomputed if edges have been loaded from
106 // * The representation can be recomputed if edges have been loaded from
107 // external memory or if edges have been re-ordered.
108 // * The memory consumption is: 2 * m * sizeof(NodeIndexType)
109 // + 2 * m * sizeof(ArcIndexType)
110 // + n * sizeof(ArcIndexType)
111 // plus a small constant.
112 //
113 // The EbertGraph implementation differs from the implementation described in
114 // [Ebert 1987] in the following respects:
115 // * arcs are represented using an (i, ~i) approach, whereas Ebert used
116 // (i, -i). Indices for direct arcs thus start at 0, in a fashion that is
117 // compatible with the index numbering in C and C++. Note that we also tested
118 // a (2*i, 2*i+1) storage pattern, which did not show any speed benefit, and
119 // made the use of the API much more difficult.
120 // * because of this, the 'nil' values for nodes and arcs are not 0, as Ebert
121 // first described. The value for the 'nil' node is set to -1, while the
122 // value for the 'nil' arc is set to the smallest integer representable with
123 // ArcIndexSize bytes.
124 // * it is possible to add arcs to the graph, with AddArc, in a much simpler
125 // way than described by Ebert.
126 // * TODO(user) although it is already possible, using the
127 // GroupForwardArcsByFunctor method, to group all the outgoing (resp.
128 // incoming) arcs of a node, the iterator logic could still be improved to
129 // allow traversing the outgoing (resp. incoming) arcs in O(out_degree(node))
130 // (resp. O(in_degree(node))) instead of O(degree(node)).
131 // * TODO(user) it is possible to implement arc deletion and garbage collection
132 // in an efficient (relatively) manner. For the time being we haven't seen an
133 // application for this.
134 //
135 // The ForwardEbertGraph representation is like the EbertGraph case described
136 // above, with the following modifications:
137 // * The part of the head_[] array with negative indices is absent. In its
138 // place is a pointer tail_ which, if assigned, points to an array of tail
139 // nodes indexed by (nonnegative) arc index. In typical usage tail_ is NULL
140 // and the memory for the tail nodes need not be allocated.
141 // * The array of arc tails can be allocated as needed and populated from the
142 // adjacency lists of the graph.
143 // * Representing only the forward star of each node implies that the graph
144 // cannot be serialized directly nor rebuilt from scratch from just the head_
145 // array. Rebuilding from scratch requires constructing the array of arc
146 // tails from the adjacency lists first, and serialization can be done either
147 // by first constructing the array of arc tails from the adjacency lists, or
148 // by serializing directly from the adjacency lists.
149 // * The memory consumption is: m * sizeof(NodeIndexType)
150 // + m * sizeof(ArcIndexType)
151 // + n * sizeof(ArcIndexType)
152 // plus a small constant when the array of arc tails is absent. Allocating
153 // the arc tail array adds another m * sizeof(NodeIndexType).
154 //
155 // The ForwardStaticGraph representation is restricted yet farther
156 // than ForwardEbertGraph, with the benefit that it provides higher
157 // performance to those applications that can use it.
158 // * As with ForwardEbertGraph, the presence of the array of arc
159 // tails is optional.
160 // * The outgoing adjacency list for each node is stored in a
161 // contiguous segment of the head_[] array, obviating the
162 // next_adjacent_arc_ structure entirely and ensuring good locality
163 // of reference for applications that iterate over outgoing
164 // adjacency lists.
165 // * The memory consumption is: m * sizeof(NodeIndexType)
166 // + n * sizeof(ArcIndexType)
167 // plus a small constant when the array of arc tails is absent. Allocating
168 // the arc tail array adds another m * sizeof(NodeIndexType).
169 
170 #include <algorithm>
171 #include <cstdint>
172 #include <limits>
173 #include <memory>
174 #include <string>
175 #include <utility>
176 #include <vector>
177 
178 #include "absl/strings/str_cat.h"
179 #include "ortools/base/integral_types.h"
180 #include "ortools/base/logging.h"
181 #include "ortools/base/macros.h"
182 #include "ortools/util/permutation.h"
183 #include "ortools/util/zvector.h"
184 
185 namespace operations_research {
186 
187 // Forward declarations.
188 template <typename NodeIndexType, typename ArcIndexType>
190 template <typename NodeIndexType, typename ArcIndexType>
192 template <typename NodeIndexType, typename ArcIndexType>
194 
195 // Standard instantiation of ForwardEbertGraph (named 'ForwardStarGraph') of
196 // EbertGraph (named 'StarGraph'); and relevant type shortcuts. Unless their use
197 // cases prevent them from doing so, users are encouraged to use StarGraph or
198 // ForwardStarGraph according to whether or not they require reverse arcs to be
199 // represented explicitly. Along with either graph representation, the other
200 // type shortcuts here will often come in handy.
201 typedef int32_t NodeIndex;
202 typedef int32_t ArcIndex;
203 typedef int64_t FlowQuantity;
204 typedef int64_t CostValue;
208 typedef ZVector<NodeIndex> NodeIndexArray;
209 typedef ZVector<ArcIndex> ArcIndexArray;
210 typedef ZVector<FlowQuantity> QuantityArray;
211 typedef ZVector<CostValue> CostArray;
212 
213 template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
215  public:
216  // The index of the 'nil' node in the graph.
217  static const NodeIndexType kNilNode;
218 
219  // The index of the 'nil' arc in the graph.
220  static const ArcIndexType kNilArc;
221 
222  // The index of the first node in the graph.
223  static const NodeIndexType kFirstNode;
224 
225  // The index of the first arc in the graph.
226  static const ArcIndexType kFirstArc;
227 
228  // The maximum possible number of nodes in the graph. (The maximum
229  // index is kMaxNumNodes-1, since indices start at 0. Unfortunately
230  // we waste a value representing this and the max_num_nodes_ member.)
231  static const NodeIndexType kMaxNumNodes;
232 
233  // The maximum possible number of arcs in the graph. (The maximum
234  // index is kMaxNumArcs-1, since indices start at 0. Unfortunately
235  // we waste a value representing this and the max_num_arcs_ member.)
236  static const ArcIndexType kMaxNumArcs;
237  // Returns the number of nodes in the graph.
238  NodeIndexType num_nodes() const { return num_nodes_; }
239 
240  // Returns the number of original arcs in the graph
241  // (The ones with positive indices.)
242  ArcIndexType num_arcs() const { return num_arcs_; }
243 
244  // Returns one more than the largest index of an extant node,
245  // meaning a node that is mentioned as the head or tail of some arc
246  // in the graph. To be used as a helper when clients need to
247  // dimension or iterate over arrays of node annotation information.
248  NodeIndexType end_node_index() const { return kFirstNode + num_nodes_; }
249 
250  // Returns one more than the largest index of an extant direct
251  // arc. To be used as a helper when clients need to dimension or
252  // iterate over arrays of arc annotation information.
253  ArcIndexType end_arc_index() const { return kFirstArc + num_arcs_; }
254 
255  // Returns the maximum possible number of nodes in the graph.
256  NodeIndexType max_num_nodes() const { return max_num_nodes_; }
257 
258  // Returns the maximum possible number of original arcs in the graph.
259  // (The ones with positive indices.)
260  ArcIndexType max_num_arcs() const { return max_num_arcs_; }
261 
262  // Returns one more than the largest valid index of a node. To be
263  // used as a helper when clients need to dimension or iterate over
264  // arrays of node annotation information.
265  NodeIndexType max_end_node_index() const {
266  return kFirstNode + max_num_nodes_;
267  }
268 
269  // Returns one more than the largest valid index of a direct arc. To
270  // be used as a helper when clients need to dimension or iterate
271  // over arrays of arc annotation information.
272  ArcIndexType max_end_arc_index() const { return kFirstArc + max_num_arcs_; }
273 
274  // Utility function to check that a node index is within the bounds AND
275  // different from kNilNode.
276  // Returns true if node is in the range [kFirstNode .. max_num_nodes_).
277  // It is exported so that users of the DerivedGraph class can use it.
278  // To be used in a DCHECK; also used internally to validate
279  // arguments passed to our methods from clients (e.g., AddArc()).
280  bool IsNodeValid(NodeIndexType node) const {
281  return node >= kFirstNode && node < max_num_nodes_;
282  }
283 
284  // Returns the first arc going from tail to head, if it exists, or kNilArc
285  // if such an arc does not exist.
286  ArcIndexType LookUpArc(const NodeIndexType tail,
287  const NodeIndexType head) const {
288  for (ArcIndexType arc = FirstOutgoingArc(tail); arc != kNilArc;
289  arc = ThisAsDerived()->NextOutgoingArc(tail, arc)) {
290  if (Head(arc) == head) {
291  return arc;
292  }
293  }
294  return kNilArc;
295  }
296 
297  // Returns the head or end-node of arc.
298  NodeIndexType Head(const ArcIndexType arc) const {
299  DCHECK(ThisAsDerived()->CheckArcValidity(arc));
300  return head_[arc];
301  }
302 
303  std::string NodeDebugString(const NodeIndexType node) const {
304  if (node == kNilNode) {
305  return "NilNode";
306  } else {
307  return absl::StrCat(static_cast<int64_t>(node));
308  }
309  }
310 
311  std::string ArcDebugString(const ArcIndexType arc) const {
312  if (arc == kNilArc) {
313  return "NilArc";
314  } else {
315  return absl::StrCat(static_cast<int64_t>(arc));
316  }
317  }
318 
319 #if !defined(SWIG)
320  // Iterator class for traversing all the nodes in the graph.
321  class NodeIterator {
322  public:
323  explicit NodeIterator(const DerivedGraph& graph)
324  : graph_(graph), head_(graph_.StartNode(kFirstNode)) {}
325 
326  // Returns true unless all the nodes have been traversed.
327  bool Ok() const { return head_ != kNilNode; }
328 
329  // Advances the current node index.
330  void Next() { head_ = graph_.NextNode(head_); }
331 
332  // Returns the index of the node currently pointed to by the iterator.
333  NodeIndexType Index() const { return head_; }
334 
335  private:
336  // A reference to the current DerivedGraph considered.
337  const DerivedGraph& graph_;
338 
339  // The index of the current node considered.
340  NodeIndexType head_;
341  };
342 
343  // Iterator class for traversing the arcs in the graph.
344  class ArcIterator {
345  public:
346  explicit ArcIterator(const DerivedGraph& graph)
347  : graph_(graph), arc_(graph_.StartArc(kFirstArc)) {}
348 
349  // Returns true unless all the arcs have been traversed.
350  bool Ok() const { return arc_ != kNilArc; }
351 
352  // Advances the current arc index.
353  void Next() { arc_ = graph_.NextArc(arc_); }
354 
355  // Returns the index of the arc currently pointed to by the iterator.
356  ArcIndexType Index() const { return arc_; }
357 
358  private:
359  // A reference to the current DerivedGraph considered.
360  const DerivedGraph& graph_;
361 
362  // The index of the current arc considered.
363  ArcIndexType arc_;
364  };
365 
366  // Iterator class for traversing the outgoing arcs associated to a given node.
368  public:
369  OutgoingArcIterator(const DerivedGraph& graph, NodeIndexType node)
370  : graph_(graph),
371  node_(graph_.StartNode(node)),
372  arc_(graph_.StartArc(graph_.FirstOutgoingArc(node))) {
373  DCHECK(CheckInvariant());
374  }
375 
376  // This constructor takes an arc as extra argument and makes the iterator
377  // start at arc.
378  OutgoingArcIterator(const DerivedGraph& graph, NodeIndexType node,
379  ArcIndexType arc)
380  : graph_(graph),
381  node_(graph_.StartNode(node)),
382  arc_(graph_.StartArc(arc)) {
383  DCHECK(CheckInvariant());
384  }
385 
386  // Can only assign from an iterator on the same graph.
387  void operator=(const OutgoingArcIterator& iterator) {
388  DCHECK(&iterator.graph_ == &graph_);
389  node_ = iterator.node_;
390  arc_ = iterator.arc_;
391  }
392 
393  // Returns true unless all the outgoing arcs have been traversed.
394  bool Ok() const { return arc_ != kNilArc; }
395 
396  // Advances the current outgoing arc index.
397  void Next() {
398  arc_ = graph_.NextOutgoingArc(node_, arc_);
399  DCHECK(CheckInvariant());
400  }
401 
402  // Returns the index of the arc currently pointed to by the iterator.
403  ArcIndexType Index() const { return arc_; }
404 
405  private:
406  // Returns true if the invariant for the iterator is verified.
407  // To be used in a DCHECK.
408  bool CheckInvariant() const {
409  if (arc_ == kNilArc) {
410  return true; // This occurs when the iterator has reached the end.
411  }
412  DCHECK(graph_.IsOutgoing(arc_, node_));
413  return true;
414  }
415 
416  // A reference to the current DerivedGraph considered.
417  const DerivedGraph& graph_;
418 
419  // The index of the node on which arcs are iterated.
420  NodeIndexType node_;
421 
422  // The index of the current arc considered.
423  ArcIndexType arc_;
424  };
425 #endif // SWIG
426 
427  protected:
429  : max_num_nodes_(0),
430  max_num_arcs_(0),
431  num_nodes_(0),
432  num_arcs_(0),
434 
436 
437  // Returns kNilNode if the graph has no nodes or node if it has at least one
438  // node. Useful for initializing iterators correctly in the case of empty
439  // graphs.
440  NodeIndexType StartNode(NodeIndexType node) const {
441  return num_nodes_ == 0 ? kNilNode : node;
442  }
443 
444  // Returns kNilArc if the graph has no arcs arc if it has at least one arc.
445  // Useful for initializing iterators correctly in the case of empty graphs.
446  ArcIndexType StartArc(ArcIndexType arc) const {
447  return num_arcs_ == 0 ? kNilArc : arc;
448  }
449 
450  // Returns the node following the argument in the graph.
451  // Returns kNilNode (= end) if the range of nodes has been exhausted.
452  // It is called by NodeIterator::Next() and as such does not expect to be
453  // passed an argument equal to kNilNode.
454  // This is why the return line is simplified from
455  // return (node == kNilNode || next_node >= num_nodes_)
456  // ? kNilNode : next_node;
457  // to
458  // return next_node < num_nodes_ ? next_node : kNilNode;
459  NodeIndexType NextNode(const NodeIndexType node) const {
460  DCHECK(IsNodeValid(node));
461  const NodeIndexType next_node = node + 1;
462  return next_node < num_nodes_ ? next_node : kNilNode;
463  }
464 
465  // Returns the arc following the argument in the graph.
466  // Returns kNilArc (= end) if the range of arcs has been exhausted.
467  // It is called by ArcIterator::Next() and as such does not expect to be
468  // passed an argument equal to kNilArc.
469  // This is why the return line is simplified from
470  // return ( arc == kNilArc || next_arc >= num_arcs_) ? kNilArc : next_arc;
471  // to
472  // return next_arc < num_arcs_ ? next_arc : kNilArc;
473  ArcIndexType NextArc(const ArcIndexType arc) const {
474  DCHECK(ThisAsDerived()->CheckArcValidity(arc));
475  const ArcIndexType next_arc = arc + 1;
476  return next_arc < num_arcs_ ? next_arc : kNilArc;
477  }
478 
479  // Returns the first outgoing arc for node.
480  ArcIndexType FirstOutgoingArc(const NodeIndexType node) const {
481  DCHECK(IsNodeValid(node));
482  return ThisAsDerived()->FindNextOutgoingArc(
483  ThisAsDerived()->FirstOutgoingOrOppositeIncomingArc(node));
484  }
485 
486  // The maximum number of nodes that the graph can hold.
487  NodeIndexType max_num_nodes_;
488 
489  // The maximum number of arcs that the graph can hold.
490  ArcIndexType max_num_arcs_;
491 
492  // The maximum index of the node currently held by the graph.
493  NodeIndexType num_nodes_;
494 
495  // The current number of arcs held by the graph.
496  ArcIndexType num_arcs_;
497 
498  // Array of node indices. head_[i] contains the head node of arc i.
499  ZVector<NodeIndexType> head_;
500 
501  // Array of arc indices. first_incident_arc_[i] contains the first arc
502  // incident to node i.
503  ZVector<ArcIndexType> first_incident_arc_;
504 
505  private:
506  // Shorthand: returns a const DerivedGraph*-typed version of our
507  // "this" pointer.
508  inline const DerivedGraph* ThisAsDerived() const {
509  return static_cast<const DerivedGraph*>(this);
510  }
511 
512  // Shorthand: returns a DerivedGraph*-typed version of our "this"
513  // pointer.
514  inline DerivedGraph* ThisAsDerived() {
515  return static_cast<DerivedGraph*>(this);
516  }
517 };
518 
519 template <typename NodeIndexType, typename ArcIndexType>
521  public:
523  const ZVector<NodeIndexType>& head)
524  : head_(head) {}
525 
526  bool operator()(ArcIndexType a, ArcIndexType b) const {
527  return head_[a] < head_[b];
528  }
529 
530  private:
531  const ZVector<NodeIndexType>& head_;
532 };
533 
534 template <typename NodeIndexType, typename ArcIndexType>
535 class ForwardStaticGraph
536  : public StarGraphBase<NodeIndexType, ArcIndexType,
537  ForwardStaticGraph<NodeIndexType, ArcIndexType> > {
538  typedef StarGraphBase<NodeIndexType, ArcIndexType,
539  ForwardStaticGraph<NodeIndexType, ArcIndexType> >
540  Base;
541  friend class StarGraphBase<NodeIndexType, ArcIndexType,
542  ForwardStaticGraph<NodeIndexType, ArcIndexType> >;
543 
544  using Base::ArcDebugString;
545  using Base::NodeDebugString;
546 
548  using Base::head_;
549  using Base::max_num_arcs_;
550  using Base::max_num_nodes_;
551  using Base::num_arcs_;
552  using Base::num_nodes_;
553 
554  public:
555 #if !defined(SWIG)
556  using Base::end_arc_index;
557  using Base::Head;
558  using Base::IsNodeValid;
559 
560  using Base::kFirstArc;
561  using Base::kFirstNode;
562  using Base::kNilArc;
563 #endif // SWIG
564 
565  typedef NodeIndexType NodeIndex;
566  typedef ArcIndexType ArcIndex;
567 
568 // TODO(user): Configure SWIG to handle the
569 // CycleHandlerForAnnotatedArcs class.
570 #if !defined(SWIG)
572  : public ArrayIndexCycleHandler<NodeIndexType, ArcIndexType> {
573  typedef ArrayIndexCycleHandler<NodeIndexType, ArcIndexType> Base;
574 
575  public:
577  PermutationCycleHandler<ArcIndexType>* annotation_handler,
578  NodeIndexType* data)
579  : ArrayIndexCycleHandler<NodeIndexType, ArcIndexType>(&data[kFirstArc]),
580  annotation_handler_(annotation_handler) {}
581 
582  void SetTempFromIndex(ArcIndexType source) override {
583  Base::SetTempFromIndex(source);
584  annotation_handler_->SetTempFromIndex(source);
585  }
586 
587  void SetIndexFromIndex(ArcIndexType source,
588  ArcIndexType destination) const override {
589  Base::SetIndexFromIndex(source, destination);
590  annotation_handler_->SetIndexFromIndex(source, destination);
591  }
592 
593  void SetIndexFromTemp(ArcIndexType destination) const override {
594  Base::SetIndexFromTemp(destination);
595  annotation_handler_->SetIndexFromTemp(destination);
596  }
597 
598  private:
599  PermutationCycleHandler<ArcIndexType>* annotation_handler_;
600 
601  DISALLOW_COPY_AND_ASSIGN(CycleHandlerForAnnotatedArcs);
602  };
603 #endif // SWIG
604 
605  // Constructor for use by GraphBuilderFromArcs instances and direct
606  // clients that want to materialize a graph in one step.
607  // Materializing all at once is the only choice available with a
608  // static graph.
609  //
610  // Args:
611  // sort_arcs_by_head: determines whether arcs incident to each tail
612  // node are sorted by head node.
613  // client_cycle_handler: if non-NULL, mediates the permutation of
614  // arbitrary annotation data belonging to the client according
615  // to the permutation applied to the arcs in forming the
616  // graph. Two permutations may be composed to form the final one
617  // that affects the arcs. First, the arcs are always permuted to
618  // group them by tail node because ForwardStaticGraph requires
619  // this. Second, if each node's outgoing arcs are sorted by head
620  // node (according to sort_arcs_by_head), that sorting implies
621  // an additional permutation on the arcs.
623  const NodeIndexType num_nodes, const ArcIndexType num_arcs,
624  const bool sort_arcs_by_head,
625  std::vector<std::pair<NodeIndexType, NodeIndexType> >* client_input_arcs,
626  // TODO(user): For some reason, SWIG breaks if the
627  // operations_research namespace is not explicit in the
628  // following argument declaration.
629  operations_research::PermutationCycleHandler<ArcIndexType>* const
630  client_cycle_handler) {
634  // A more convenient name for a parameter required by style to be
635  // a pointer, because we modify its referent.
636  std::vector<std::pair<NodeIndexType, NodeIndexType> >& input_arcs =
637  *client_input_arcs;
638 
639  // We coopt the first_incident_arc_ array as a node-indexed vector
640  // used for two purposes related to degree before setting up its
641  // final values. First, it counts the out-degree of each
642  // node. Second, it is reused to count the number of arcs outgoing
643  // from each node that have already been put in place from the
644  // given input_arcs. We reserve an extra entry as a sentinel at
645  // the end.
647  first_incident_arc_.SetAll(0);
648  for (ArcIndexType arc = kFirstArc; arc < kFirstArc + num_arcs; ++arc) {
649  first_incident_arc_[kFirstNode + input_arcs[arc].first] += 1;
650  // Take this opportunity to see how many nodes are really
651  // mentioned in the arc list.
652  num_nodes_ = std::max(
653  num_nodes_, static_cast<NodeIndexType>(input_arcs[arc].first + 1));
654  num_nodes_ = std::max(
655  num_nodes_, static_cast<NodeIndexType>(input_arcs[arc].second + 1));
656  }
657  ArcIndexType next_arc = kFirstArc;
658  for (NodeIndexType node = 0; node < num_nodes; ++node) {
659  ArcIndexType degree = first_incident_arc_[kFirstNode + node];
660  first_incident_arc_[kFirstNode + node] = next_arc;
661  next_arc += degree;
662  }
663  DCHECK_EQ(num_arcs, next_arc);
664  head_.Reserve(kFirstArc, kFirstArc + num_arcs - 1);
665  std::unique_ptr<ArcIndexType[]> arc_permutation;
666  if (client_cycle_handler != nullptr) {
667  arc_permutation.reset(new ArcIndexType[end_arc_index()]);
668  for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
669  NodeIndexType tail = input_arcs[input_arc].first;
670  NodeIndexType head = input_arcs[input_arc].second;
671  ArcIndexType arc = first_incident_arc_[kFirstNode + tail];
672  // The head_ entry will get permuted into the right place
673  // later.
674  head_[kFirstArc + input_arc] = kFirstNode + head;
675  arc_permutation[kFirstArc + arc] = input_arc;
676  first_incident_arc_[kFirstNode + tail] += 1;
677  }
678  } else {
679  if (sizeof(input_arcs[0].first) >= sizeof(first_incident_arc_[0])) {
680  // We reuse the input_arcs[].first entries to hold our
681  // mapping to the head_ array. This allows us to spread out
682  // cache badness.
683  for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
684  NodeIndexType tail = input_arcs[input_arc].first;
685  ArcIndexType arc = first_incident_arc_[kFirstNode + tail];
686  first_incident_arc_[kFirstNode + tail] = arc + 1;
687  input_arcs[input_arc].first = static_cast<NodeIndexType>(arc);
688  }
689  for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
690  ArcIndexType arc =
691  static_cast<ArcIndexType>(input_arcs[input_arc].first);
692  NodeIndexType head = input_arcs[input_arc].second;
693  head_[kFirstArc + arc] = kFirstNode + head;
694  }
695  } else {
696  // We cannot reuse the input_arcs[].first entries so we map to
697  // the head_ array in a single loop.
698  for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
699  NodeIndexType tail = input_arcs[input_arc].first;
700  NodeIndexType head = input_arcs[input_arc].second;
701  ArcIndexType arc = first_incident_arc_[kFirstNode + tail];
702  first_incident_arc_[kFirstNode + tail] = arc + 1;
703  head_[kFirstArc + arc] = kFirstNode + head;
704  }
705  }
706  }
707  // Shift the entries in first_incident_arc_ to compensate for the
708  // counting each one has done through its incident arcs. Note that
709  // there is a special sentry element at the end of
710  // first_incident_arc_.
711  for (NodeIndexType node = kFirstNode + num_nodes; node > /* kFirstNode */ 0;
712  --node) {
713  first_incident_arc_[node] = first_incident_arc_[node - 1];
714  }
716  if (sort_arcs_by_head) {
717  ArcIndexType begin = first_incident_arc_[kFirstNode];
718  if (client_cycle_handler != nullptr) {
719  for (NodeIndexType node = 0; node < num_nodes; ++node) {
720  ArcIndexType end = first_incident_arc_[node + 1];
721  std::sort(
722  &arc_permutation[begin], &arc_permutation[end],
724  head_));
725  begin = end;
726  }
727  } else {
728  for (NodeIndexType node = 0; node < num_nodes; ++node) {
729  ArcIndexType end = first_incident_arc_[node + 1];
730  // The second argument in the following has a strange index
731  // expression because ZVector claims that no index is valid
732  // unless it refers to an element in the vector. In particular
733  // an index one past the end is invalid.
734  ArcIndexType begin_index = (begin < num_arcs ? begin : begin - 1);
735  ArcIndexType begin_offset = (begin < num_arcs ? 0 : 1);
736  ArcIndexType end_index = (end > 0 ? end - 1 : end);
737  ArcIndexType end_offset = (end > 0 ? 1 : 0);
738  std::sort(&head_[begin_index] + begin_offset,
739  &head_[end_index] + end_offset);
740  begin = end;
741  }
742  }
743  }
744  if (client_cycle_handler != nullptr && num_arcs > 0) {
745  // Apply the computed permutation if we haven't already.
746  CycleHandlerForAnnotatedArcs handler_for_constructor(
747  client_cycle_handler, &head_[kFirstArc] - kFirstArc);
748  // We use a permutation cycle handler to place the head array
749  // indices and permute the client's arc annotation data along
750  // with them.
751  PermutationApplier<ArcIndexType> permutation(&handler_for_constructor);
752  permutation.Apply(&arc_permutation[0], kFirstArc, end_arc_index());
753  }
754  }
755 
756  // Returns the tail or start-node of arc.
757  NodeIndexType Tail(const ArcIndexType arc) const {
758  DCHECK(CheckArcValidity(arc));
759  DCHECK(CheckTailIndexValidity(arc));
760  return (*tail_)[arc];
761  }
762 
763  // Returns true if arc is incoming to node.
764  bool IsIncoming(ArcIndexType arc, NodeIndexType node) const {
765  return Head(arc) == node;
766  }
767 
768  // Utility function to check that an arc index is within the bounds.
769  // It is exported so that users of the ForwardStaticGraph class can use it.
770  // To be used in a DCHECK.
771  bool CheckArcBounds(const ArcIndexType arc) const {
772  return ((arc == kNilArc) || (arc >= kFirstArc && arc < max_num_arcs_));
773  }
774 
775  // Utility function to check that an arc index is within the bounds AND
776  // different from kNilArc.
777  // It is exported so that users of the ForwardStaticGraph class can use it.
778  // To be used in a DCHECK.
779  bool CheckArcValidity(const ArcIndexType arc) const {
780  return ((arc != kNilArc) && (arc >= kFirstArc && arc < max_num_arcs_));
781  }
782 
783  // Returns true if arc is a valid index into the (*tail_) array.
784  bool CheckTailIndexValidity(const ArcIndexType arc) const {
785  return ((tail_ != nullptr) && (arc >= kFirstArc) &&
786  (arc <= tail_->max_index()));
787  }
788 
789  ArcIndexType NextOutgoingArc(const NodeIndexType node,
790  ArcIndexType arc) const {
791  DCHECK(IsNodeValid(node));
792  DCHECK(CheckArcValidity(arc));
793  ++arc;
794  if (arc < first_incident_arc_[node + 1]) {
795  return arc;
796  } else {
797  return kNilArc;
798  }
799  }
800 
801  // Returns a debug string containing all the information contained in the
802  // data structure in raw form.
803  std::string DebugString() const {
804  std::string result = "Arcs:(node) :\n";
805  for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) {
806  result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) +
807  ")\n";
808  }
809  result += "Node:First arc :\n";
810  for (NodeIndexType node = kFirstNode; node <= num_nodes_; ++node) {
811  result += " " + NodeDebugString(node) + ":" +
812  ArcDebugString(first_incident_arc_[node]) + "\n";
813  }
814  return result;
815  }
816 
817  bool BuildTailArray() {
818  // If (*tail_) is already allocated, we have the invariant that
819  // its contents are canonical, so we do not need to do anything
820  // here in that case except return true.
821  if (tail_ == nullptr) {
822  if (!RepresentationClean()) {
823  // We have been asked to build the (*tail_) array, but we have
824  // no valid information from which to build it. The graph is
825  // in an unrecoverable, inconsistent state.
826  return false;
827  }
828  // Reallocate (*tail_) and rebuild its contents from the
829  // adjacency lists.
830  tail_.reset(new ZVector<NodeIndexType>);
831  tail_->Reserve(kFirstArc, max_num_arcs_ - 1);
832  typename Base::NodeIterator node_it(*this);
833  for (; node_it.Ok(); node_it.Next()) {
834  NodeIndexType node = node_it.Index();
835  typename Base::OutgoingArcIterator arc_it(*this, node);
836  for (; arc_it.Ok(); arc_it.Next()) {
837  (*tail_)[arc_it.Index()] = node;
838  }
839  }
840  }
841  DCHECK(TailArrayComplete());
842  return true;
843  }
844 
845  void ReleaseTailArray() { tail_.reset(nullptr); }
846 
847  // To be used in a DCHECK().
848  bool TailArrayComplete() const {
849  CHECK(tail_);
850  for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) {
851  CHECK(CheckTailIndexValidity(arc));
852  CHECK(IsNodeValid((*tail_)[arc]));
853  }
854  return true;
855  }
856 
857  private:
858  bool IsDirect() const { return true; }
859  bool RepresentationClean() const { return true; }
860  bool IsOutgoing(const NodeIndexType node,
861  const ArcIndexType unused_arc) const {
862  return true;
863  }
864 
865  // Returns the first arc in node's incidence list.
866  ArcIndexType FirstOutgoingOrOppositeIncomingArc(NodeIndexType node) const {
867  DCHECK(RepresentationClean());
868  DCHECK(IsNodeValid(node));
869  ArcIndexType result = first_incident_arc_[node];
870  return ((result != first_incident_arc_[node + 1]) ? result : kNilArc);
871  }
872 
873  // Utility method that finds the next outgoing arc.
874  ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const {
875  DCHECK(CheckArcBounds(arc));
876  return arc;
877  }
878 
879  // Array of node indices, not always present. (*tail_)[i] contains
880  // the tail node of arc i. This array is not needed for normal graph
881  // traversal operations, but is used in optimizing the graph's
882  // layout so arcs are grouped by tail node, and can be used in one
883  // approach to serializing the graph.
884  //
885  // Invariants: At any time when we are not executing a method of
886  // this class, either tail_ == NULL or the tail_ array's contents
887  // are kept canonical. If tail_ != NULL, any method that modifies
888  // adjacency lists must also ensure (*tail_) is modified
889  // correspondingly. The converse does not hold: Modifications to
890  // (*tail_) are allowed without updating the adjacency lists. If
891  // such modifications take place, representation_clean_ must be set
892  // to false, of course, to indicate that the adjacency lists are no
893  // longer current.
894  std::unique_ptr<ZVector<NodeIndexType> > tail_;
895 };
896 
897 // The index of the 'nil' node in the graph.
898 template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
899 const NodeIndexType
901 
902 // The index of the 'nil' arc in the graph.
903 template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
904 const ArcIndexType
906  std::numeric_limits<ArcIndexType>::min();
907 
908 // The index of the first node in the graph.
909 template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
910 const NodeIndexType
912 
913 // The index of the first arc in the graph.
914 template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
915 const ArcIndexType
917 
918 // The maximum possible node index in the graph.
919 template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
920 const NodeIndexType
922  std::numeric_limits<NodeIndexType>::max();
923 
924 // The maximum possible number of arcs in the graph.
925 // (The maximum index is kMaxNumArcs-1, since indices start at 0.)
926 template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
927 const ArcIndexType
929  std::numeric_limits<ArcIndexType>::max();
930 
931 // A template for the base class that holds the functionality that exists in
932 // common between the EbertGraph<> template and the ForwardEbertGraph<>
933 // template.
934 //
935 // This template is for internal use only, and this is enforced by making all
936 // constructors for this class template protected. Clients should use one of the
937 // two derived-class templates. Most clients will not even use those directly,
938 // but will use the StarGraph and ForwardStarGraph typenames declared above.
939 //
940 // The DerivedGraph template argument must be the type of the class (typically
941 // itself built from a template) that:
942 // 1. implements the full interface expected for either ForwardEbertGraph or
943 // EbertGraph, and
944 // 2. inherits from an instance of this template.
945 // The base class needs access to some members of the derived class such as, for
946 // example, NextOutgoingArc(), and it gets this access via the DerivedGraph
947 // template argument.
948 template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
950  : public StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph> {
952  friend class StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph>;
953 
954  protected:
956  using Base::head_;
957  using Base::max_num_arcs_;
958  using Base::max_num_nodes_;
959  using Base::num_arcs_;
960  using Base::num_nodes_;
961 
962  public:
963 #if !SWIG
964  using Base::end_arc_index;
965  using Base::IsNodeValid;
966 
967  using Base::kFirstArc;
968  using Base::kFirstNode;
969  using Base::kMaxNumArcs;
970  using Base::kMaxNumNodes;
971  using Base::kNilArc;
972  using Base::kNilNode;
973 #endif // SWIG
974 
975  // Reserves memory needed for max_num_nodes nodes and max_num_arcs arcs.
976  // Returns false if the parameters passed are not OK.
977  // It can be used to enlarge the graph, but does not shrink memory
978  // if called with smaller values.
979  bool Reserve(NodeIndexType new_max_num_nodes, ArcIndexType new_max_num_arcs) {
980  if (new_max_num_nodes < 0 || new_max_num_nodes > kMaxNumNodes) {
981  return false;
982  }
983  if (new_max_num_arcs < 0 || new_max_num_arcs > kMaxNumArcs) {
984  return false;
985  }
986  first_incident_arc_.Reserve(kFirstNode, new_max_num_nodes - 1);
987  for (NodeIndexType node = max_num_nodes_;
988  node <= first_incident_arc_.max_index(); ++node) {
989  first_incident_arc_.Set(node, kNilArc);
990  }
991  ThisAsDerived()->ReserveInternal(new_max_num_nodes, new_max_num_arcs);
992  max_num_nodes_ = new_max_num_nodes;
993  max_num_arcs_ = new_max_num_arcs;
994  return true;
995  }
996 
997  // Adds an arc to the graph and returns its index.
998  // Returns kNilArc if the arc could not be added.
999  // Note that for a given pair (tail, head) AddArc does not overwrite an
1000  // already-existing arc between tail and head: Another arc is created
1001  // instead. This makes it possible to handle multi-graphs.
1002  ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head) {
1003  if (num_arcs_ >= max_num_arcs_ || !IsNodeValid(tail) ||
1004  !IsNodeValid(head)) {
1005  return kNilArc;
1006  }
1007  if (tail + 1 > num_nodes_) {
1008  num_nodes_ = tail + 1; // max does not work on int16_t.
1009  }
1010  if (head + 1 > num_nodes_) {
1011  num_nodes_ = head + 1;
1012  }
1013  ArcIndexType arc = num_arcs_;
1014  ++num_arcs_;
1015  ThisAsDerived()->RecordArc(arc, tail, head);
1016  return arc;
1017  }
1018 
1019 // TODO(user): Configure SWIG to handle the GroupForwardArcsByFunctor
1020 // member template and the CycleHandlerForAnnotatedArcs class.
1021 #if !SWIG
1022  template <typename ArcIndexTypeStrictWeakOrderingFunctor>
1024  const ArcIndexTypeStrictWeakOrderingFunctor& compare,
1025  PermutationCycleHandler<ArcIndexType>* annotation_handler) {
1026  std::unique_ptr<ArcIndexType[]> arc_permutation(
1027  new ArcIndexType[end_arc_index()]);
1028 
1029  // Determine the permutation that groups arcs by their tail nodes.
1030  for (ArcIndexType i = 0; i < end_arc_index(); ++i) {
1031  // Start with the identity permutation.
1032  arc_permutation[i] = i;
1033  }
1034  std::sort(&arc_permutation[kFirstArc], &arc_permutation[end_arc_index()],
1035  compare);
1036 
1037  // Now we actually permute the head_ array and the
1038  // scaled_arc_cost_ array according to the sorting permutation.
1039  CycleHandlerForAnnotatedArcs cycle_handler(annotation_handler,
1040  ThisAsDerived());
1041  PermutationApplier<ArcIndexType> permutation(&cycle_handler);
1042  permutation.Apply(&arc_permutation[0], kFirstArc, end_arc_index());
1043 
1044  // Finally, rebuild the graph from its permuted head_ array.
1045  ThisAsDerived()->BuildRepresentation();
1046  }
1047 
1049  : public PermutationCycleHandler<ArcIndexType> {
1050  public:
1052  PermutationCycleHandler<ArcIndexType>* annotation_handler,
1053  DerivedGraph* graph)
1054  : annotation_handler_(annotation_handler),
1055  graph_(graph),
1056  head_temp_(kNilNode),
1057  tail_temp_(kNilNode) {}
1058 
1059  void SetTempFromIndex(ArcIndexType source) override {
1060  if (annotation_handler_ != nullptr) {
1061  annotation_handler_->SetTempFromIndex(source);
1062  }
1063  head_temp_ = graph_->Head(source);
1064  tail_temp_ = graph_->Tail(source);
1065  }
1066 
1067  void SetIndexFromIndex(ArcIndexType source,
1068  ArcIndexType destination) const override {
1069  if (annotation_handler_ != nullptr) {
1070  annotation_handler_->SetIndexFromIndex(source, destination);
1071  }
1072  graph_->SetHead(destination, graph_->Head(source));
1073  graph_->SetTail(destination, graph_->Tail(source));
1074  }
1075 
1076  void SetIndexFromTemp(ArcIndexType destination) const override {
1077  if (annotation_handler_ != nullptr) {
1078  annotation_handler_->SetIndexFromTemp(destination);
1079  }
1080  graph_->SetHead(destination, head_temp_);
1081  graph_->SetTail(destination, tail_temp_);
1082  }
1083 
1084  // Since we are free to destroy the permutation array we use the
1085  // kNilArc value to mark entries in the array that have been
1086  // processed already. There is no need to be able to recover the
1087  // original permutation array entries once they have been seen.
1088  void SetSeen(ArcIndexType* permutation_element) const override {
1089  *permutation_element = kNilArc;
1090  }
1091 
1092  bool Unseen(ArcIndexType permutation_element) const override {
1093  return permutation_element != kNilArc;
1094  }
1095 
1097 
1098  private:
1099  PermutationCycleHandler<ArcIndexType>* annotation_handler_;
1100  DerivedGraph* graph_;
1101  NodeIndexType head_temp_;
1102  NodeIndexType tail_temp_;
1103 
1104  DISALLOW_COPY_AND_ASSIGN(CycleHandlerForAnnotatedArcs);
1105  };
1106 #endif // SWIG
1107 
1108  protected:
1110 
1112 
1113  void Initialize(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) {
1115  LOG(DFATAL) << "Could not reserve memory for "
1116  << static_cast<int64_t>(max_num_nodes) << " nodes and "
1117  << static_cast<int64_t>(max_num_arcs) << " arcs.";
1118  }
1119  first_incident_arc_.SetAll(kNilArc);
1120  ThisAsDerived()->InitializeInternal(max_num_nodes, max_num_arcs);
1121  }
1122 
1123  // Returns the first arc in node's incidence list.
1125  const NodeIndexType node) const {
1126  DCHECK(representation_clean_);
1127  DCHECK(IsNodeValid(node));
1128  return first_incident_arc_[node];
1129  }
1130 
1131  // Returns the next arc following the passed argument in its adjacency list.
1132  ArcIndexType NextAdjacentArc(const ArcIndexType arc) const {
1133  DCHECK(representation_clean_);
1134  DCHECK(ThisAsDerived()->CheckArcValidity(arc));
1135  return next_adjacent_arc_[arc];
1136  }
1137 
1138  // Returns the outgoing arc following the argument in the adjacency list.
1139  ArcIndexType NextOutgoingArc(const NodeIndexType unused_node,
1140  const ArcIndexType arc) const {
1141  DCHECK(ThisAsDerived()->CheckArcValidity(arc));
1142  DCHECK(ThisAsDerived()->IsDirect(arc));
1143  return ThisAsDerived()->FindNextOutgoingArc(NextAdjacentArc(arc));
1144  }
1145 
1146  // Array of next indices.
1147  // next_adjacent_arc_[i] contains the next arc in the adjacency list of arc i.
1148  ZVector<ArcIndexType> next_adjacent_arc_;
1149 
1150  // Flag to indicate that BuildRepresentation() needs to be called
1151  // before the adjacency lists are examined. Only for DCHECK in debug
1152  // builds.
1154 
1155  private:
1156  // Shorthand: returns a const DerivedGraph*-typed version of our
1157  // "this" pointer.
1158  inline const DerivedGraph* ThisAsDerived() const {
1159  return static_cast<const DerivedGraph*>(this);
1160  }
1161 
1162  // Shorthand: returns a DerivedGraph*-typed version of our "this"
1163  // pointer.
1164  inline DerivedGraph* ThisAsDerived() {
1165  return static_cast<DerivedGraph*>(this);
1166  }
1167 
1168  void InitializeInternal(NodeIndexType max_num_nodes,
1169  ArcIndexType max_num_arcs) {
1170  next_adjacent_arc_.SetAll(kNilArc);
1171  }
1172 
1173  bool RepresentationClean() const { return representation_clean_; }
1174 
1175  // Using the SetHead() method implies that the BuildRepresentation()
1176  // method must be called to restore consistency before the graph is
1177  // used.
1178  void SetHead(const ArcIndexType arc, const NodeIndexType head) {
1179  representation_clean_ = false;
1180  head_.Set(arc, head);
1181  }
1182 };
1183 
1184 // Most users should only use StarGraph, which is EbertGraph<int32_t, int32_t>,
1185 // and other type shortcuts; see the bottom of this file.
1186 template <typename NodeIndexType, typename ArcIndexType>
1187 class EbertGraph
1188  : public EbertGraphBase<NodeIndexType, ArcIndexType,
1189  EbertGraph<NodeIndexType, ArcIndexType> > {
1190  typedef EbertGraphBase<NodeIndexType, ArcIndexType,
1191  EbertGraph<NodeIndexType, ArcIndexType> >
1192  Base;
1193  friend class EbertGraphBase<NodeIndexType, ArcIndexType,
1194  EbertGraph<NodeIndexType, ArcIndexType> >;
1195  friend class StarGraphBase<NodeIndexType, ArcIndexType,
1196  EbertGraph<NodeIndexType, ArcIndexType> >;
1197 
1198  using Base::ArcDebugString;
1200  using Base::Initialize;
1201  using Base::NextAdjacentArc;
1202  using Base::NodeDebugString;
1203 
1205  using Base::head_;
1206  using Base::max_num_arcs_;
1207  using Base::max_num_nodes_;
1209  using Base::num_arcs_;
1210  using Base::num_nodes_;
1212 
1213  public:
1214 #if !SWIG
1215  using Base::Head;
1216  using Base::IsNodeValid;
1217 
1218  using Base::kFirstArc;
1219  using Base::kFirstNode;
1220  using Base::kNilArc;
1221  using Base::kNilNode;
1222 #endif // SWIG
1223 
1224  typedef NodeIndexType NodeIndex;
1225  typedef ArcIndexType ArcIndex;
1226 
1228 
1229  EbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) {
1231  }
1232 
1234 
1235 #if !SWIG
1236  // Iterator class for traversing the arcs incident to a given node in the
1237  // graph.
1239  public:
1241  NodeIndexType node)
1242  : graph_(graph),
1243  node_(graph_.StartNode(node)),
1244  arc_(graph_.StartArc(
1245  graph_.FirstOutgoingOrOppositeIncomingArc(node))) {
1246  DCHECK(CheckInvariant());
1247  }
1248 
1249  // This constructor takes an arc as extra argument and makes the iterator
1250  // start at arc.
1252  NodeIndexType node, ArcIndexType arc)
1253  : graph_(graph),
1254  node_(graph_.StartNode(node)),
1255  arc_(graph_.StartArc(arc)) {
1256  DCHECK(CheckInvariant());
1257  }
1258 
1259  // Can only assign from an iterator on the same graph.
1261  DCHECK(&iterator.graph_ == &graph_);
1262  node_ = iterator.node_;
1263  arc_ = iterator.arc_;
1264  }
1265 
1266  // Returns true unless all the adjancent arcs have been traversed.
1267  bool Ok() const { return arc_ != kNilArc; }
1268 
1269  // Advances the current adjacent arc index.
1270  void Next() {
1271  arc_ = graph_.NextAdjacentArc(arc_);
1272  DCHECK(CheckInvariant());
1273  }
1274 
1275  // Returns the index of the arc currently pointed to by the iterator.
1276  ArcIndexType Index() const { return arc_; }
1277 
1278  private:
1279  // Returns true if the invariant for the iterator is verified.
1280  // To be used in a DCHECK.
1281  bool CheckInvariant() const {
1282  if (arc_ == kNilArc) {
1283  return true; // This occurs when the iterator has reached the end.
1284  }
1285  DCHECK(graph_.IsOutgoingOrOppositeIncoming(arc_, node_));
1286  return true;
1287  }
1288  // A reference to the current EbertGraph considered.
1289  const EbertGraph& graph_;
1290 
1291  // The index of the node on which arcs are iterated.
1292  NodeIndexType node_;
1293 
1294  // The index of the current arc considered.
1295  ArcIndexType arc_;
1296  };
1297 
1298  // Iterator class for traversing the incoming arcs associated to a given node.
1300  public:
1301  IncomingArcIterator(const EbertGraph& graph, NodeIndexType node)
1302  : graph_(graph),
1303  node_(graph_.StartNode(node)),
1304  arc_(graph_.StartArc(graph_.FirstIncomingArc(node))) {
1305  DCHECK(CheckInvariant());
1306  }
1307 
1308  // This constructor takes an arc as extra argument and makes the iterator
1309  // start at arc.
1310  IncomingArcIterator(const EbertGraph& graph, NodeIndexType node,
1311  ArcIndexType arc)
1312  : graph_(graph),
1313  node_(graph_.StartNode(node)),
1314  arc_(arc == kNilArc ? kNilArc
1315  : graph_.StartArc(graph_.Opposite(arc))) {
1316  DCHECK(CheckInvariant());
1317  }
1318 
1319  // Can only assign from an iterator on the same graph.
1320  void operator=(const IncomingArcIterator& iterator) {
1321  DCHECK(&iterator.graph_ == &graph_);
1322  node_ = iterator.node_;
1323  arc_ = iterator.arc_;
1324  }
1325 
1326  // Returns true unless all the incoming arcs have been traversed.
1327  bool Ok() const { return arc_ != kNilArc; }
1328 
1329  // Advances the current incoming arc index.
1330  void Next() {
1331  arc_ = graph_.NextIncomingArc(arc_);
1332  DCHECK(CheckInvariant());
1333  }
1334 
1335  // Returns the index of the arc currently pointed to by the iterator.
1336  ArcIndexType Index() const {
1337  return arc_ == kNilArc ? kNilArc : graph_.Opposite(arc_);
1338  }
1339 
1340  private:
1341  // Returns true if the invariant for the iterator is verified.
1342  // To be used in a DCHECK.
1343  bool CheckInvariant() const {
1344  if (arc_ == kNilArc) {
1345  return true; // This occurs when the iterator has reached the end.
1346  }
1347  DCHECK(graph_.IsIncoming(Index(), node_));
1348  return true;
1349  }
1350  // A reference to the current EbertGraph considered.
1351  const EbertGraph& graph_;
1352 
1353  // The index of the node on which arcs are iterated.
1354  NodeIndexType node_;
1355 
1356  // The index of the current arc considered.
1357  ArcIndexType arc_;
1358  };
1359 #endif // SWIG
1360 
1361  // Utility function to check that an arc index is within the bounds.
1362  // It is exported so that users of the EbertGraph class can use it.
1363  // To be used in a DCHECK.
1364  bool CheckArcBounds(const ArcIndexType arc) const {
1365  return (arc == kNilArc) || (arc >= -max_num_arcs_ && arc < max_num_arcs_);
1366  }
1367 
1368  // Utility function to check that an arc index is within the bounds AND
1369  // different from kNilArc.
1370  // It is exported so that users of the EbertGraph class can use it.
1371  // To be used in a DCHECK.
1372  bool CheckArcValidity(const ArcIndexType arc) const {
1373  return (arc != kNilArc) && (arc >= -max_num_arcs_ && arc < max_num_arcs_);
1374  }
1375 
1376  // Returns the tail or start-node of arc.
1377  NodeIndexType Tail(const ArcIndexType arc) const {
1378  DCHECK(CheckArcValidity(arc));
1379  return head_[Opposite(arc)];
1380  }
1381 
1382  // Returns the tail or start-node of arc if it is positive
1383  // (i.e. it is taken in the direction it was entered in the graph),
1384  // and the head or end-node otherwise. 'This' in Ebert's paper.
1385  NodeIndexType DirectArcTail(const ArcIndexType arc) const {
1386  return Tail(DirectArc(arc));
1387  }
1388 
1389  // Returns the head or end-node of arc if it is positive
1390  // (i.e. it is taken in the direction it was entered in the graph),
1391  // and the tail or start-node otherwise. 'That' in Ebert's paper.
1392  NodeIndexType DirectArcHead(const ArcIndexType arc) const {
1393  return Head(DirectArc(arc));
1394  }
1395 
1396  // Returns the arc in normal/direct direction.
1397  ArcIndexType DirectArc(const ArcIndexType arc) const {
1398  DCHECK(CheckArcValidity(arc));
1399  return std::max(arc, Opposite(arc));
1400  }
1401 
1402  // Returns the arc in reverse direction.
1403  ArcIndexType ReverseArc(const ArcIndexType arc) const {
1404  DCHECK(CheckArcValidity(arc));
1405  return std::min(arc, Opposite(arc));
1406  }
1407 
1408  // Returns the opposite arc, i.e the direct arc is the arc is in reverse
1409  // direction, and the reverse arc if the arc is direct.
1410  ArcIndexType Opposite(const ArcIndexType arc) const {
1411  const ArcIndexType opposite = ~arc;
1412  DCHECK(CheckArcValidity(arc));
1413  DCHECK(CheckArcValidity(opposite));
1414  return opposite;
1415  }
1416 
1417  // Returns true if the arc is direct.
1418  bool IsDirect(const ArcIndexType arc) const {
1419  DCHECK(CheckArcBounds(arc));
1420  return arc != kNilArc && arc >= 0;
1421  }
1422 
1423  // Returns true if the arc is in the reverse direction.
1424  bool IsReverse(const ArcIndexType arc) const {
1425  DCHECK(CheckArcBounds(arc));
1426  return arc != kNilArc && arc < 0;
1427  }
1428 
1429  // Returns true if arc is incident to node.
1430  bool IsOutgoingOrOppositeIncoming(ArcIndexType arc,
1431  NodeIndexType node) const {
1432  return Tail(arc) == node;
1433  }
1434 
1435  // Returns true if arc is incoming to node.
1436  bool IsIncoming(ArcIndexType arc, NodeIndexType node) const {
1437  return IsDirect(arc) && Head(arc) == node;
1438  }
1439 
1440  // Returns true if arc is outgoing from node.
1441  bool IsOutgoing(ArcIndexType arc, NodeIndexType node) const {
1442  return IsDirect(arc) && Tail(arc) == node;
1443  }
1444 
1445  // Recreates the next_adjacent_arc_ and first_incident_arc_ variables from
1446  // the array head_ in O(n + m) time.
1447  // This is useful if head_ array has been sorted according to a given
1448  // criterion, for example.
1450  first_incident_arc_.SetAll(kNilArc);
1451  for (ArcIndexType arc = kFirstArc; arc < max_num_arcs_; ++arc) {
1452  Attach(arc);
1453  }
1454  representation_clean_ = true;
1455  }
1456 
1457  // Returns a debug string containing all the information contained in the
1458  // data structure in raw form.
1459  std::string DebugString() const {
1460  DCHECK(representation_clean_);
1461  std::string result = "Arcs:(node, next arc) :\n";
1462  for (ArcIndexType arc = -num_arcs_; arc < num_arcs_; ++arc) {
1463  result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) +
1464  "," + ArcDebugString(next_adjacent_arc_[arc]) + ")\n";
1465  }
1466  result += "Node:First arc :\n";
1467  for (NodeIndexType node = kFirstNode; node < num_nodes_; ++node) {
1468  result += " " + NodeDebugString(node) + ":" +
1469  ArcDebugString(first_incident_arc_[node]) + "\n";
1470  }
1471  return result;
1472  }
1473 
1474  private:
1475  // Handles reserving space in the next_adjacent_arc_ and head_
1476  // arrays, which are always present and are therefore in the base
1477  // class. Although they reside in the base class, those two arrays
1478  // are maintained differently by different derived classes,
1479  // depending on whether the derived class stores reverse arcs. Hence
1480  // the code to set those arrays up is in a method of the derived
1481  // class.
1482  void ReserveInternal(NodeIndexType new_max_num_nodes,
1483  ArcIndexType new_max_num_arcs) {
1484  head_.Reserve(-new_max_num_arcs, new_max_num_arcs - 1);
1485  next_adjacent_arc_.Reserve(-new_max_num_arcs, new_max_num_arcs - 1);
1486  for (ArcIndexType arc = -new_max_num_arcs; arc < -max_num_arcs_; ++arc) {
1487  head_.Set(arc, kNilNode);
1488  next_adjacent_arc_.Set(arc, kNilArc);
1489  }
1490  for (ArcIndexType arc = max_num_arcs_; arc < new_max_num_arcs; ++arc) {
1491  head_.Set(arc, kNilNode);
1492  next_adjacent_arc_.Set(arc, kNilArc);
1493  }
1494  }
1495 
1496  // Returns the first incoming arc for node.
1497  ArcIndexType FirstIncomingArc(const NodeIndexType node) const {
1498  DCHECK_LE(kFirstNode, node);
1499  DCHECK_GE(max_num_nodes_, node);
1500  return FindNextIncomingArc(FirstOutgoingOrOppositeIncomingArc(node));
1501  }
1502 
1503  // Returns the incoming arc following the argument in the adjacency list.
1504  ArcIndexType NextIncomingArc(const ArcIndexType arc) const {
1505  DCHECK(CheckArcValidity(arc));
1506  DCHECK(IsReverse(arc));
1507  return FindNextIncomingArc(NextAdjacentArc(arc));
1508  }
1509 
1510  // Handles the part of AddArc() that is not in common with other
1511  // graph classes based on the EbertGraphBase template.
1512  void RecordArc(ArcIndexType arc, NodeIndexType tail, NodeIndexType head) {
1513  head_.Set(Opposite(arc), tail);
1514  head_.Set(arc, head);
1515  Attach(arc);
1516  }
1517 
1518  // Using the SetTail() method implies that the BuildRepresentation()
1519  // method must be called to restore consistency before the graph is
1520  // used.
1521  void SetTail(const ArcIndexType arc, const NodeIndexType tail) {
1522  representation_clean_ = false;
1523  head_.Set(Opposite(arc), tail);
1524  }
1525 
1526  // Utility method to attach a new arc.
1527  void Attach(ArcIndexType arc) {
1528  DCHECK(CheckArcValidity(arc));
1529  const NodeIndexType tail = head_[Opposite(arc)];
1530  DCHECK(IsNodeValid(tail));
1531  next_adjacent_arc_.Set(arc, first_incident_arc_[tail]);
1532  first_incident_arc_.Set(tail, arc);
1533  const NodeIndexType head = head_[arc];
1534  DCHECK(IsNodeValid(head));
1536  first_incident_arc_.Set(head, Opposite(arc));
1537  }
1538 
1539  // Utility method that finds the next outgoing arc.
1540  ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const {
1541  DCHECK(CheckArcBounds(arc));
1542  while (IsReverse(arc)) {
1543  arc = NextAdjacentArc(arc);
1544  DCHECK(CheckArcBounds(arc));
1545  }
1546  return arc;
1547  }
1548 
1549  // Utility method that finds the next incoming arc.
1550  ArcIndexType FindNextIncomingArc(ArcIndexType arc) const {
1551  DCHECK(CheckArcBounds(arc));
1552  while (IsDirect(arc)) {
1553  arc = NextAdjacentArc(arc);
1554  DCHECK(CheckArcBounds(arc));
1555  }
1556  return arc;
1557  }
1558 };
1559 
1560 // A forward-star-only graph representation for greater efficiency in
1561 // those algorithms that don't need reverse arcs.
1562 template <typename NodeIndexType, typename ArcIndexType>
1563 class ForwardEbertGraph
1564  : public EbertGraphBase<NodeIndexType, ArcIndexType,
1565  ForwardEbertGraph<NodeIndexType, ArcIndexType> > {
1566  typedef EbertGraphBase<NodeIndexType, ArcIndexType,
1567  ForwardEbertGraph<NodeIndexType, ArcIndexType> >
1568  Base;
1569  friend class EbertGraphBase<NodeIndexType, ArcIndexType,
1570  ForwardEbertGraph<NodeIndexType, ArcIndexType> >;
1571  friend class StarGraphBase<NodeIndexType, ArcIndexType,
1572  ForwardEbertGraph<NodeIndexType, ArcIndexType> >;
1573 
1574  using Base::ArcDebugString;
1575  using Base::Initialize;
1576  using Base::NextAdjacentArc;
1577  using Base::NodeDebugString;
1578 
1580  using Base::head_;
1581  using Base::max_num_arcs_;
1582  using Base::max_num_nodes_;
1584  using Base::num_arcs_;
1585  using Base::num_nodes_;
1587 
1588  public:
1589 #if !SWIG
1590  using Base::Head;
1591  using Base::IsNodeValid;
1592 
1593  using Base::kFirstArc;
1594  using Base::kFirstNode;
1595  using Base::kNilArc;
1596  using Base::kNilNode;
1597 #endif // SWIG
1598 
1599  typedef NodeIndexType NodeIndex;
1600  typedef ArcIndexType ArcIndex;
1601 
1603 
1604  ForwardEbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) {
1606  }
1607 
1609 
1610  // Utility function to check that an arc index is within the bounds.
1611  // It is exported so that users of the ForwardEbertGraph class can use it.
1612  // To be used in a DCHECK.
1613  bool CheckArcBounds(const ArcIndexType arc) const {
1614  return (arc == kNilArc) || (arc >= kFirstArc && arc < max_num_arcs_);
1615  }
1616 
1617  // Utility function to check that an arc index is within the bounds AND
1618  // different from kNilArc.
1619  // It is exported so that users of the ForwardEbertGraph class can use it.
1620  // To be used in a DCHECK.
1621  bool CheckArcValidity(const ArcIndexType arc) const {
1622  return (arc != kNilArc) && (arc >= kFirstArc && arc < max_num_arcs_);
1623  }
1624 
1625  // Returns true if arc is a valid index into the (*tail_) array.
1626  bool CheckTailIndexValidity(const ArcIndexType arc) const {
1627  return (tail_ != nullptr) && (arc >= kFirstArc) &&
1628  (arc <= tail_->max_index());
1629  }
1630 
1631  // Returns the tail or start-node of arc.
1632  NodeIndexType Tail(const ArcIndexType arc) const {
1633  DCHECK(CheckArcValidity(arc));
1634  DCHECK(CheckTailIndexValidity(arc));
1635  return (*tail_)[arc];
1636  }
1637 
1638  // Returns true if arc is incoming to node.
1639  bool IsIncoming(ArcIndexType arc, NodeIndexType node) const {
1640  return IsDirect(arc) && Head(arc) == node;
1641  }
1642 
1643  // Recreates the next_adjacent_arc_ and first_incident_arc_
1644  // variables from the arrays head_ and tail_ in O(n + m) time. This
1645  // is useful if the head_ and tail_ arrays have been sorted
1646  // according to a given criterion, for example.
1648  first_incident_arc_.SetAll(kNilArc);
1649  DCHECK(TailArrayComplete());
1650  for (ArcIndexType arc = kFirstArc; arc < max_num_arcs_; ++arc) {
1651  DCHECK(CheckTailIndexValidity(arc));
1652  Attach((*tail_)[arc], arc);
1653  }
1654  representation_clean_ = true;
1655  }
1656 
1658  // If (*tail_) is already allocated, we have the invariant that
1659  // its contents are canonical, so we do not need to do anything
1660  // here in that case except return true.
1661  if (tail_ == nullptr) {
1662  if (!representation_clean_) {
1663  // We have been asked to build the (*tail_) array, but we have
1664  // no valid information from which to build it. The graph is
1665  // in an unrecoverable, inconsistent state.
1666  return false;
1667  }
1668  // Reallocate (*tail_) and rebuild its contents from the
1669  // adjacency lists.
1670  tail_.reset(new ZVector<NodeIndexType>);
1671  tail_->Reserve(kFirstArc, max_num_arcs_ - 1);
1672  typename Base::NodeIterator node_it(*this);
1673  for (; node_it.Ok(); node_it.Next()) {
1674  NodeIndexType node = node_it.Index();
1675  typename Base::OutgoingArcIterator arc_it(*this, node);
1676  for (; arc_it.Ok(); arc_it.Next()) {
1677  (*tail_)[arc_it.Index()] = node;
1678  }
1679  }
1680  }
1681  DCHECK(TailArrayComplete());
1682  return true;
1683  }
1684 
1685  void ReleaseTailArray() { tail_.reset(nullptr); }
1686 
1687  // To be used in a DCHECK().
1688  bool TailArrayComplete() const {
1689  CHECK(tail_);
1690  for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) {
1691  CHECK(CheckTailIndexValidity(arc));
1692  CHECK(IsNodeValid((*tail_)[arc]));
1693  }
1694  return true;
1695  }
1696 
1697  // Returns a debug string containing all the information contained in the
1698  // data structure in raw form.
1699  std::string DebugString() const {
1700  DCHECK(representation_clean_);
1701  std::string result = "Arcs:(node, next arc) :\n";
1702  for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) {
1703  result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) +
1704  "," + ArcDebugString(next_adjacent_arc_[arc]) + ")\n";
1705  }
1706  result += "Node:First arc :\n";
1707  for (NodeIndexType node = kFirstNode; node < num_nodes_; ++node) {
1708  result += " " + NodeDebugString(node) + ":" +
1709  ArcDebugString(first_incident_arc_[node]) + "\n";
1710  }
1711  return result;
1712  }
1713 
1714  private:
1715  // Reserves space for the (*tail_) array.
1716  //
1717  // This method is separate from ReserveInternal() because our
1718  // practice of making the (*tail_) array optional implies that the
1719  // tail_ pointer might not be constructed when the ReserveInternal()
1720  // method is called. Therefore we have this method also, and we
1721  // ensure that it is called only when tail_ is guaranteed to have
1722  // been initialized.
1723  void ReserveTailArray(ArcIndexType new_max_num_arcs) {
1724  if (tail_ != nullptr) {
1725  // The (*tail_) values are already canonical, so we're just
1726  // reserving additional space for new arcs that haven't been
1727  // added yet.
1728  if (tail_->Reserve(kFirstArc, new_max_num_arcs - 1)) {
1729  for (ArcIndexType arc = tail_->max_index() + 1; arc < new_max_num_arcs;
1730  ++arc) {
1731  tail_->Set(arc, kNilNode);
1732  }
1733  }
1734  }
1735  }
1736 
1737  // Reserves space for the arrays indexed by arc indices, except
1738  // (*tail_) even if it is present. We cannot grow the (*tail_) array
1739  // in this method because this method is called from
1740  // Base::Reserve(), which in turn is called from the base template
1741  // class constructor. That base class constructor is called on *this
1742  // before tail_ is constructed. Hence when this method is called,
1743  // tail_ might contain garbage. This method can safely refer only to
1744  // fields of the base template class, not to fields of *this outside
1745  // the base template class.
1746  //
1747  // The strange situation in which this method of a derived class can
1748  // refer only to members of the base class arises because different
1749  // derived classes use the data members of the base class in
1750  // slightly different ways. The purpose of this derived class
1751  // method, then, is only to encode the derived-class-specific
1752  // conventions for how the derived class uses the data members of
1753  // the base class.
1754  //
1755  // To be specific, the forward-star graph representation, lacking
1756  // reverse arcs, allocates only the positive index range for the
1757  // head_ and next_adjacent_arc_ arrays, while the general
1758  // representation allocates space for both positive- and
1759  // negative-indexed arcs (i.e., both forward and reverse arcs).
1760  void ReserveInternal(NodeIndexType new_max_num_nodes,
1761  ArcIndexType new_max_num_arcs) {
1762  head_.Reserve(kFirstArc, new_max_num_arcs - 1);
1763  next_adjacent_arc_.Reserve(kFirstArc, new_max_num_arcs - 1);
1764  for (ArcIndexType arc = max_num_arcs_; arc < new_max_num_arcs; ++arc) {
1765  head_.Set(arc, kNilNode);
1766  next_adjacent_arc_.Set(arc, kNilArc);
1767  }
1768  ReserveTailArray(new_max_num_arcs);
1769  }
1770 
1771  // Handles the part of AddArc() that is not in common wth other
1772  // graph classes based on the EbertGraphBase template.
1773  void RecordArc(ArcIndexType arc, NodeIndexType tail, NodeIndexType head) {
1774  head_.Set(arc, head);
1775  Attach(tail, arc);
1776  }
1777 
1778  // Using the SetTail() method implies that the BuildRepresentation()
1779  // method must be called to restore consistency before the graph is
1780  // used.
1781  void SetTail(const ArcIndexType arc, const NodeIndexType tail) {
1782  DCHECK(CheckTailIndexValidity(arc));
1783  CHECK(tail_);
1784  representation_clean_ = false;
1785  tail_->Set(arc, tail);
1786  }
1787 
1788  // Utility method to attach a new arc.
1789  void Attach(NodeIndexType tail, ArcIndexType arc) {
1790  DCHECK(CheckArcValidity(arc));
1791  DCHECK(IsNodeValid(tail));
1792  next_adjacent_arc_.Set(arc, first_incident_arc_[tail]);
1793  first_incident_arc_.Set(tail, arc);
1794  const NodeIndexType head = head_[arc];
1795  DCHECK(IsNodeValid(head));
1796  // Because Attach() is a public method, keeping (*tail_) canonical
1797  // requires us to record the new arc's tail here.
1798  if (tail_ != nullptr) {
1799  DCHECK(CheckTailIndexValidity(arc));
1800  tail_->Set(arc, tail);
1801  }
1802  }
1803 
1804  // Utility method that finds the next outgoing arc.
1805  ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const {
1806  DCHECK(CheckArcBounds(arc));
1807  return arc;
1808  }
1809 
1810  private:
1811  // Always returns true because for any ForwardEbertGraph, only
1812  // direct arcs are represented, so all valid arc indices refer to
1813  // arcs that are outgoing from their tail nodes.
1814  bool IsOutgoing(const ArcIndex unused_arc,
1815  const NodeIndex unused_node) const {
1816  return true;
1817  }
1818 
1819  // Always returns true because for any ForwardEbertGraph, only
1820  // outgoing arcs are represented, so all valid arc indices refer to
1821  // direct arcs.
1822  bool IsDirect(const ArcIndex unused_arc) const { return true; }
1823 
1824  // Array of node indices, not always present. (*tail_)[i] contains
1825  // the tail node of arc i. This array is not needed for normal graph
1826  // traversal operations, but is used in optimizing the graph's
1827  // layout so arcs are grouped by tail node, and can be used in one
1828  // approach to serializing the graph.
1829  //
1830  // Invariants: At any time when we are not executing a method of
1831  // this class, either tail_ == NULL or the tail_ array's contents
1832  // are kept canonical. If tail_ != NULL, any method that modifies
1833  // adjacency lists must also ensure (*tail_) is modified
1834  // correspondingly. The converse does not hold: Modifications to
1835  // (*tail_) are allowed without updating the adjacency lists. If
1836  // such modifications take place, representation_clean_ must be set
1837  // to false, of course, to indicate that the adjacency lists are no
1838  // longer current.
1839  std::unique_ptr<ZVector<NodeIndexType> > tail_;
1840 };
1841 
1842 // Traits for EbertGraphBase types, for use in testing and clients
1843 // that work with both forward-only and forward/reverse graphs.
1844 //
1845 // The default is to assume reverse arcs so if someone forgets to
1846 // specialize the traits of a new forward-only graph type, they will
1847 // get errors from tests rather than incomplete testing.
1848 template <typename GraphType>
1850  static constexpr bool has_reverse_arcs = true;
1851  static constexpr bool is_dynamic = true;
1852 };
1853 
1854 template <typename NodeIndexType, typename ArcIndexType>
1855 struct graph_traits<ForwardEbertGraph<NodeIndexType, ArcIndexType> > {
1856  static constexpr bool has_reverse_arcs = false;
1857  static constexpr bool is_dynamic = true;
1858 };
1859 
1860 template <typename NodeIndexType, typename ArcIndexType>
1861 struct graph_traits<ForwardStaticGraph<NodeIndexType, ArcIndexType> > {
1862  static constexpr bool has_reverse_arcs = false;
1863  static constexpr bool is_dynamic = false;
1864 };
1865 
1866 namespace or_internal {
1867 
1868 // The TailArrayBuilder class template is not expected to be used by
1869 // clients. It is a helper for the TailArrayManager template.
1870 //
1871 // The TailArrayBuilder for graphs with reverse arcs does nothing.
1872 template <typename GraphType, bool has_reverse_arcs>
1874  explicit TailArrayBuilder(GraphType* unused_graph) {}
1875 
1876  bool BuildTailArray() const { return true; }
1877 };
1878 
1879 // The TailArrayBuilder for graphs without reverse arcs calls the
1880 // appropriate method on the graph from the TailArrayBuilder
1881 // constructor.
1882 template <typename GraphType>
1883 struct TailArrayBuilder<GraphType, false> {
1884  explicit TailArrayBuilder(GraphType* graph) : graph_(graph) {}
1885 
1886  bool BuildTailArray() const { return graph_->BuildTailArray(); }
1887 
1888  GraphType* const graph_;
1889 };
1890 
1891 // The TailArrayReleaser class template is not expected to be used by
1892 // clients. It is a helper for the TailArrayManager template.
1893 //
1894 // The TailArrayReleaser for graphs with reverse arcs does nothing.
1895 template <typename GraphType, bool has_reverse_arcs>
1897  explicit TailArrayReleaser(GraphType* unused_graph) {}
1898 
1899  void ReleaseTailArray() const {}
1900 };
1901 
1902 // The TailArrayReleaser for graphs without reverse arcs calls the
1903 // appropriate method on the graph from the TailArrayReleaser
1904 // constructor.
1905 template <typename GraphType>
1906 struct TailArrayReleaser<GraphType, false> {
1907  explicit TailArrayReleaser(GraphType* graph) : graph_(graph) {}
1908 
1909  void ReleaseTailArray() const { graph_->ReleaseTailArray(); }
1910 
1911  GraphType* const graph_;
1912 };
1913 
1914 } // namespace or_internal
1915 
1916 template <typename GraphType>
1918  public:
1919  explicit TailArrayManager(GraphType* g) : graph_(g) {}
1920 
1924  tail_array_builder(graph_);
1925  return tail_array_builder.BuildTailArray();
1926  }
1927 
1931  tail_array_releaser(graph_);
1932  tail_array_releaser.ReleaseTailArray();
1933  }
1934 
1935  private:
1936  GraphType* graph_;
1937 };
1938 
1939 template <typename GraphType>
1941  public:
1942  explicit ArcFunctorOrderingByTailAndHead(const GraphType& graph)
1943  : graph_(graph) {}
1944 
1946  typename GraphType::ArcIndex b) const {
1947  return ((graph_.Tail(a) < graph_.Tail(b)) ||
1948  ((graph_.Tail(a) == graph_.Tail(b)) &&
1949  (graph_.Head(a) < graph_.Head(b))));
1950  }
1951 
1952  private:
1953  const GraphType& graph_;
1954 };
1955 
1956 namespace or_internal {
1957 
1958 // The GraphBuilderFromArcs class template is not expected to be used
1959 // by clients. It is a helper for the AnnotatedGraphBuildManager
1960 // template.
1961 //
1962 // Deletes itself upon returning the graph!
1963 template <typename GraphType, bool is_dynamic>
1965  public:
1967  typename GraphType::ArcIndex max_num_arcs,
1968  bool sort_arcs)
1969  : num_arcs_(0), sort_arcs_(sort_arcs) {
1970  Reserve(max_num_nodes, max_num_arcs);
1971  }
1972 
1974  typename GraphType::NodeIndex head) {
1975  DCHECK_LT(num_arcs_, max_num_arcs_);
1976  DCHECK_LT(tail, GraphType::kFirstNode + max_num_nodes_);
1977  DCHECK_LT(head, GraphType::kFirstNode + max_num_nodes_);
1978  if (num_arcs_ < max_num_arcs_ &&
1979  tail < GraphType::kFirstNode + max_num_nodes_ &&
1980  head < GraphType::kFirstNode + max_num_nodes_) {
1981  typename GraphType::ArcIndex result = GraphType::kFirstArc + num_arcs_;
1982  arcs_.push_back(std::make_pair(tail, head));
1983  num_arcs_ += 1;
1984  return result;
1985  } else {
1986  // Too many arcs or node index out of bounds!
1987  return GraphType::kNilArc;
1988  }
1989  }
1990 
1991  // Builds the graph from the given arcs.
1992  GraphType* Graph(PermutationCycleHandler<typename GraphType::ArcIndex>*
1993  client_cycle_handler) {
1994  GraphType* graph = new GraphType(max_num_nodes_, num_arcs_, sort_arcs_,
1995  &arcs_, client_cycle_handler);
1996  delete this;
1997  return graph;
1998  }
1999 
2000  private:
2001  bool Reserve(typename GraphType::NodeIndex new_max_num_nodes,
2002  typename GraphType::ArcIndex new_max_num_arcs) {
2003  max_num_nodes_ = new_max_num_nodes;
2004  max_num_arcs_ = new_max_num_arcs;
2005  arcs_.reserve(new_max_num_arcs);
2006  return true;
2007  }
2008 
2009  typename GraphType::NodeIndex max_num_nodes_;
2010  typename GraphType::ArcIndex max_num_arcs_;
2011  typename GraphType::ArcIndex num_arcs_;
2012 
2013  std::vector<
2014  std::pair<typename GraphType::NodeIndex, typename GraphType::NodeIndex> >
2015  arcs_;
2016 
2017  const bool sort_arcs_;
2018 };
2019 
2020 // Trivial delegating specialization for dynamic graphs.
2021 //
2022 // Deletes itself upon returning the graph!
2023 template <typename GraphType>
2024 class GraphBuilderFromArcs<GraphType, true> {
2025  public:
2027  typename GraphType::ArcIndex max_num_arcs,
2028  bool sort_arcs)
2029  : graph_(new GraphType(max_num_nodes, max_num_arcs)),
2030  sort_arcs_(sort_arcs) {}
2031 
2032  bool Reserve(const typename GraphType::NodeIndex new_max_num_nodes,
2033  const typename GraphType::ArcIndex new_max_num_arcs) {
2034  return graph_->Reserve(new_max_num_nodes, new_max_num_arcs);
2035  }
2036 
2038  const typename GraphType::NodeIndex tail,
2039  const typename GraphType::NodeIndex head) {
2040  return graph_->AddArc(tail, head);
2041  }
2042 
2043  GraphType* Graph(PermutationCycleHandler<typename GraphType::ArcIndex>*
2044  client_cycle_handler) {
2045  if (sort_arcs_) {
2046  TailArrayManager<GraphType> tail_array_manager(graph_);
2048  ArcFunctorOrderingByTailAndHead<GraphType> arc_ordering(*graph_);
2049  graph_->GroupForwardArcsByFunctor(arc_ordering, client_cycle_handler);
2050  tail_array_manager.ReleaseTailArrayIfForwardGraph();
2051  }
2052  GraphType* result = graph_;
2053  delete this;
2054  return result;
2055  }
2056 
2057  private:
2058  GraphType* const graph_;
2059  const bool sort_arcs_;
2060 };
2061 
2062 } // namespace or_internal
2063 
2064 template <typename GraphType>
2067  GraphType, graph_traits<GraphType>::is_dynamic> {
2068  public:
2070  typename GraphType::ArcIndex num_arcs,
2071  bool sort_arcs)
2072  : or_internal::GraphBuilderFromArcs<GraphType,
2073  graph_traits<GraphType>::is_dynamic>(
2074  num_nodes, num_arcs, sort_arcs) {}
2075 };
2076 
2077 // Builds a directed line graph for 'graph' (see "directed line graph" in
2078 // http://en.wikipedia.org/wiki/Line_graph). Arcs of the original graph
2079 // become nodes and the new graph contains only nodes created from arcs in the
2080 // original graph (we use the notation (a->b) for these new nodes); the index
2081 // of the node (a->b) in the new graph is exactly the same as the index of the
2082 // arc a->b in the original graph.
2083 // An arc from node (a->b) to node (c->d) in the new graph is added if and only
2084 // if b == c in the original graph.
2085 // This method expects that 'line_graph' is an empty graph (it has no nodes
2086 // and no arcs).
2087 // Returns false on an error.
2088 template <typename GraphType>
2089 bool BuildLineGraph(const GraphType& graph, GraphType* const line_graph) {
2090  if (line_graph == nullptr) {
2091  LOG(DFATAL) << "line_graph must not be NULL";
2092  return false;
2093  }
2094  if (line_graph->num_nodes() != 0) {
2095  LOG(DFATAL) << "line_graph must be empty";
2096  return false;
2097  }
2098  typedef typename GraphType::ArcIterator ArcIterator;
2099  typedef typename GraphType::OutgoingArcIterator OutgoingArcIterator;
2100  // Sizing then filling.
2101  typename GraphType::ArcIndex num_arcs = 0;
2102  for (ArcIterator arc_iterator(graph); arc_iterator.Ok();
2103  arc_iterator.Next()) {
2104  const typename GraphType::ArcIndex arc = arc_iterator.Index();
2105  const typename GraphType::NodeIndex head = graph.Head(arc);
2106  for (OutgoingArcIterator iterator(graph, head); iterator.Ok();
2107  iterator.Next()) {
2108  ++num_arcs;
2109  }
2110  }
2111  line_graph->Reserve(graph.num_arcs(), num_arcs);
2112  for (ArcIterator arc_iterator(graph); arc_iterator.Ok();
2113  arc_iterator.Next()) {
2114  const typename GraphType::ArcIndex arc = arc_iterator.Index();
2115  const typename GraphType::NodeIndex head = graph.Head(arc);
2116  for (OutgoingArcIterator iterator(graph, head); iterator.Ok();
2117  iterator.Next()) {
2118  line_graph->AddArc(arc, iterator.Index());
2119  }
2120  }
2121  return true;
2122 }
2123 
2124 } // namespace operations_research
2125 #endif // OR_TOOLS_GRAPH_EBERT_GRAPH_H_
GraphType * Graph(PermutationCycleHandler< typename GraphType::ArcIndex > *client_cycle_handler)
Definition: ebert_graph.h:2043
CycleHandlerForAnnotatedArcs(PermutationCycleHandler< ArcIndexType > *annotation_handler, DerivedGraph *graph)
Definition: ebert_graph.h:1051
std::string NodeDebugString(const NodeIndexType node) const
Definition: ebert_graph.h:303
bool operator()(ArcIndexType a, ArcIndexType b) const
Definition: ebert_graph.h:526
ArcIndexType max_end_arc_index() const
Definition: ebert_graph.h:272
ArcIndexType FirstOutgoingOrOppositeIncomingArc(const NodeIndexType node) const
Definition: ebert_graph.h:1124
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
Definition: ebert_graph.h:587
NodeIndexType StartNode(NodeIndexType node) const
Definition: ebert_graph.h:440
ZVector< ArcIndexType > first_incident_arc_
Definition: ebert_graph.h:503
CycleHandlerForAnnotatedArcs(PermutationCycleHandler< ArcIndexType > *annotation_handler, NodeIndexType *data)
Definition: ebert_graph.h:576
OutgoingArcIterator(const DerivedGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: ebert_graph.h:378
AnnotatedGraphBuildManager(typename GraphType::NodeIndex num_nodes, typename GraphType::ArcIndex num_arcs, bool sort_arcs)
Definition: ebert_graph.h:2069
ZVector< ArcIndexType > next_adjacent_arc_
Definition: ebert_graph.h:1148
GraphType::ArcIndex AddArc(const typename GraphType::NodeIndex tail, const typename GraphType::NodeIndex head)
Definition: ebert_graph.h:2037
OutgoingOrOppositeIncomingArcIterator(const EbertGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: ebert_graph.h:1251
bool Unseen(ArcIndexType permutation_element) const override
Definition: ebert_graph.h:1092
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
Definition: ebert_graph.h:1067
void SetIndexFromTemp(ArcIndexType destination) const override
Definition: ebert_graph.h:593
void Initialize(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
Definition: ebert_graph.h:1113
ArcIndexType NextOutgoingArc(const NodeIndexType unused_node, const ArcIndexType arc) const
Definition: ebert_graph.h:1139
NodeIndexType max_num_nodes() const
Definition: ebert_graph.h:256
ArcIndexType DirectArc(const ArcIndexType arc) const
Definition: ebert_graph.h:1397
ForwardEbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
Definition: ebert_graph.h:1604
ArcIndexType StartArc(ArcIndexType arc) const
Definition: ebert_graph.h:446
void GroupForwardArcsByFunctor(const ArcIndexTypeStrictWeakOrderingFunctor &compare, PermutationCycleHandler< ArcIndexType > *annotation_handler)
Definition: ebert_graph.h:1023
void operator=(const OutgoingArcIterator &iterator)
Definition: ebert_graph.h:387
NodeIndexType DirectArcHead(const ArcIndexType arc) const
Definition: ebert_graph.h:1392
ForwardStaticGraph(const NodeIndexType num_nodes, const ArcIndexType num_arcs, const bool sort_arcs_by_head, std::vector< std::pair< NodeIndexType, NodeIndexType > > *client_input_arcs, operations_research::PermutationCycleHandler< ArcIndexType > *const client_cycle_handler)
Definition: ebert_graph.h:622
GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, typename GraphType::ArcIndex max_num_arcs, bool sort_arcs)
Definition: ebert_graph.h:2026
bool IsReverse(const ArcIndexType arc) const
Definition: ebert_graph.h:1424
ZVector< FlowQuantity > QuantityArray
Definition: ebert_graph.h:210
IncomingArcIterator(const EbertGraph &graph, NodeIndexType node)
Definition: ebert_graph.h:1301
bool CheckArcBounds(const ArcIndexType arc) const
Definition: ebert_graph.h:1364
bool IsDirect(const ArcIndexType arc) const
Definition: ebert_graph.h:1418
bool CheckTailIndexValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:784
bool BuildTailArrayFromAdjacencyListsIfForwardGraph() const
Definition: ebert_graph.h:1921
static constexpr bool has_reverse_arcs
Definition: ebert_graph.h:1850
bool Reserve(NodeIndexType new_max_num_nodes, ArcIndexType new_max_num_arcs)
Definition: ebert_graph.h:979
std::string DebugString() const
Definition: ebert_graph.h:1459
ArcIndexType max_num_arcs() const
Definition: ebert_graph.h:260
ZVector< NodeIndexType > head_
Definition: ebert_graph.h:499
std::string ArcDebugString(const ArcIndexType arc) const
Definition: ebert_graph.h:311
bool BuildLineGraph(const GraphType &graph, GraphType *const line_graph)
Definition: ebert_graph.h:2089
bool IsOutgoingOrOppositeIncoming(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:1430
ZVector< CostValue > CostArray
Definition: ebert_graph.h:211
NodeIndexType DirectArcTail(const ArcIndexType arc) const
Definition: ebert_graph.h:1385
ArcIndexType LookUpArc(const NodeIndexType tail, const NodeIndexType head) const
Definition: ebert_graph.h:286
ArcIndexType Opposite(const ArcIndexType arc) const
Definition: ebert_graph.h:1410
IncomingArcIterator(const EbertGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: ebert_graph.h:1310
bool IsOutgoing(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:1441
bool IsNodeValid(NodeIndexType node) const
Definition: ebert_graph.h:280
bool operator()(typename GraphType::ArcIndex a, typename GraphType::ArcIndex b) const
Definition: ebert_graph.h:1945
bool CheckArcValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:1372
static const ArcIndexType kMaxNumArcs
Definition: ebert_graph.h:236
EbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
Definition: ebert_graph.h:1229
bool CheckArcBounds(const ArcIndexType arc) const
Definition: ebert_graph.h:771
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:1639
static const NodeIndexType kMaxNumNodes
Definition: ebert_graph.h:231
ArcIndexType FirstOutgoingArc(const NodeIndexType node) const
Definition: ebert_graph.h:480
bool CheckArcValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:779
ZVector< ArcIndex > ArcIndexArray
Definition: ebert_graph.h:209
static const NodeIndexType kFirstNode
Definition: ebert_graph.h:223
void operator=(const OutgoingOrOppositeIncomingArcIterator &iterator)
Definition: ebert_graph.h:1260
static const NodeIndexType kNilNode
Definition: ebert_graph.h:217
NodeIndexType max_end_node_index() const
Definition: ebert_graph.h:265
ArcIndexType NextAdjacentArc(const ArcIndexType arc) const
Definition: ebert_graph.h:1132
void SetIndexFromTemp(ArcIndexType destination) const override
Definition: ebert_graph.h:1076
ZVector< NodeIndex > NodeIndexArray
Definition: ebert_graph.h:208
void operator=(const IncomingArcIterator &iterator)
Definition: ebert_graph.h:1320
NodeIndexType Tail(const ArcIndexType arc) const
Definition: ebert_graph.h:1377
void SetSeen(ArcIndexType *permutation_element) const override
Definition: ebert_graph.h:1088
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Definition: ebert_graph.h:1002
ArcIndexType NextOutgoingArc(const NodeIndexType node, ArcIndexType arc) const
Definition: ebert_graph.h:789
bool CheckArcValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:1621
GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, typename GraphType::ArcIndex max_num_arcs, bool sort_arcs)
Definition: ebert_graph.h:1966
EbertGraph< NodeIndex, ArcIndex > StarGraph
Definition: ebert_graph.h:205
NodeIndexType Tail(const ArcIndexType arc) const
Definition: ebert_graph.h:1632
ArcIndexType num_arcs() const
Definition: ebert_graph.h:242
static const ArcIndexType kNilArc
Definition: ebert_graph.h:220
ForwardStaticGraph< NodeIndex, ArcIndex > ForwardStarStaticGraph
Definition: ebert_graph.h:207
static constexpr bool is_dynamic
Definition: ebert_graph.h:1851
GraphType * Graph(PermutationCycleHandler< typename GraphType::ArcIndex > *client_cycle_handler)
Definition: ebert_graph.h:1992
OutgoingArcIterator(const DerivedGraph &graph, NodeIndexType node)
Definition: ebert_graph.h:369
PermutationIndexComparisonByArcHead(const ZVector< NodeIndexType > &head)
Definition: ebert_graph.h:522
ForwardEbertGraph< NodeIndex, ArcIndex > ForwardStarGraph
Definition: ebert_graph.h:206
NodeIndexType end_node_index() const
Definition: ebert_graph.h:248
OutgoingOrOppositeIncomingArcIterator(const EbertGraph &graph, NodeIndexType node)
Definition: ebert_graph.h:1240
bool CheckArcBounds(const ArcIndexType arc) const
Definition: ebert_graph.h:1613
NodeIndexType Tail(const ArcIndexType arc) const
Definition: ebert_graph.h:757
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:764
ArcIndexType ReverseArc(const ArcIndexType arc) const
Definition: ebert_graph.h:1403
NodeIndexType num_nodes() const
Definition: ebert_graph.h:238
bool Reserve(const typename GraphType::NodeIndex new_max_num_nodes, const typename GraphType::ArcIndex new_max_num_arcs)
Definition: ebert_graph.h:2032
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:1436
ArcIndexType end_arc_index() const
Definition: ebert_graph.h:253
static const ArcIndexType kFirstArc
Definition: ebert_graph.h:226
NodeIndexType Head(const ArcIndexType arc) const
Definition: ebert_graph.h:298
NodeIndexType NextNode(const NodeIndexType node) const
Definition: ebert_graph.h:459
bool CheckTailIndexValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:1626
ArcIndexType NextArc(const ArcIndexType arc) const
Definition: ebert_graph.h:473
GraphType::ArcIndex AddArc(typename GraphType::NodeIndex tail, typename GraphType::NodeIndex head)
Definition: ebert_graph.h:1973