Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
ebert_graph.h
Go to the documentation of this file.
1// Copyright 2010-2024 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/logging.h"
181#include "ortools/util/zvector.h"
182
183namespace operations_research {
184
185// Forward declarations.
186template <typename NodeIndexType, typename ArcIndexType>
187class EbertGraph;
188template <typename NodeIndexType, typename ArcIndexType>
189class ForwardEbertGraph;
190template <typename NodeIndexType, typename ArcIndexType>
191class ForwardStaticGraph;
192
193// Standard instantiation of ForwardEbertGraph (named 'ForwardStarGraph') of
194// EbertGraph (named 'StarGraph'); and relevant type shortcuts. Unless their use
195// cases prevent them from doing so, users are encouraged to use StarGraph or
196// ForwardStarGraph according to whether or not they require reverse arcs to be
197// represented explicitly. Along with either graph representation, the other
198// type shortcuts here will often come in handy.
199typedef int32_t NodeIndex;
200typedef int32_t ArcIndex;
201typedef int64_t FlowQuantity;
202typedef int64_t CostValue;
210
211template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
213 public:
214 // The index of the 'nil' node in the graph.
215 static const NodeIndexType kNilNode;
216
217 // The index of the 'nil' arc in the graph.
218 static const ArcIndexType kNilArc;
219
220 // The index of the first node in the graph.
221 static const NodeIndexType kFirstNode;
222
223 // The index of the first arc in the graph.
224 static const ArcIndexType kFirstArc;
225
226 // The maximum possible number of nodes in the graph. (The maximum
227 // index is kMaxNumNodes-1, since indices start at 0. Unfortunately
228 // we waste a value representing this and the max_num_nodes_ member.)
229 static const NodeIndexType kMaxNumNodes;
230
231 // The maximum possible number of arcs in the graph. (The maximum
232 // index is kMaxNumArcs-1, since indices start at 0. Unfortunately
233 // we waste a value representing this and the max_num_arcs_ member.)
234 static const ArcIndexType kMaxNumArcs;
235 // Returns the number of nodes in the graph.
236 NodeIndexType num_nodes() const { return num_nodes_; }
237
238 // Returns the number of original arcs in the graph
239 // (The ones with positive indices.)
240 ArcIndexType num_arcs() const { return num_arcs_; }
241
242 // Returns one more than the largest index of an extant node,
243 // meaning a node that is mentioned as the head or tail of some arc
244 // in the graph. To be used as a helper when clients need to
245 // dimension or iterate over arrays of node annotation information.
246 NodeIndexType end_node_index() const { return kFirstNode + num_nodes_; }
247
248 // Returns one more than the largest index of an extant direct
249 // arc. To be used as a helper when clients need to dimension or
250 // iterate over arrays of arc annotation information.
251 ArcIndexType end_arc_index() const { return kFirstArc + num_arcs_; }
252
253 // Returns the maximum possible number of nodes in the graph.
254 NodeIndexType max_num_nodes() const { return max_num_nodes_; }
255
256 // Returns the maximum possible number of original arcs in the graph.
257 // (The ones with positive indices.)
258 ArcIndexType max_num_arcs() const { return max_num_arcs_; }
259
260 // Returns one more than the largest valid index of a node. To be
261 // used as a helper when clients need to dimension or iterate over
262 // arrays of node annotation information.
263 NodeIndexType max_end_node_index() const {
264 return kFirstNode + max_num_nodes_;
265 }
266
267 // Returns one more than the largest valid index of a direct arc. To
268 // be used as a helper when clients need to dimension or iterate
269 // over arrays of arc annotation information.
270 ArcIndexType max_end_arc_index() const { return kFirstArc + max_num_arcs_; }
271
272 // Utility function to check that a node index is within the bounds AND
273 // different from kNilNode.
274 // Returns true if node is in the range [kFirstNode .. max_num_nodes_).
275 // It is exported so that users of the DerivedGraph class can use it.
276 // To be used in a DCHECK; also used internally to validate
277 // arguments passed to our methods from clients (e.g., AddArc()).
278 bool IsNodeValid(NodeIndexType node) const {
279 return node >= kFirstNode && node < max_num_nodes_;
280 }
281
282 // Returns the first arc going from tail to head, if it exists, or kNilArc
283 // if such an arc does not exist.
284 ArcIndexType LookUpArc(const NodeIndexType tail,
285 const NodeIndexType head) const {
286 for (ArcIndexType arc = FirstOutgoingArc(tail); arc != kNilArc;
287 arc = ThisAsDerived()->NextOutgoingArc(tail, arc)) {
288 if (Head(arc) == head) {
289 return arc;
290 }
291 }
292 return kNilArc;
293 }
294
295 // Returns the head or end-node of arc.
296 NodeIndexType Head(const ArcIndexType arc) const {
297 DCHECK(ThisAsDerived()->CheckArcValidity(arc));
298 return head_[arc];
299 }
300
301 std::string NodeDebugString(const NodeIndexType node) const {
302 if (node == kNilNode) {
303 return "NilNode";
304 } else {
305 return absl::StrCat(static_cast<int64_t>(node));
306 }
307 }
308
309 std::string ArcDebugString(const ArcIndexType arc) const {
310 if (arc == kNilArc) {
311 return "NilArc";
312 } else {
313 return absl::StrCat(static_cast<int64_t>(arc));
314 }
315 }
316
317#if !defined(SWIG)
318 // Iterator class for traversing all the nodes in the graph.
320 public:
321 explicit NodeIterator(const DerivedGraph& graph)
322 : graph_(graph), head_(graph_.StartNode(kFirstNode)) {}
323
324 // Returns true unless all the nodes have been traversed.
325 bool Ok() const { return head_ != kNilNode; }
326
327 // Advances the current node index.
328 void Next() { head_ = graph_.NextNode(head_); }
329
330 // Returns the index of the node currently pointed to by the iterator.
331 NodeIndexType Index() const { return head_; }
332
333 private:
334 // A reference to the current DerivedGraph considered.
335 const DerivedGraph& graph_;
336
337 // The index of the current node considered.
338 NodeIndexType head_;
339 };
340
341 // Iterator class for traversing the arcs in the graph.
343 public:
344 explicit ArcIterator(const DerivedGraph& graph)
345 : graph_(graph), arc_(graph_.StartArc(kFirstArc)) {}
346
347 // Returns true unless all the arcs have been traversed.
348 bool Ok() const { return arc_ != kNilArc; }
349
350 // Advances the current arc index.
351 void Next() { arc_ = graph_.NextArc(arc_); }
352
353 // Returns the index of the arc currently pointed to by the iterator.
354 ArcIndexType Index() const { return arc_; }
355
356 private:
357 // A reference to the current DerivedGraph considered.
358 const DerivedGraph& graph_;
359
360 // The index of the current arc considered.
361 ArcIndexType arc_;
362 };
363
364 // Iterator class for traversing the outgoing arcs associated to a given node.
366 public:
367 OutgoingArcIterator(const DerivedGraph& graph, NodeIndexType node)
368 : graph_(graph),
369 node_(graph_.StartNode(node)),
370 arc_(graph_.StartArc(graph_.FirstOutgoingArc(node))) {
371 DCHECK(CheckInvariant());
372 }
373
374 // This constructor takes an arc as extra argument and makes the iterator
375 // start at arc.
376 OutgoingArcIterator(const DerivedGraph& graph, NodeIndexType node,
377 ArcIndexType arc)
378 : graph_(graph),
379 node_(graph_.StartNode(node)),
380 arc_(graph_.StartArc(arc)) {
381 DCHECK(CheckInvariant());
382 }
383
384 // Can only assign from an iterator on the same graph.
385 void operator=(const OutgoingArcIterator& iterator) {
386 DCHECK(&iterator.graph_ == &graph_);
387 node_ = iterator.node_;
388 arc_ = iterator.arc_;
389 }
390
391 // Returns true unless all the outgoing arcs have been traversed.
392 bool Ok() const { return arc_ != kNilArc; }
393
394 // Advances the current outgoing arc index.
395 void Next() {
396 arc_ = graph_.NextOutgoingArc(node_, arc_);
397 DCHECK(CheckInvariant());
398 }
399
400 // Returns the index of the arc currently pointed to by the iterator.
401 ArcIndexType Index() const { return arc_; }
402
403 private:
404 // Returns true if the invariant for the iterator is verified.
405 // To be used in a DCHECK.
406 bool CheckInvariant() const {
407 if (arc_ == kNilArc) {
408 return true; // This occurs when the iterator has reached the end.
409 }
410 DCHECK(graph_.IsOutgoing(arc_, node_));
411 return true;
412 }
413
414 // A reference to the current DerivedGraph considered.
415 const DerivedGraph& graph_;
416
417 // The index of the node on which arcs are iterated.
418 NodeIndexType node_;
419
420 // The index of the current arc considered.
421 ArcIndexType arc_;
422 };
423#endif // SWIG
424
425 protected:
432
434
435 // Returns kNilNode if the graph has no nodes or node if it has at least one
436 // node. Useful for initializing iterators correctly in the case of empty
437 // graphs.
438 NodeIndexType StartNode(NodeIndexType node) const {
439 return num_nodes_ == 0 ? kNilNode : node;
440 }
441
442 // Returns kNilArc if the graph has no arcs arc if it has at least one arc.
443 // Useful for initializing iterators correctly in the case of empty graphs.
444 ArcIndexType StartArc(ArcIndexType arc) const {
445 return num_arcs_ == 0 ? kNilArc : arc;
446 }
447
448 // Returns the node following the argument in the graph.
449 // Returns kNilNode (= end) if the range of nodes has been exhausted.
450 // It is called by NodeIterator::Next() and as such does not expect to be
451 // passed an argument equal to kNilNode.
452 // This is why the return line is simplified from
453 // return (node == kNilNode || next_node >= num_nodes_)
454 // ? kNilNode : next_node;
455 // to
456 // return next_node < num_nodes_ ? next_node : kNilNode;
457 NodeIndexType NextNode(const NodeIndexType node) const {
458 DCHECK(IsNodeValid(node));
459 const NodeIndexType next_node = node + 1;
460 return next_node < num_nodes_ ? next_node : kNilNode;
461 }
462
463 // Returns the arc following the argument in the graph.
464 // Returns kNilArc (= end) if the range of arcs has been exhausted.
465 // It is called by ArcIterator::Next() and as such does not expect to be
466 // passed an argument equal to kNilArc.
467 // This is why the return line is simplified from
468 // return ( arc == kNilArc || next_arc >= num_arcs_) ? kNilArc : next_arc;
469 // to
470 // return next_arc < num_arcs_ ? next_arc : kNilArc;
471 ArcIndexType NextArc(const ArcIndexType arc) const {
472 DCHECK(ThisAsDerived()->CheckArcValidity(arc));
473 const ArcIndexType next_arc = arc + 1;
474 return next_arc < num_arcs_ ? next_arc : kNilArc;
475 }
476
477 // Returns the first outgoing arc for node.
478 ArcIndexType FirstOutgoingArc(const NodeIndexType node) const {
479 DCHECK(IsNodeValid(node));
480 return ThisAsDerived()->FindNextOutgoingArc(
481 ThisAsDerived()->FirstOutgoingOrOppositeIncomingArc(node));
482 }
483
484 // The maximum number of nodes that the graph can hold.
485 NodeIndexType max_num_nodes_;
486
487 // The maximum number of arcs that the graph can hold.
488 ArcIndexType max_num_arcs_;
489
490 // The maximum index of the node currently held by the graph.
491 NodeIndexType num_nodes_;
492
493 // The current number of arcs held by the graph.
494 ArcIndexType num_arcs_;
495
496 // Array of node indices. head_[i] contains the head node of arc i.
498
499 // Array of arc indices. first_incident_arc_[i] contains the first arc
500 // incident to node i.
502
503 private:
504 // Shorthand: returns a const DerivedGraph*-typed version of our
505 // "this" pointer.
506 inline const DerivedGraph* ThisAsDerived() const {
507 return static_cast<const DerivedGraph*>(this);
508 }
509
510 // Shorthand: returns a DerivedGraph*-typed version of our "this"
511 // pointer.
512 inline DerivedGraph* ThisAsDerived() {
513 return static_cast<DerivedGraph*>(this);
514 }
515};
516
517template <typename NodeIndexType, typename ArcIndexType>
519 public:
523
524 bool operator()(ArcIndexType a, ArcIndexType b) const {
525 return head_[a] < head_[b];
526 }
527
528 private:
529 const ZVector<NodeIndexType>& head_;
530};
531
532template <typename NodeIndexType, typename ArcIndexType>
534 : public StarGraphBase<NodeIndexType, ArcIndexType,
535 ForwardStaticGraph<NodeIndexType, ArcIndexType> > {
536 typedef StarGraphBase<NodeIndexType, ArcIndexType,
539 friend class StarGraphBase<NodeIndexType, ArcIndexType,
540 ForwardStaticGraph<NodeIndexType, ArcIndexType> >;
541
544
546 using Base::head_;
549 using Base::num_arcs_;
550 using Base::num_nodes_;
551
552 public:
553#if !defined(SWIG)
555 using Base::Head;
556 using Base::IsNodeValid;
557
558 using Base::kFirstArc;
559 using Base::kFirstNode;
560 using Base::kNilArc;
561#endif // SWIG
562
563 typedef NodeIndexType NodeIndex;
564 typedef ArcIndexType ArcIndex;
565
566// TODO(user): Configure SWIG to handle the
567// CycleHandlerForAnnotatedArcs class.
568#if !defined(SWIG)
570 : public ArrayIndexCycleHandler<NodeIndexType, ArcIndexType> {
572
573 public:
575 PermutationCycleHandler<ArcIndexType>* annotation_handler,
576 NodeIndexType* data)
577 : ArrayIndexCycleHandler<NodeIndexType, ArcIndexType>(&data[kFirstArc]),
578 annotation_handler_(annotation_handler) {}
579
580 // This type is neither copyable nor movable.
583 const CycleHandlerForAnnotatedArcs&) = delete;
584
585 void SetTempFromIndex(ArcIndexType source) override {
587 annotation_handler_->SetTempFromIndex(source);
588 }
589
590 void SetIndexFromIndex(ArcIndexType source,
591 ArcIndexType destination) const override {
592 Base::SetIndexFromIndex(source, destination);
593 annotation_handler_->SetIndexFromIndex(source, destination);
594 }
595
596 void SetIndexFromTemp(ArcIndexType destination) const override {
597 Base::SetIndexFromTemp(destination);
598 annotation_handler_->SetIndexFromTemp(destination);
599 }
600
601 private:
602 PermutationCycleHandler<ArcIndexType>* annotation_handler_;
603 };
604#endif // SWIG
605
606 // Constructor for use by GraphBuilderFromArcs instances and direct
607 // clients that want to materialize a graph in one step.
608 // Materializing all at once is the only choice available with a
609 // static graph.
610 //
611 // Args:
612 // sort_arcs_by_head: determines whether arcs incident to each tail
613 // node are sorted by head node.
614 // client_cycle_handler: if non-NULL, mediates the permutation of
615 // arbitrary annotation data belonging to the client according
616 // to the permutation applied to the arcs in forming the
617 // graph. Two permutations may be composed to form the final one
618 // that affects the arcs. First, the arcs are always permuted to
619 // group them by tail node because ForwardStaticGraph requires
620 // this. Second, if each node's outgoing arcs are sorted by head
621 // node (according to sort_arcs_by_head), that sorting implies
622 // an additional permutation on the arcs.
624 const NodeIndexType num_nodes, const ArcIndexType num_arcs,
625 const bool sort_arcs_by_head,
626 std::vector<std::pair<NodeIndexType, NodeIndexType> >* client_input_arcs,
627 // TODO(user): For some reason, SWIG breaks if the
628 // operations_research namespace is not explicit in the
629 // following argument declaration.
631 client_cycle_handler) {
635 // A more convenient name for a parameter required by style to be
636 // a pointer, because we modify its referent.
637 std::vector<std::pair<NodeIndexType, NodeIndexType> >& input_arcs =
638 *client_input_arcs;
639
640 // We coopt the first_incident_arc_ array as a node-indexed vector
641 // used for two purposes related to degree before setting up its
642 // final values. First, it counts the out-degree of each
643 // node. Second, it is reused to count the number of arcs outgoing
644 // from each node that have already been put in place from the
645 // given input_arcs. We reserve an extra entry as a sentinel at
646 // the end.
649 for (ArcIndexType arc = kFirstArc; arc < kFirstArc + num_arcs; ++arc) {
650 first_incident_arc_[kFirstNode + input_arcs[arc].first] += 1;
651 // Take this opportunity to see how many nodes are really
652 // mentioned in the arc list.
653 num_nodes_ = std::max(
654 num_nodes_, static_cast<NodeIndexType>(input_arcs[arc].first + 1));
655 num_nodes_ = std::max(
656 num_nodes_, static_cast<NodeIndexType>(input_arcs[arc].second + 1));
657 }
658 ArcIndexType next_arc = kFirstArc;
659 for (NodeIndexType node = 0; node < num_nodes; ++node) {
660 ArcIndexType degree = first_incident_arc_[kFirstNode + node];
661 first_incident_arc_[kFirstNode + node] = next_arc;
662 next_arc += degree;
663 }
664 DCHECK_EQ(num_arcs, next_arc);
666 std::unique_ptr<ArcIndexType[]> arc_permutation;
667 if (client_cycle_handler != nullptr) {
668 arc_permutation.reset(new ArcIndexType[end_arc_index()]);
669 for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
670 NodeIndexType tail = input_arcs[input_arc].first;
671 NodeIndexType head = input_arcs[input_arc].second;
672 ArcIndexType arc = first_incident_arc_[kFirstNode + tail];
673 // The head_ entry will get permuted into the right place
674 // later.
675 head_[kFirstArc + input_arc] = kFirstNode + head;
676 arc_permutation[kFirstArc + arc] = input_arc;
678 }
679 } else {
680 if (sizeof(input_arcs[0].first) >= sizeof(first_incident_arc_[0])) {
681 // We reuse the input_arcs[].first entries to hold our
682 // mapping to the head_ array. This allows us to spread out
683 // cache badness.
684 for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
685 NodeIndexType tail = input_arcs[input_arc].first;
686 ArcIndexType arc = first_incident_arc_[kFirstNode + tail];
688 input_arcs[input_arc].first = static_cast<NodeIndexType>(arc);
689 }
690 for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
691 ArcIndexType arc =
692 static_cast<ArcIndexType>(input_arcs[input_arc].first);
693 NodeIndexType head = input_arcs[input_arc].second;
695 }
696 } else {
697 // We cannot reuse the input_arcs[].first entries so we map to
698 // the head_ array in a single loop.
699 for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
700 NodeIndexType tail = input_arcs[input_arc].first;
701 NodeIndexType head = input_arcs[input_arc].second;
702 ArcIndexType arc = first_incident_arc_[kFirstNode + tail];
705 }
706 }
707 }
708 // Shift the entries in first_incident_arc_ to compensate for the
709 // counting each one has done through its incident arcs. Note that
710 // there is a special sentry element at the end of
711 // first_incident_arc_.
712 for (NodeIndexType node = kFirstNode + num_nodes; node > /* kFirstNode */ 0;
713 --node) {
715 }
717 if (sort_arcs_by_head) {
718 ArcIndexType begin = first_incident_arc_[kFirstNode];
719 if (client_cycle_handler != nullptr) {
720 for (NodeIndexType node = 0; node < num_nodes; ++node) {
721 ArcIndexType end = first_incident_arc_[node + 1];
722 std::sort(
723 &arc_permutation[begin], &arc_permutation[end],
725 head_));
726 begin = end;
727 }
728 } else {
729 for (NodeIndexType node = 0; node < num_nodes; ++node) {
730 ArcIndexType end = first_incident_arc_[node + 1];
731 // The second argument in the following has a strange index
732 // expression because ZVector claims that no index is valid
733 // unless it refers to an element in the vector. In particular
734 // an index one past the end is invalid.
735 ArcIndexType begin_index = (begin < num_arcs ? begin : begin - 1);
736 ArcIndexType begin_offset = (begin < num_arcs ? 0 : 1);
737 ArcIndexType end_index = (end > 0 ? end - 1 : end);
738 ArcIndexType end_offset = (end > 0 ? 1 : 0);
739 std::sort(&head_[begin_index] + begin_offset,
740 &head_[end_index] + end_offset);
741 begin = end;
742 }
743 }
744 }
745 if (client_cycle_handler != nullptr && num_arcs > 0) {
746 // Apply the computed permutation if we haven't already.
747 CycleHandlerForAnnotatedArcs handler_for_constructor(
748 client_cycle_handler, &head_[kFirstArc] - kFirstArc);
749 // We use a permutation cycle handler to place the head array
750 // indices and permute the client's arc annotation data along
751 // with them.
752 PermutationApplier<ArcIndexType> permutation(&handler_for_constructor);
753 permutation.Apply(&arc_permutation[0], kFirstArc, end_arc_index());
754 }
755 }
756
757 // Returns the tail or start-node of arc.
758 NodeIndexType Tail(const ArcIndexType arc) const {
759 DCHECK(CheckArcValidity(arc));
761 return (*tail_)[arc];
762 }
763
764 // Returns true if arc is incoming to node.
765 bool IsIncoming(ArcIndexType arc, NodeIndexType node) const {
766 return Head(arc) == node;
767 }
768
769 // Utility function to check that an arc index is within the bounds.
770 // It is exported so that users of the ForwardStaticGraph class can use it.
771 // To be used in a DCHECK.
772 bool CheckArcBounds(const ArcIndexType arc) const {
773 return ((arc == kNilArc) || (arc >= kFirstArc && arc < max_num_arcs_));
774 }
775
776 // Utility function to check that an arc index is within the bounds AND
777 // different from kNilArc.
778 // It is exported so that users of the ForwardStaticGraph class can use it.
779 // To be used in a DCHECK.
780 bool CheckArcValidity(const ArcIndexType arc) const {
781 return ((arc != kNilArc) && (arc >= kFirstArc && arc < max_num_arcs_));
782 }
783
784 // Returns true if arc is a valid index into the (*tail_) array.
785 bool CheckTailIndexValidity(const ArcIndexType arc) const {
786 return ((tail_ != nullptr) && (arc >= kFirstArc) &&
787 (arc <= tail_->max_index()));
788 }
789
790 ArcIndexType NextOutgoingArc(const NodeIndexType node,
791 ArcIndexType arc) const {
792 DCHECK(IsNodeValid(node));
793 DCHECK(CheckArcValidity(arc));
794 ++arc;
795 if (arc < first_incident_arc_[node + 1]) {
796 return arc;
797 } else {
798 return kNilArc;
799 }
800 }
801
802 // Returns a debug string containing all the information contained in the
803 // data structure in raw form.
804 std::string DebugString() const {
805 std::string result = "Arcs:(node) :\n";
806 for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) {
807 result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) +
808 ")\n";
809 }
810 result += "Node:First arc :\n";
811 for (NodeIndexType node = kFirstNode; node <= num_nodes_; ++node) {
812 result += " " + NodeDebugString(node) + ":" +
814 }
815 return result;
816 }
817
819 // If (*tail_) is already allocated, we have the invariant that
820 // its contents are canonical, so we do not need to do anything
821 // here in that case except return true.
822 if (tail_ == nullptr) {
823 if (!RepresentationClean()) {
824 // We have been asked to build the (*tail_) array, but we have
825 // no valid information from which to build it. The graph is
826 // in an unrecoverable, inconsistent state.
827 return false;
828 }
829 // Reallocate (*tail_) and rebuild its contents from the
830 // adjacency lists.
831 tail_.reset(new ZVector<NodeIndexType>);
832 tail_->Reserve(kFirstArc, max_num_arcs_ - 1);
833 typename Base::NodeIterator node_it(*this);
834 for (; node_it.Ok(); node_it.Next()) {
835 NodeIndexType node = node_it.Index();
836 typename Base::OutgoingArcIterator arc_it(*this, node);
837 for (; arc_it.Ok(); arc_it.Next()) {
838 (*tail_)[arc_it.Index()] = node;
839 }
840 }
841 }
842 DCHECK(TailArrayComplete());
843 return true;
844 }
845
846 void ReleaseTailArray() { tail_.reset(nullptr); }
847
848 // To be used in a DCHECK().
849 bool TailArrayComplete() const {
850 CHECK(tail_);
851 for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) {
853 CHECK(IsNodeValid((*tail_)[arc]));
854 }
855 return true;
856 }
857
858 private:
859 bool IsDirect() const { return true; }
860 bool RepresentationClean() const { return true; }
861 bool IsOutgoing(const NodeIndexType node,
862 const ArcIndexType unused_arc) const {
863 return true;
864 }
865
866 // Returns the first arc in node's incidence list.
867 ArcIndexType FirstOutgoingOrOppositeIncomingArc(NodeIndexType node) const {
868 DCHECK(RepresentationClean());
869 DCHECK(IsNodeValid(node));
870 ArcIndexType result = first_incident_arc_[node];
871 return ((result != first_incident_arc_[node + 1]) ? result : kNilArc);
872 }
873
874 // Utility method that finds the next outgoing arc.
875 ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const {
876 DCHECK(CheckArcBounds(arc));
877 return arc;
878 }
879
880 // Array of node indices, not always present. (*tail_)[i] contains
881 // the tail node of arc i. This array is not needed for normal graph
882 // traversal operations, but is used in optimizing the graph's
883 // layout so arcs are grouped by tail node, and can be used in one
884 // approach to serializing the graph.
885 //
886 // Invariants: At any time when we are not executing a method of
887 // this class, either tail_ == NULL or the tail_ array's contents
888 // are kept canonical. If tail_ != NULL, any method that modifies
889 // adjacency lists must also ensure (*tail_) is modified
890 // correspondingly. The converse does not hold: Modifications to
891 // (*tail_) are allowed without updating the adjacency lists. If
892 // such modifications take place, representation_clean_ must be set
893 // to false, of course, to indicate that the adjacency lists are no
894 // longer current.
895 std::unique_ptr<ZVector<NodeIndexType> > tail_;
896};
897
898// The index of the 'nil' node in the graph.
899template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
900const NodeIndexType
902
903// The index of the 'nil' arc in the graph.
904template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
905const ArcIndexType
907 std::numeric_limits<ArcIndexType>::min();
908
909// The index of the first node in the graph.
910template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
911const NodeIndexType
913
914// The index of the first arc in the graph.
915template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
916const ArcIndexType
918
919// The maximum possible node index in the graph.
920template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
921const NodeIndexType
923 std::numeric_limits<NodeIndexType>::max();
924
925// The maximum possible number of arcs in the graph.
926// (The maximum index is kMaxNumArcs-1, since indices start at 0.)
927template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
928const ArcIndexType
930 std::numeric_limits<ArcIndexType>::max();
931
932// A template for the base class that holds the functionality that exists in
933// common between the EbertGraph<> template and the ForwardEbertGraph<>
934// template.
935//
936// This template is for internal use only, and this is enforced by making all
937// constructors for this class template protected. Clients should use one of the
938// two derived-class templates. Most clients will not even use those directly,
939// but will use the StarGraph and ForwardStarGraph typenames declared above.
940//
941// The DerivedGraph template argument must be the type of the class (typically
942// itself built from a template) that:
943// 1. implements the full interface expected for either ForwardEbertGraph or
944// EbertGraph, and
945// 2. inherits from an instance of this template.
946// The base class needs access to some members of the derived class such as, for
947// example, NextOutgoingArc(), and it gets this access via the DerivedGraph
948// template argument.
949template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
951 : public StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph> {
953 friend class StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph>;
954
955 protected:
962
963 public:
964#if !SWIG
967
974#endif // SWIG
975
976 // Reserves memory needed for max_num_nodes nodes and max_num_arcs arcs.
977 // Returns false if the parameters passed are not OK.
978 // It can be used to enlarge the graph, but does not shrink memory
979 // if called with smaller values.
980 bool Reserve(NodeIndexType new_max_num_nodes, ArcIndexType new_max_num_arcs) {
981 if (new_max_num_nodes < 0 || new_max_num_nodes > kMaxNumNodes) {
982 return false;
983 }
984 if (new_max_num_arcs < 0 || new_max_num_arcs > kMaxNumArcs) {
985 return false;
986 }
987 first_incident_arc_.Reserve(kFirstNode, new_max_num_nodes - 1);
988 for (NodeIndexType node = max_num_nodes_;
989 node <= first_incident_arc_.max_index(); ++node) {
991 }
992 ThisAsDerived()->ReserveInternal(new_max_num_nodes, new_max_num_arcs);
993 max_num_nodes_ = new_max_num_nodes;
994 max_num_arcs_ = new_max_num_arcs;
995 return true;
996 }
997
998 // Adds an arc to the graph and returns its index.
999 // Returns kNilArc if the arc could not be added.
1000 // Note that for a given pair (tail, head) AddArc does not overwrite an
1001 // already-existing arc between tail and head: Another arc is created
1002 // instead. This makes it possible to handle multi-graphs.
1003 ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head) {
1005 !IsNodeValid(head)) {
1006 return kNilArc;
1007 }
1008 if (tail + 1 > num_nodes_) {
1009 num_nodes_ = tail + 1; // max does not work on int16_t.
1010 }
1011 if (head + 1 > num_nodes_) {
1012 num_nodes_ = head + 1;
1013 }
1014 ArcIndexType arc = num_arcs_;
1015 ++num_arcs_;
1016 ThisAsDerived()->RecordArc(arc, tail, head);
1017 return arc;
1018 }
1019
1020// TODO(user): Configure SWIG to handle the GroupForwardArcsByFunctor
1021// member template and the CycleHandlerForAnnotatedArcs class.
1022#if !SWIG
1023 template <typename ArcIndexTypeStrictWeakOrderingFunctor>
1025 const ArcIndexTypeStrictWeakOrderingFunctor& compare,
1026 PermutationCycleHandler<ArcIndexType>* annotation_handler) {
1027 std::unique_ptr<ArcIndexType[]> arc_permutation(
1028 new ArcIndexType[end_arc_index()]);
1029
1030 // Determine the permutation that groups arcs by their tail nodes.
1031 for (ArcIndexType i = 0; i < end_arc_index(); ++i) {
1032 // Start with the identity permutation.
1033 arc_permutation[i] = i;
1034 }
1035 std::sort(&arc_permutation[kFirstArc], &arc_permutation[end_arc_index()],
1036 compare);
1037
1038 // Now we actually permute the head_ array and the
1039 // scaled_arc_cost_ array according to the sorting permutation.
1040 CycleHandlerForAnnotatedArcs cycle_handler(annotation_handler,
1041 ThisAsDerived());
1042 PermutationApplier<ArcIndexType> permutation(&cycle_handler);
1043 permutation.Apply(&arc_permutation[0], kFirstArc, end_arc_index());
1044
1045 // Finally, rebuild the graph from its permuted head_ array.
1046 ThisAsDerived()->BuildRepresentation();
1047 }
1048
1050 : public PermutationCycleHandler<ArcIndexType> {
1051 public:
1053 PermutationCycleHandler<ArcIndexType>* annotation_handler,
1054 DerivedGraph* graph)
1055 : annotation_handler_(annotation_handler),
1056 graph_(graph),
1057 head_temp_(kNilNode),
1058 tail_temp_(kNilNode) {}
1059
1060 // This type is neither copyable nor movable.
1063 const CycleHandlerForAnnotatedArcs&) = delete;
1064
1065 void SetTempFromIndex(ArcIndexType source) override {
1066 if (annotation_handler_ != nullptr) {
1067 annotation_handler_->SetTempFromIndex(source);
1068 }
1069 head_temp_ = graph_->Head(source);
1070 tail_temp_ = graph_->Tail(source);
1071 }
1072
1073 void SetIndexFromIndex(ArcIndexType source,
1074 ArcIndexType destination) const override {
1075 if (annotation_handler_ != nullptr) {
1076 annotation_handler_->SetIndexFromIndex(source, destination);
1077 }
1078 graph_->SetHead(destination, graph_->Head(source));
1079 graph_->SetTail(destination, graph_->Tail(source));
1080 }
1081
1082 void SetIndexFromTemp(ArcIndexType destination) const override {
1083 if (annotation_handler_ != nullptr) {
1084 annotation_handler_->SetIndexFromTemp(destination);
1085 }
1086 graph_->SetHead(destination, head_temp_);
1087 graph_->SetTail(destination, tail_temp_);
1088 }
1089
1090 // Since we are free to destroy the permutation array we use the
1091 // kNilArc value to mark entries in the array that have been
1092 // processed already. There is no need to be able to recover the
1093 // original permutation array entries once they have been seen.
1094 void SetSeen(ArcIndexType* permutation_element) const override {
1095 *permutation_element = kNilArc;
1096 }
1097
1098 bool Unseen(ArcIndexType permutation_element) const override {
1099 return permutation_element != kNilArc;
1100 }
1101
1103
1104 private:
1105 PermutationCycleHandler<ArcIndexType>* annotation_handler_;
1106 DerivedGraph* graph_;
1107 NodeIndexType head_temp_;
1108 NodeIndexType tail_temp_;
1109 };
1110#endif // SWIG
1111
1112 protected:
1114
1116
1117 void Initialize(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) {
1119 LOG(DFATAL) << "Could not reserve memory for "
1120 << static_cast<int64_t>(max_num_nodes) << " nodes and "
1121 << static_cast<int64_t>(max_num_arcs) << " arcs.";
1122 }
1124 ThisAsDerived()->InitializeInternal(max_num_nodes, max_num_arcs);
1125 }
1126
1127 // Returns the first arc in node's incidence list.
1129 const NodeIndexType node) const {
1130 DCHECK(representation_clean_);
1131 DCHECK(IsNodeValid(node));
1132 return first_incident_arc_[node];
1133 }
1134
1135 // Returns the next arc following the passed argument in its adjacency list.
1136 ArcIndexType NextAdjacentArc(const ArcIndexType arc) const {
1137 DCHECK(representation_clean_);
1138 DCHECK(ThisAsDerived()->CheckArcValidity(arc));
1139 return next_adjacent_arc_[arc];
1140 }
1141
1142 // Returns the outgoing arc following the argument in the adjacency list.
1143 ArcIndexType NextOutgoingArc(const NodeIndexType unused_node,
1144 const ArcIndexType arc) const {
1145 DCHECK(ThisAsDerived()->CheckArcValidity(arc));
1146 DCHECK(ThisAsDerived()->IsDirect(arc));
1147 return ThisAsDerived()->FindNextOutgoingArc(NextAdjacentArc(arc));
1148 }
1149
1150 // Array of next indices.
1151 // next_adjacent_arc_[i] contains the next arc in the adjacency list of arc i.
1153
1154 // Flag to indicate that BuildRepresentation() needs to be called
1155 // before the adjacency lists are examined. Only for DCHECK in debug
1156 // builds.
1158
1159 private:
1160 // Shorthand: returns a const DerivedGraph*-typed version of our
1161 // "this" pointer.
1162 inline const DerivedGraph* ThisAsDerived() const {
1163 return static_cast<const DerivedGraph*>(this);
1164 }
1165
1166 // Shorthand: returns a DerivedGraph*-typed version of our "this"
1167 // pointer.
1168 inline DerivedGraph* ThisAsDerived() {
1169 return static_cast<DerivedGraph*>(this);
1170 }
1171
1172 void InitializeInternal(NodeIndexType max_num_nodes,
1173 ArcIndexType max_num_arcs) {
1175 }
1176
1177 bool RepresentationClean() const { return representation_clean_; }
1178
1179 // Using the SetHead() method implies that the BuildRepresentation()
1180 // method must be called to restore consistency before the graph is
1181 // used.
1182 void SetHead(const ArcIndexType arc, const NodeIndexType head) {
1183 representation_clean_ = false;
1184 head_.Set(arc, head);
1185 }
1186};
1187
1188// Most users should only use StarGraph, which is EbertGraph<int32_t, int32_t>,
1189// and other type shortcuts; see the bottom of this file.
1190template <typename NodeIndexType, typename ArcIndexType>
1192 : public EbertGraphBase<NodeIndexType, ArcIndexType,
1193 EbertGraph<NodeIndexType, ArcIndexType> > {
1194 typedef EbertGraphBase<NodeIndexType, ArcIndexType,
1197 friend class EbertGraphBase<NodeIndexType, ArcIndexType,
1198 EbertGraph<NodeIndexType, ArcIndexType> >;
1199 friend class StarGraphBase<NodeIndexType, ArcIndexType,
1200 EbertGraph<NodeIndexType, ArcIndexType> >;
1201
1204 using Base::Initialize;
1207
1209 using Base::head_;
1210 using Base::max_num_arcs_;
1213 using Base::num_arcs_;
1214 using Base::num_nodes_;
1216
1217 public:
1218#if !SWIG
1219 using Base::Head;
1220 using Base::IsNodeValid;
1221
1222 using Base::kFirstArc;
1223 using Base::kFirstNode;
1224 using Base::kNilArc;
1225 using Base::kNilNode;
1226#endif // SWIG
1227
1228 typedef NodeIndexType NodeIndex;
1229 typedef ArcIndexType ArcIndex;
1230
1232
1233 EbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) {
1235 }
1236
1238
1239#if !SWIG
1240 // Iterator class for traversing the arcs incident to a given node in the
1241 // graph.
1243 public:
1245 NodeIndexType node)
1246 : graph_(graph),
1247 node_(graph_.StartNode(node)),
1248 arc_(graph_.StartArc(
1249 graph_.FirstOutgoingOrOppositeIncomingArc(node))) {
1250 DCHECK(CheckInvariant());
1251 }
1252
1253 // This constructor takes an arc as extra argument and makes the iterator
1254 // start at arc.
1256 NodeIndexType node, ArcIndexType arc)
1257 : graph_(graph),
1258 node_(graph_.StartNode(node)),
1259 arc_(graph_.StartArc(arc)) {
1260 DCHECK(CheckInvariant());
1261 }
1262
1263 // Can only assign from an iterator on the same graph.
1265 DCHECK(&iterator.graph_ == &graph_);
1266 node_ = iterator.node_;
1267 arc_ = iterator.arc_;
1268 }
1269
1270 // Returns true unless all the adjancent arcs have been traversed.
1271 bool Ok() const { return arc_ != kNilArc; }
1272
1273 // Advances the current adjacent arc index.
1274 void Next() {
1275 arc_ = graph_.NextAdjacentArc(arc_);
1276 DCHECK(CheckInvariant());
1277 }
1278
1279 // Returns the index of the arc currently pointed to by the iterator.
1280 ArcIndexType Index() const { return arc_; }
1281
1282 private:
1283 // Returns true if the invariant for the iterator is verified.
1284 // To be used in a DCHECK.
1285 bool CheckInvariant() const {
1286 if (arc_ == kNilArc) {
1287 return true; // This occurs when the iterator has reached the end.
1288 }
1289 DCHECK(graph_.IsOutgoingOrOppositeIncoming(arc_, node_));
1290 return true;
1291 }
1292 // A reference to the current EbertGraph considered.
1293 const EbertGraph& graph_;
1294
1295 // The index of the node on which arcs are iterated.
1296 NodeIndexType node_;
1297
1298 // The index of the current arc considered.
1299 ArcIndexType arc_;
1300 };
1301
1302 // Iterator class for traversing the incoming arcs associated to a given node.
1304 public:
1305 IncomingArcIterator(const EbertGraph& graph, NodeIndexType node)
1306 : graph_(graph),
1307 node_(graph_.StartNode(node)),
1308 arc_(graph_.StartArc(graph_.FirstIncomingArc(node))) {
1309 DCHECK(CheckInvariant());
1310 }
1311
1312 // This constructor takes an arc as extra argument and makes the iterator
1313 // start at arc.
1314 IncomingArcIterator(const EbertGraph& graph, NodeIndexType node,
1315 ArcIndexType arc)
1316 : graph_(graph),
1317 node_(graph_.StartNode(node)),
1318 arc_(arc == kNilArc ? kNilArc
1319 : graph_.StartArc(graph_.Opposite(arc))) {
1320 DCHECK(CheckInvariant());
1321 }
1322
1323 // Can only assign from an iterator on the same graph.
1324 void operator=(const IncomingArcIterator& iterator) {
1325 DCHECK(&iterator.graph_ == &graph_);
1326 node_ = iterator.node_;
1327 arc_ = iterator.arc_;
1328 }
1329
1330 // Returns true unless all the incoming arcs have been traversed.
1331 bool Ok() const { return arc_ != kNilArc; }
1332
1333 // Advances the current incoming arc index.
1334 void Next() {
1335 arc_ = graph_.NextIncomingArc(arc_);
1336 DCHECK(CheckInvariant());
1337 }
1338
1339 // Returns the index of the arc currently pointed to by the iterator.
1340 ArcIndexType Index() const {
1341 return arc_ == kNilArc ? kNilArc : graph_.Opposite(arc_);
1342 }
1343
1344 private:
1345 // Returns true if the invariant for the iterator is verified.
1346 // To be used in a DCHECK.
1347 bool CheckInvariant() const {
1348 if (arc_ == kNilArc) {
1349 return true; // This occurs when the iterator has reached the end.
1350 }
1351 DCHECK(graph_.IsIncoming(Index(), node_));
1352 return true;
1353 }
1354 // A reference to the current EbertGraph considered.
1355 const EbertGraph& graph_;
1356
1357 // The index of the node on which arcs are iterated.
1358 NodeIndexType node_;
1359
1360 // The index of the current arc considered.
1361 ArcIndexType arc_;
1362 };
1363#endif // SWIG
1364
1365 // Utility function to check that an arc index is within the bounds.
1366 // It is exported so that users of the EbertGraph class can use it.
1367 // To be used in a DCHECK.
1368 bool CheckArcBounds(const ArcIndexType arc) const {
1369 return (arc == kNilArc) || (arc >= -max_num_arcs_ && arc < max_num_arcs_);
1370 }
1371
1372 // Utility function to check that an arc index is within the bounds AND
1373 // different from kNilArc.
1374 // It is exported so that users of the EbertGraph class can use it.
1375 // To be used in a DCHECK.
1376 bool CheckArcValidity(const ArcIndexType arc) const {
1377 return (arc != kNilArc) && (arc >= -max_num_arcs_ && arc < max_num_arcs_);
1378 }
1379
1380 // Returns the tail or start-node of arc.
1381 NodeIndexType Tail(const ArcIndexType arc) const {
1382 DCHECK(CheckArcValidity(arc));
1383 return head_[Opposite(arc)];
1384 }
1385
1386 // Returns the tail or start-node of arc if it is positive
1387 // (i.e. it is taken in the direction it was entered in the graph),
1388 // and the head or end-node otherwise. 'This' in Ebert's paper.
1389 NodeIndexType DirectArcTail(const ArcIndexType arc) const {
1390 return Tail(DirectArc(arc));
1391 }
1392
1393 // Returns the head or end-node of arc if it is positive
1394 // (i.e. it is taken in the direction it was entered in the graph),
1395 // and the tail or start-node otherwise. 'That' in Ebert's paper.
1396 NodeIndexType DirectArcHead(const ArcIndexType arc) const {
1397 return Head(DirectArc(arc));
1398 }
1399
1400 // Returns the arc in normal/direct direction.
1401 ArcIndexType DirectArc(const ArcIndexType arc) const {
1402 DCHECK(CheckArcValidity(arc));
1403 return std::max(arc, Opposite(arc));
1404 }
1405
1406 // Returns the arc in reverse direction.
1407 ArcIndexType ReverseArc(const ArcIndexType arc) const {
1408 DCHECK(CheckArcValidity(arc));
1409 return std::min(arc, Opposite(arc));
1410 }
1411
1412 // Returns the opposite arc, i.e. the direct arc is the arc is in reverse
1413 // direction, and the reverse arc if the arc is direct.
1414 ArcIndexType Opposite(const ArcIndexType arc) const {
1415 const ArcIndexType opposite = ~arc;
1416 DCHECK(CheckArcValidity(arc));
1417 DCHECK(CheckArcValidity(opposite));
1418 return opposite;
1419 }
1420
1421 // Returns true if the arc is direct.
1422 bool IsDirect(const ArcIndexType arc) const {
1423 DCHECK(CheckArcBounds(arc));
1424 return arc != kNilArc && arc >= 0;
1425 }
1426
1427 // Returns true if the arc is in the reverse direction.
1428 bool IsReverse(const ArcIndexType arc) const {
1429 DCHECK(CheckArcBounds(arc));
1430 return arc != kNilArc && arc < 0;
1431 }
1432
1433 // Returns true if arc is incident to node.
1435 NodeIndexType node) const {
1436 return Tail(arc) == node;
1437 }
1438
1439 // Returns true if arc is incoming to node.
1440 bool IsIncoming(ArcIndexType arc, NodeIndexType node) const {
1441 return IsDirect(arc) && Head(arc) == node;
1442 }
1443
1444 // Returns true if arc is outgoing from node.
1445 bool IsOutgoing(ArcIndexType arc, NodeIndexType node) const {
1446 return IsDirect(arc) && Tail(arc) == node;
1447 }
1448
1449 // Recreates the next_adjacent_arc_ and first_incident_arc_ variables from
1450 // the array head_ in O(n + m) time.
1451 // This is useful if head_ array has been sorted according to a given
1452 // criterion, for example.
1455 for (ArcIndexType arc = kFirstArc; arc < max_num_arcs_; ++arc) {
1456 Attach(arc);
1457 }
1458 representation_clean_ = true;
1459 }
1460
1461 // Returns a debug string containing all the information contained in the
1462 // data structure in raw form.
1463 std::string DebugString() const {
1464 DCHECK(representation_clean_);
1465 std::string result = "Arcs:(node, next arc) :\n";
1466 for (ArcIndexType arc = -num_arcs_; arc < num_arcs_; ++arc) {
1467 result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) +
1468 "," + ArcDebugString(next_adjacent_arc_[arc]) + ")\n";
1469 }
1470 result += "Node:First arc :\n";
1471 for (NodeIndexType node = kFirstNode; node < num_nodes_; ++node) {
1472 result += " " + NodeDebugString(node) + ":" +
1473 ArcDebugString(first_incident_arc_[node]) + "\n";
1474 }
1475 return result;
1476 }
1477
1478 private:
1479 // Handles reserving space in the next_adjacent_arc_ and head_
1480 // arrays, which are always present and are therefore in the base
1481 // class. Although they reside in the base class, those two arrays
1482 // are maintained differently by different derived classes,
1483 // depending on whether the derived class stores reverse arcs. Hence
1484 // the code to set those arrays up is in a method of the derived
1485 // class.
1486 void ReserveInternal(NodeIndexType new_max_num_nodes,
1487 ArcIndexType new_max_num_arcs) {
1488 head_.Reserve(-new_max_num_arcs, new_max_num_arcs - 1);
1489 next_adjacent_arc_.Reserve(-new_max_num_arcs, new_max_num_arcs - 1);
1490 for (ArcIndexType arc = -new_max_num_arcs; arc < -max_num_arcs_; ++arc) {
1493 }
1494 for (ArcIndexType arc = max_num_arcs_; arc < new_max_num_arcs; ++arc) {
1497 }
1498 }
1499
1500 // Returns the first incoming arc for node.
1501 ArcIndexType FirstIncomingArc(const NodeIndexType node) const {
1502 DCHECK_LE(kFirstNode, node);
1503 DCHECK_GE(max_num_nodes_, node);
1504 return FindNextIncomingArc(FirstOutgoingOrOppositeIncomingArc(node));
1505 }
1506
1507 // Returns the incoming arc following the argument in the adjacency list.
1508 ArcIndexType NextIncomingArc(const ArcIndexType arc) const {
1509 DCHECK(CheckArcValidity(arc));
1510 DCHECK(IsReverse(arc));
1511 return FindNextIncomingArc(NextAdjacentArc(arc));
1512 }
1513
1514 // Handles the part of AddArc() that is not in common with other
1515 // graph classes based on the EbertGraphBase template.
1516 void RecordArc(ArcIndexType arc, NodeIndexType tail, NodeIndexType head) {
1518 head_.Set(arc, head);
1519 Attach(arc);
1520 }
1521
1522 // Using the SetTail() method implies that the BuildRepresentation()
1523 // method must be called to restore consistency before the graph is
1524 // used.
1525 void SetTail(const ArcIndexType arc, const NodeIndexType tail) {
1526 representation_clean_ = false;
1528 }
1529
1530 // Utility method to attach a new arc.
1531 void Attach(ArcIndexType arc) {
1532 DCHECK(CheckArcValidity(arc));
1533 const NodeIndexType tail = head_[Opposite(arc)];
1534 DCHECK(IsNodeValid(tail));
1537 const NodeIndexType head = head_[arc];
1538 DCHECK(IsNodeValid(head));
1541 }
1542
1543 // Utility method that finds the next outgoing arc.
1544 ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const {
1545 DCHECK(CheckArcBounds(arc));
1546 while (IsReverse(arc)) {
1548 DCHECK(CheckArcBounds(arc));
1549 }
1550 return arc;
1551 }
1552
1553 // Utility method that finds the next incoming arc.
1554 ArcIndexType FindNextIncomingArc(ArcIndexType arc) const {
1555 DCHECK(CheckArcBounds(arc));
1556 while (IsDirect(arc)) {
1558 DCHECK(CheckArcBounds(arc));
1559 }
1560 return arc;
1561 }
1562};
1563
1564// A forward-star-only graph representation for greater efficiency in
1565// those algorithms that don't need reverse arcs.
1566template <typename NodeIndexType, typename ArcIndexType>
1568 : public EbertGraphBase<NodeIndexType, ArcIndexType,
1569 ForwardEbertGraph<NodeIndexType, ArcIndexType> > {
1570 typedef EbertGraphBase<NodeIndexType, ArcIndexType,
1573 friend class EbertGraphBase<NodeIndexType, ArcIndexType,
1574 ForwardEbertGraph<NodeIndexType, ArcIndexType> >;
1575 friend class StarGraphBase<NodeIndexType, ArcIndexType,
1576 ForwardEbertGraph<NodeIndexType, ArcIndexType> >;
1577
1579 using Base::Initialize;
1582
1584 using Base::head_;
1585 using Base::max_num_arcs_;
1588 using Base::num_arcs_;
1589 using Base::num_nodes_;
1591
1592 public:
1593#if !SWIG
1594 using Base::Head;
1595 using Base::IsNodeValid;
1596
1597 using Base::kFirstArc;
1598 using Base::kFirstNode;
1599 using Base::kNilArc;
1600 using Base::kNilNode;
1601#endif // SWIG
1602
1603 typedef NodeIndexType NodeIndex;
1604 typedef ArcIndexType ArcIndex;
1605
1607
1611
1613
1614 // Utility function to check that an arc index is within the bounds.
1615 // It is exported so that users of the ForwardEbertGraph class can use it.
1616 // To be used in a DCHECK.
1617 bool CheckArcBounds(const ArcIndexType arc) const {
1618 return (arc == kNilArc) || (arc >= kFirstArc && arc < max_num_arcs_);
1619 }
1620
1621 // Utility function to check that an arc index is within the bounds AND
1622 // different from kNilArc.
1623 // It is exported so that users of the ForwardEbertGraph class can use it.
1624 // To be used in a DCHECK.
1625 bool CheckArcValidity(const ArcIndexType arc) const {
1626 return (arc != kNilArc) && (arc >= kFirstArc && arc < max_num_arcs_);
1627 }
1628
1629 // Returns true if arc is a valid index into the (*tail_) array.
1630 bool CheckTailIndexValidity(const ArcIndexType arc) const {
1631 return (tail_ != nullptr) && (arc >= kFirstArc) &&
1632 (arc <= tail_->max_index());
1633 }
1634
1635 // Returns the tail or start-node of arc.
1636 NodeIndexType Tail(const ArcIndexType arc) const {
1637 DCHECK(CheckArcValidity(arc));
1638 DCHECK(CheckTailIndexValidity(arc));
1639 return (*tail_)[arc];
1640 }
1641
1642 // Returns true if arc is incoming to node.
1643 bool IsIncoming(ArcIndexType arc, NodeIndexType node) const {
1644 return IsDirect(arc) && Head(arc) == node;
1645 }
1646
1647 // Recreates the next_adjacent_arc_ and first_incident_arc_
1648 // variables from the arrays head_ and tail_ in O(n + m) time. This
1649 // is useful if the head_ and tail_ arrays have been sorted
1650 // according to a given criterion, for example.
1653 DCHECK(TailArrayComplete());
1654 for (ArcIndexType arc = kFirstArc; arc < max_num_arcs_; ++arc) {
1655 DCHECK(CheckTailIndexValidity(arc));
1656 Attach((*tail_)[arc], arc);
1657 }
1658 representation_clean_ = true;
1659 }
1660
1662 // If (*tail_) is already allocated, we have the invariant that
1663 // its contents are canonical, so we do not need to do anything
1664 // here in that case except return true.
1665 if (tail_ == nullptr) {
1666 if (!representation_clean_) {
1667 // We have been asked to build the (*tail_) array, but we have
1668 // no valid information from which to build it. The graph is
1669 // in an unrecoverable, inconsistent state.
1670 return false;
1671 }
1672 // Reallocate (*tail_) and rebuild its contents from the
1673 // adjacency lists.
1674 tail_.reset(new ZVector<NodeIndexType>);
1675 tail_->Reserve(kFirstArc, max_num_arcs_ - 1);
1676 typename Base::NodeIterator node_it(*this);
1677 for (; node_it.Ok(); node_it.Next()) {
1678 NodeIndexType node = node_it.Index();
1679 typename Base::OutgoingArcIterator arc_it(*this, node);
1680 for (; arc_it.Ok(); arc_it.Next()) {
1681 (*tail_)[arc_it.Index()] = node;
1682 }
1683 }
1684 }
1685 DCHECK(TailArrayComplete());
1686 return true;
1687 }
1688
1689 void ReleaseTailArray() { tail_.reset(nullptr); }
1690
1691 // To be used in a DCHECK().
1692 bool TailArrayComplete() const {
1693 CHECK(tail_);
1694 for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) {
1696 CHECK(IsNodeValid((*tail_)[arc]));
1697 }
1698 return true;
1699 }
1700
1701 // Returns a debug string containing all the information contained in the
1702 // data structure in raw form.
1703 std::string DebugString() const {
1704 DCHECK(representation_clean_);
1705 std::string result = "Arcs:(node, next arc) :\n";
1706 for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) {
1707 result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) +
1708 "," + ArcDebugString(next_adjacent_arc_[arc]) + ")\n";
1709 }
1710 result += "Node:First arc :\n";
1711 for (NodeIndexType node = kFirstNode; node < num_nodes_; ++node) {
1712 result += " " + NodeDebugString(node) + ":" +
1713 ArcDebugString(first_incident_arc_[node]) + "\n";
1714 }
1715 return result;
1716 }
1717
1718 private:
1719 // Reserves space for the (*tail_) array.
1720 //
1721 // This method is separate from ReserveInternal() because our
1722 // practice of making the (*tail_) array optional implies that the
1723 // tail_ pointer might not be constructed when the ReserveInternal()
1724 // method is called. Therefore we have this method also, and we
1725 // ensure that it is called only when tail_ is guaranteed to have
1726 // been initialized.
1727 void ReserveTailArray(ArcIndexType new_max_num_arcs) {
1728 if (tail_ != nullptr) {
1729 // The (*tail_) values are already canonical, so we're just
1730 // reserving additional space for new arcs that haven't been
1731 // added yet.
1732 if (tail_->Reserve(kFirstArc, new_max_num_arcs - 1)) {
1733 for (ArcIndexType arc = tail_->max_index() + 1; arc < new_max_num_arcs;
1734 ++arc) {
1735 tail_->Set(arc, kNilNode);
1736 }
1737 }
1738 }
1739 }
1740
1741 // Reserves space for the arrays indexed by arc indices, except
1742 // (*tail_) even if it is present. We cannot grow the (*tail_) array
1743 // in this method because this method is called from
1744 // Base::Reserve(), which in turn is called from the base template
1745 // class constructor. That base class constructor is called on *this
1746 // before tail_ is constructed. Hence when this method is called,
1747 // tail_ might contain garbage. This method can safely refer only to
1748 // fields of the base template class, not to fields of *this outside
1749 // the base template class.
1750 //
1751 // The strange situation in which this method of a derived class can
1752 // refer only to members of the base class arises because different
1753 // derived classes use the data members of the base class in
1754 // slightly different ways. The purpose of this derived class
1755 // method, then, is only to encode the derived-class-specific
1756 // conventions for how the derived class uses the data members of
1757 // the base class.
1758 //
1759 // To be specific, the forward-star graph representation, lacking
1760 // reverse arcs, allocates only the positive index range for the
1761 // head_ and next_adjacent_arc_ arrays, while the general
1762 // representation allocates space for both positive- and
1763 // negative-indexed arcs (i.e., both forward and reverse arcs).
1764 void ReserveInternal(NodeIndexType new_max_num_nodes,
1765 ArcIndexType new_max_num_arcs) {
1766 head_.Reserve(kFirstArc, new_max_num_arcs - 1);
1767 next_adjacent_arc_.Reserve(kFirstArc, new_max_num_arcs - 1);
1768 for (ArcIndexType arc = max_num_arcs_; arc < new_max_num_arcs; ++arc) {
1771 }
1772 ReserveTailArray(new_max_num_arcs);
1773 }
1774
1775 // Handles the part of AddArc() that is not in common wth other
1776 // graph classes based on the EbertGraphBase template.
1777 void RecordArc(ArcIndexType arc, NodeIndexType tail, NodeIndexType head) {
1778 head_.Set(arc, head);
1779 Attach(tail, arc);
1780 }
1781
1782 // Using the SetTail() method implies that the BuildRepresentation()
1783 // method must be called to restore consistency before the graph is
1784 // used.
1785 void SetTail(const ArcIndexType arc, const NodeIndexType tail) {
1786 DCHECK(CheckTailIndexValidity(arc));
1787 CHECK(tail_);
1788 representation_clean_ = false;
1789 tail_->Set(arc, tail);
1790 }
1791
1792 // Utility method to attach a new arc.
1793 void Attach(NodeIndexType tail, ArcIndexType arc) {
1794 DCHECK(CheckArcValidity(arc));
1795 DCHECK(IsNodeValid(tail));
1798 const NodeIndexType head = head_[arc];
1799 DCHECK(IsNodeValid(head));
1800 // Because Attach() is a public method, keeping (*tail_) canonical
1801 // requires us to record the new arc's tail here.
1802 if (tail_ != nullptr) {
1803 DCHECK(CheckTailIndexValidity(arc));
1804 tail_->Set(arc, tail);
1805 }
1806 }
1807
1808 // Utility method that finds the next outgoing arc.
1809 ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const {
1810 DCHECK(CheckArcBounds(arc));
1811 return arc;
1812 }
1813
1814 private:
1815 // Always returns true because for any ForwardEbertGraph, only
1816 // direct arcs are represented, so all valid arc indices refer to
1817 // arcs that are outgoing from their tail nodes.
1818 bool IsOutgoing(const ArcIndex unused_arc,
1819 const NodeIndex unused_node) const {
1820 return true;
1821 }
1822
1823 // Always returns true because for any ForwardEbertGraph, only
1824 // outgoing arcs are represented, so all valid arc indices refer to
1825 // direct arcs.
1826 bool IsDirect(const ArcIndex unused_arc) const { return true; }
1827
1828 // Array of node indices, not always present. (*tail_)[i] contains
1829 // the tail node of arc i. This array is not needed for normal graph
1830 // traversal operations, but is used in optimizing the graph's
1831 // layout so arcs are grouped by tail node, and can be used in one
1832 // approach to serializing the graph.
1833 //
1834 // Invariants: At any time when we are not executing a method of
1835 // this class, either tail_ == NULL or the tail_ array's contents
1836 // are kept canonical. If tail_ != NULL, any method that modifies
1837 // adjacency lists must also ensure (*tail_) is modified
1838 // correspondingly. The converse does not hold: Modifications to
1839 // (*tail_) are allowed without updating the adjacency lists. If
1840 // such modifications take place, representation_clean_ must be set
1841 // to false, of course, to indicate that the adjacency lists are no
1842 // longer current.
1843 std::unique_ptr<ZVector<NodeIndexType> > tail_;
1844};
1845
1846// Traits for EbertGraphBase types, for use in testing and clients
1847// that work with both forward-only and forward/reverse graphs.
1848//
1849// The default is to assume reverse arcs so if someone forgets to
1850// specialize the traits of a new forward-only graph type, they will
1851// get errors from tests rather than incomplete testing.
1852template <typename GraphType>
1854 static constexpr bool has_reverse_arcs = true;
1855 static constexpr bool is_dynamic = true;
1856};
1857
1858template <typename NodeIndexType, typename ArcIndexType>
1859struct graph_traits<ForwardEbertGraph<NodeIndexType, ArcIndexType> > {
1860 static constexpr bool has_reverse_arcs = false;
1861 static constexpr bool is_dynamic = true;
1862};
1863
1864template <typename NodeIndexType, typename ArcIndexType>
1865struct graph_traits<ForwardStaticGraph<NodeIndexType, ArcIndexType> > {
1866 static constexpr bool has_reverse_arcs = false;
1867 static constexpr bool is_dynamic = false;
1868};
1869
1870namespace or_internal {
1871
1872// The TailArrayBuilder class template is not expected to be used by
1873// clients. It is a helper for the TailArrayManager template.
1874//
1875// The TailArrayBuilder for graphs with reverse arcs does nothing.
1876template <typename GraphType, bool has_reverse_arcs>
1878 explicit TailArrayBuilder(GraphType* unused_graph) {}
1879
1880 bool BuildTailArray() const { return true; }
1881};
1882
1883// The TailArrayBuilder for graphs without reverse arcs calls the
1884// appropriate method on the graph from the TailArrayBuilder
1885// constructor.
1886template <typename GraphType>
1887struct TailArrayBuilder<GraphType, false> {
1888 explicit TailArrayBuilder(GraphType* graph) : graph_(graph) {}
1889
1890 bool BuildTailArray() const { return graph_->BuildTailArray(); }
1891
1892 GraphType* const graph_;
1893};
1894
1895// The TailArrayReleaser class template is not expected to be used by
1896// clients. It is a helper for the TailArrayManager template.
1897//
1898// The TailArrayReleaser for graphs with reverse arcs does nothing.
1899template <typename GraphType, bool has_reverse_arcs>
1901 explicit TailArrayReleaser(GraphType* unused_graph) {}
1902
1903 void ReleaseTailArray() const {}
1904};
1905
1906// The TailArrayReleaser for graphs without reverse arcs calls the
1907// appropriate method on the graph from the TailArrayReleaser
1908// constructor.
1909template <typename GraphType>
1910struct TailArrayReleaser<GraphType, false> {
1911 explicit TailArrayReleaser(GraphType* graph) : graph_(graph) {}
1912
1913 void ReleaseTailArray() const { graph_->ReleaseTailArray(); }
1914
1915 GraphType* const graph_;
1916};
1917
1918} // namespace or_internal
1919
1920template <typename GraphType>
1922 public:
1923 explicit TailArrayManager(GraphType* g) : graph_(g) {}
1924
1928 tail_array_builder(graph_);
1929 return tail_array_builder.BuildTailArray();
1930 }
1931
1935 tail_array_releaser(graph_);
1936 tail_array_releaser.ReleaseTailArray();
1937 }
1938
1939 private:
1940 GraphType* graph_;
1941};
1942
1943template <typename GraphType>
1945 public:
1946 explicit ArcFunctorOrderingByTailAndHead(const GraphType& graph)
1947 : graph_(graph) {}
1948
1949 bool operator()(typename GraphType::ArcIndex a,
1950 typename GraphType::ArcIndex b) const {
1951 return ((graph_.Tail(a) < graph_.Tail(b)) ||
1952 ((graph_.Tail(a) == graph_.Tail(b)) &&
1953 (graph_.Head(a) < graph_.Head(b))));
1954 }
1955
1956 private:
1957 const GraphType& graph_;
1958};
1959
1960namespace or_internal {
1961
1962// The GraphBuilderFromArcs class template is not expected to be used
1963// by clients. It is a helper for the AnnotatedGraphBuildManager
1964// template.
1965//
1966// Deletes itself upon returning the graph!
1967template <typename GraphType, bool is_dynamic>
1969 public:
1970 GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes,
1971 typename GraphType::ArcIndex max_num_arcs,
1972 bool sort_arcs)
1973 : num_arcs_(0), sort_arcs_(sort_arcs) {
1974 Reserve(max_num_nodes, max_num_arcs);
1975 }
1976
1977 typename GraphType::ArcIndex AddArc(typename GraphType::NodeIndex tail,
1978 typename GraphType::NodeIndex head) {
1979 DCHECK_LT(num_arcs_, max_num_arcs_);
1980 DCHECK_LT(tail, GraphType::kFirstNode + max_num_nodes_);
1981 DCHECK_LT(head, GraphType::kFirstNode + max_num_nodes_);
1982 if (num_arcs_ < max_num_arcs_ &&
1983 tail < GraphType::kFirstNode + max_num_nodes_ &&
1984 head < GraphType::kFirstNode + max_num_nodes_) {
1985 typename GraphType::ArcIndex result = GraphType::kFirstArc + num_arcs_;
1986 arcs_.push_back(std::make_pair(tail, head));
1987 num_arcs_ += 1;
1988 return result;
1989 } else {
1990 // Too many arcs or node index out of bounds!
1991 return GraphType::kNilArc;
1992 }
1993 }
1994
1995 // Builds the graph from the given arcs.
1997 client_cycle_handler) {
1998 GraphType* graph = new GraphType(max_num_nodes_, num_arcs_, sort_arcs_,
1999 &arcs_, client_cycle_handler);
2000 delete this;
2001 return graph;
2002 }
2003
2004 private:
2005 bool Reserve(typename GraphType::NodeIndex new_max_num_nodes,
2006 typename GraphType::ArcIndex new_max_num_arcs) {
2007 max_num_nodes_ = new_max_num_nodes;
2008 max_num_arcs_ = new_max_num_arcs;
2009 arcs_.reserve(new_max_num_arcs);
2010 return true;
2011 }
2012
2013 typename GraphType::NodeIndex max_num_nodes_;
2014 typename GraphType::ArcIndex max_num_arcs_;
2015 typename GraphType::ArcIndex num_arcs_;
2016
2017 std::vector<
2018 std::pair<typename GraphType::NodeIndex, typename GraphType::NodeIndex> >
2019 arcs_;
2020
2021 const bool sort_arcs_;
2022};
2023
2024// Trivial delegating specialization for dynamic graphs.
2025//
2026// Deletes itself upon returning the graph!
2027template <typename GraphType>
2028class GraphBuilderFromArcs<GraphType, true> {
2029 public:
2030 GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes,
2031 typename GraphType::ArcIndex max_num_arcs,
2032 bool sort_arcs)
2033 : graph_(new GraphType(max_num_nodes, max_num_arcs)),
2034 sort_arcs_(sort_arcs) {}
2035
2036 bool Reserve(const typename GraphType::NodeIndex new_max_num_nodes,
2037 const typename GraphType::ArcIndex new_max_num_arcs) {
2038 return graph_->Reserve(new_max_num_nodes, new_max_num_arcs);
2039 }
2040
2041 typename GraphType::ArcIndex AddArc(
2042 const typename GraphType::NodeIndex tail,
2043 const typename GraphType::NodeIndex head) {
2044 return graph_->AddArc(tail, head);
2045 }
2046
2048 client_cycle_handler) {
2049 if (sort_arcs_) {
2050 TailArrayManager<GraphType> tail_array_manager(graph_);
2052 ArcFunctorOrderingByTailAndHead<GraphType> arc_ordering(*graph_);
2053 graph_->GroupForwardArcsByFunctor(arc_ordering, client_cycle_handler);
2054 tail_array_manager.ReleaseTailArrayIfForwardGraph();
2055 }
2056 GraphType* result = graph_;
2057 delete this;
2058 return result;
2059 }
2060
2061 private:
2062 GraphType* const graph_;
2063 const bool sort_arcs_;
2064};
2065
2066} // namespace or_internal
2067
2068template <typename GraphType>
2071 GraphType, graph_traits<GraphType>::is_dynamic> {
2072 public:
2073 AnnotatedGraphBuildManager(typename GraphType::NodeIndex num_nodes,
2074 typename GraphType::ArcIndex num_arcs,
2075 bool sort_arcs)
2076 : or_internal::GraphBuilderFromArcs<GraphType,
2077 graph_traits<GraphType>::is_dynamic>(
2078 num_nodes, num_arcs, sort_arcs) {}
2079};
2080
2081// Builds a directed line graph for 'graph' (see "directed line graph" in
2082// http://en.wikipedia.org/wiki/Line_graph). Arcs of the original graph
2083// become nodes and the new graph contains only nodes created from arcs in the
2084// original graph (we use the notation (a->b) for these new nodes); the index
2085// of the node (a->b) in the new graph is exactly the same as the index of the
2086// arc a->b in the original graph.
2087// An arc from node (a->b) to node (c->d) in the new graph is added if and only
2088// if b == c in the original graph.
2089// This method expects that 'line_graph' is an empty graph (it has no nodes
2090// and no arcs).
2091// Returns false on an error.
2092template <typename GraphType>
2093bool BuildLineGraph(const GraphType& graph, GraphType* const line_graph) {
2094 if (line_graph == nullptr) {
2095 LOG(DFATAL) << "line_graph must not be NULL";
2096 return false;
2097 }
2098 if (line_graph->num_nodes() != 0) {
2099 LOG(DFATAL) << "line_graph must be empty";
2100 return false;
2101 }
2102 typedef typename GraphType::ArcIterator ArcIterator;
2103 typedef typename GraphType::OutgoingArcIterator OutgoingArcIterator;
2104 // Sizing then filling.
2105 typename GraphType::ArcIndex num_arcs = 0;
2106 for (ArcIterator arc_iterator(graph); arc_iterator.Ok();
2107 arc_iterator.Next()) {
2108 const typename GraphType::ArcIndex arc = arc_iterator.Index();
2109 const typename GraphType::NodeIndex head = graph.Head(arc);
2110 for (OutgoingArcIterator iterator(graph, head); iterator.Ok();
2111 iterator.Next()) {
2112 ++num_arcs;
2113 }
2114 }
2115 line_graph->Reserve(graph.num_arcs(), num_arcs);
2116 for (ArcIterator arc_iterator(graph); arc_iterator.Ok();
2117 arc_iterator.Next()) {
2118 const typename GraphType::ArcIndex arc = arc_iterator.Index();
2119 const typename GraphType::NodeIndex head = graph.Head(arc);
2120 for (OutgoingArcIterator iterator(graph, head); iterator.Ok();
2121 iterator.Next()) {
2122 line_graph->AddArc(arc, iterator.Index());
2123 }
2124 }
2125 return true;
2126}
2127
2128} // namespace operations_research
2129#endif // OR_TOOLS_GRAPH_EBERT_GRAPH_H_
AnnotatedGraphBuildManager(typename GraphType::NodeIndex num_nodes, typename GraphType::ArcIndex num_arcs, bool sort_arcs)
bool operator()(typename GraphType::ArcIndex a, typename GraphType::ArcIndex b) const
void SetIndexFromTemp(ArcIndexType destination) const override
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
CycleHandlerForAnnotatedArcs & operator=(const CycleHandlerForAnnotatedArcs &)=delete
CycleHandlerForAnnotatedArcs(PermutationCycleHandler< ArcIndexType > *annotation_handler, DerivedGraph *graph)
void SetSeen(ArcIndexType *permutation_element) const override
CycleHandlerForAnnotatedArcs(const CycleHandlerForAnnotatedArcs &)=delete
This type is neither copyable nor movable.
void SetIndexFromTemp(ArcIndexType destination) const override
Sets a data element from the temporary.
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
Moves a data element one step along its cycle.
bool Unseen(ArcIndexType permutation_element) const override
static const ArcIndexType kMaxNumArcs
ZVector< NodeIndexType > head_
Array of node indices. head_[i] contains the head node of arc i.
ZVector< ArcIndexType > next_adjacent_arc_
bool Reserve(NodeIndexType new_max_num_nodes, ArcIndexType new_max_num_arcs)
static const NodeIndexType kFirstNode
The index of the first node in the graph.
static const NodeIndexType kNilNode
The index of the 'nil' node in the graph.
static const ArcIndexType kFirstArc
The index of the first arc in the graph.
ArcIndexType NextOutgoingArc(const NodeIndexType unused_node, const ArcIndexType arc) const
Returns the outgoing arc following the argument in the adjacency list.
NodeIndexType max_num_nodes_
The maximum number of nodes that the graph can hold.
ArcIndexType end_arc_index() const
ArcIndexType FirstOutgoingOrOppositeIncomingArc(const NodeIndexType node) const
Returns the first arc in node's incidence list.
static const ArcIndexType kNilArc
The index of the 'nil' arc in the graph.
ArcIndexType num_arcs_
The current number of arcs held by the graph.
void GroupForwardArcsByFunctor(const ArcIndexTypeStrictWeakOrderingFunctor &compare, PermutationCycleHandler< ArcIndexType > *annotation_handler)
ArcIndexType NextAdjacentArc(const ArcIndexType arc) const
Returns the next arc following the passed argument in its adjacency list.
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ArcIndexType max_num_arcs_
The maximum number of arcs that the graph can hold.
bool IsNodeValid(NodeIndexType node) const
NodeIndexType num_nodes_
The maximum index of the node currently held by the graph.
static const NodeIndexType kMaxNumNodes
The maximum possible node index in the graph.
void Initialize(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
ZVector< ArcIndexType > first_incident_arc_
Iterator class for traversing the incoming arcs associated to a given node.
void operator=(const IncomingArcIterator &iterator)
Can only assign from an iterator on the same graph.
IncomingArcIterator(const EbertGraph &graph, NodeIndexType node, ArcIndexType arc)
bool Ok() const
Returns true unless all the incoming arcs have been traversed.
ArcIndexType Index() const
Returns the index of the arc currently pointed to by the iterator.
IncomingArcIterator(const EbertGraph &graph, NodeIndexType node)
void Next()
Advances the current incoming arc index.
OutgoingOrOppositeIncomingArcIterator(const EbertGraph &graph, NodeIndexType node)
ArcIndexType Index() const
Returns the index of the arc currently pointed to by the iterator.
bool Ok() const
Returns true unless all the adjancent arcs have been traversed.
OutgoingOrOppositeIncomingArcIterator(const EbertGraph &graph, NodeIndexType node, ArcIndexType arc)
void operator=(const OutgoingOrOppositeIncomingArcIterator &iterator)
Can only assign from an iterator on the same graph.
ArcIndexType Opposite(const ArcIndexType arc) const
NodeIndexType DirectArcHead(const ArcIndexType arc) const
bool IsOutgoingOrOppositeIncoming(ArcIndexType arc, NodeIndexType node) const
Returns true if arc is incident to node.
EbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
bool IsReverse(const ArcIndexType arc) const
Returns true if the arc is in the reverse direction.
bool CheckArcBounds(const ArcIndexType arc) const
NodeIndexType Tail(const ArcIndexType arc) const
Returns the tail or start-node of arc.
bool CheckArcValidity(const ArcIndexType arc) const
ArcIndexType DirectArc(const ArcIndexType arc) const
Returns the arc in normal/direct direction.
NodeIndexType DirectArcTail(const ArcIndexType arc) const
bool IsDirect(const ArcIndexType arc) const
Returns true if the arc is direct.
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Returns true if arc is incoming to node.
ArcIndexType ReverseArc(const ArcIndexType arc) const
Returns the arc in reverse direction.
bool IsOutgoing(ArcIndexType arc, NodeIndexType node) const
Returns true if arc is outgoing from node.
std::string DebugString() const
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Returns true if arc is incoming to node.
bool CheckArcValidity(const ArcIndexType arc) const
ForwardEbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
NodeIndexType Tail(const ArcIndexType arc) const
Returns the tail or start-node of arc.
bool CheckTailIndexValidity(const ArcIndexType arc) const
Returns true if arc is a valid index into the (*tail_) array.
bool TailArrayComplete() const
To be used in a DCHECK().
bool CheckArcBounds(const ArcIndexType arc) const
CycleHandlerForAnnotatedArcs(PermutationCycleHandler< ArcIndexType > *annotation_handler, NodeIndexType *data)
CycleHandlerForAnnotatedArcs & operator=(const CycleHandlerForAnnotatedArcs &)=delete
CycleHandlerForAnnotatedArcs(const CycleHandlerForAnnotatedArcs &)=delete
This type is neither copyable nor movable.
void SetIndexFromTemp(ArcIndexType destination) const override
Sets a data element from the temporary.
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
Moves a data element one step along its cycle.
bool CheckArcValidity(const ArcIndexType arc) const
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)
bool CheckArcBounds(const ArcIndexType arc) const
bool CheckTailIndexValidity(const ArcIndexType arc) const
Returns true if arc is a valid index into the (*tail_) array.
bool TailArrayComplete() const
To be used in a DCHECK().
ArcIndexType NextOutgoingArc(const NodeIndexType node, ArcIndexType arc) const
NodeIndexType Tail(const ArcIndexType arc) const
Returns the tail or start-node of arc.
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Returns true if arc is incoming to node.
void Apply(IndexType permutation[], int permutation_start, int permutation_end)
virtual void SetIndexFromTemp(IndexType destination) const =0
Sets a data element from the temporary.
virtual void SetTempFromIndex(IndexType source)=0
virtual void SetIndexFromIndex(IndexType source, IndexType destination) const =0
Moves a data element one step along its cycle.
bool operator()(ArcIndexType a, ArcIndexType b) const
PermutationIndexComparisonByArcHead(const ZVector< NodeIndexType > &head)
Iterator class for traversing the arcs in the graph.
void Next()
Advances the current arc index.
ArcIndexType Index() const
Returns the index of the arc currently pointed to by the iterator.
bool Ok() const
Returns true unless all the arcs have been traversed.
Iterator class for traversing all the nodes in the graph.
bool Ok() const
Returns true unless all the nodes have been traversed.
NodeIndexType Index() const
Returns the index of the node currently pointed to by the iterator.
void Next()
Advances the current node index.
Iterator class for traversing the outgoing arcs associated to a given node.
OutgoingArcIterator(const DerivedGraph &graph, NodeIndexType node)
void operator=(const OutgoingArcIterator &iterator)
Can only assign from an iterator on the same graph.
void Next()
Advances the current outgoing arc index.
OutgoingArcIterator(const DerivedGraph &graph, NodeIndexType node, ArcIndexType arc)
ArcIndexType Index() const
Returns the index of the arc currently pointed to by the iterator.
bool Ok() const
Returns true unless all the outgoing arcs have been traversed.
NodeIndexType end_node_index() const
static const ArcIndexType kMaxNumArcs
ZVector< NodeIndexType > head_
Array of node indices. head_[i] contains the head node of arc i.
static const NodeIndexType kFirstNode
The index of the first node in the graph.
static const NodeIndexType kNilNode
The index of the 'nil' node in the graph.
ArcIndexType NextArc(const ArcIndexType arc) const
std::string ArcDebugString(const ArcIndexType arc) const
static const ArcIndexType kFirstArc
The index of the first arc in the graph.
NodeIndexType max_num_nodes() const
Returns the maximum possible number of nodes in the graph.
NodeIndexType max_num_nodes_
The maximum number of nodes that the graph can hold.
std::string NodeDebugString(const NodeIndexType node) const
ArcIndexType end_arc_index() const
NodeIndexType max_end_node_index() const
static const ArcIndexType kNilArc
The index of the 'nil' arc in the graph.
ArcIndexType num_arcs_
The current number of arcs held by the graph.
NodeIndexType StartNode(NodeIndexType node) const
ArcIndexType max_end_arc_index() const
NodeIndexType NextNode(const NodeIndexType node) const
ArcIndexType max_num_arcs() const
ArcIndexType max_num_arcs_
The maximum number of arcs that the graph can hold.
ArcIndexType StartArc(ArcIndexType arc) const
NodeIndexType num_nodes() const
Returns the number of nodes in the graph.
NodeIndexType Head(const ArcIndexType arc) const
Returns the head or end-node of arc.
ArcIndexType LookUpArc(const NodeIndexType tail, const NodeIndexType head) const
bool IsNodeValid(NodeIndexType node) const
NodeIndexType num_nodes_
The maximum index of the node currently held by the graph.
ArcIndexType FirstOutgoingArc(const NodeIndexType node) const
Returns the first outgoing arc for node.
static const NodeIndexType kMaxNumNodes
The maximum possible node index in the graph.
ZVector< ArcIndexType > first_incident_arc_
bool BuildTailArrayFromAdjacencyListsIfForwardGraph() const
bool Reserve(int64_t new_min_index, int64_t new_max_index)
Definition zvector.h:96
void Set(int64_t index, T value)
Sets to value the content of the array at index.
Definition zvector.h:86
int64_t max_index() const
Definition zvector.h:58
void SetAll(T value)
Sets all the elements in the array to value.
Definition zvector.h:131
GraphType * Graph(PermutationCycleHandler< typename GraphType::ArcIndex > *client_cycle_handler)
bool Reserve(const typename GraphType::NodeIndex new_max_num_nodes, const typename GraphType::ArcIndex new_max_num_arcs)
GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, typename GraphType::ArcIndex max_num_arcs, bool sort_arcs)
GraphType::ArcIndex AddArc(const typename GraphType::NodeIndex tail, const typename GraphType::NodeIndex head)
GraphType * Graph(PermutationCycleHandler< typename GraphType::ArcIndex > *client_cycle_handler)
Builds the graph from the given arcs.
GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, typename GraphType::ArcIndex max_num_arcs, bool sort_arcs)
GraphType::ArcIndex AddArc(typename GraphType::NodeIndex tail, typename GraphType::NodeIndex head)
int64_t b
Definition table.cc:45
int64_t a
Definition table.cc:44
GraphType graph
int arc
In SWIG mode, we don't want anything besides these top-level includes.
ZVector< NodeIndex > NodeIndexArray
ForwardEbertGraph< NodeIndex, ArcIndex > ForwardStarGraph
ZVector< FlowQuantity > QuantityArray
ZVector< ArcIndex > ArcIndexArray
ForwardStaticGraph< NodeIndex, ArcIndex > ForwardStarStaticGraph
bool BuildLineGraph(const GraphType &graph, GraphType *const line_graph)
EbertGraph< NodeIndex, ArcIndex > StarGraph
ZVector< CostValue > CostArray
int head
int tail
std::optional< int64_t > end
static constexpr bool has_reverse_arcs
static constexpr bool is_dynamic