OR-Tools  9.1
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"
180#include "ortools/base/logging.h"
181#include "ortools/base/macros.h"
183#include "ortools/util/zvector.h"
184
185namespace operations_research {
186
187// Forward declarations.
188template <typename NodeIndexType, typename ArcIndexType>
189class EbertGraph;
190template <typename NodeIndexType, typename ArcIndexType>
191class ForwardEbertGraph;
192template <typename NodeIndexType, typename ArcIndexType>
193class ForwardStaticGraph;
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.
201typedef int32_t NodeIndex;
202typedef int32_t ArcIndex;
203typedef int64_t FlowQuantity;
204typedef int64_t CostValue;
212
213template <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.
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.
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.
500
501 // Array of arc indices. first_incident_arc_[i] contains the first arc
502 // incident to node i.
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
519template <typename NodeIndexType, typename ArcIndexType>
521 public:
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
534template <typename NodeIndexType, typename ArcIndexType>
536 : public StarGraphBase<NodeIndexType, ArcIndexType,
537 ForwardStaticGraph<NodeIndexType, ArcIndexType> > {
538 typedef StarGraphBase<NodeIndexType, ArcIndexType,
541 friend class StarGraphBase<NodeIndexType, ArcIndexType,
542 ForwardStaticGraph<NodeIndexType, ArcIndexType> >;
543
546
548 using Base::head_;
551 using Base::num_arcs_;
552 using Base::num_nodes_;
553
554 public:
555#if !defined(SWIG)
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> {
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 {
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.
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.
653 num_nodes_, static_cast<NodeIndexType>(input_arcs[arc].first + 1));
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;
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];
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];
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) {
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 {
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));
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) + ":" +
813 }
814 return result;
815 }
816
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 }
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) {
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 {
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.
898template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
899const NodeIndexType
901
902// The index of the 'nil' arc in the graph.
903template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
904const ArcIndexType
907
908// The index of the first node in the graph.
909template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
910const NodeIndexType
912
913// The index of the first arc in the graph.
914template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
915const ArcIndexType
917
918// The maximum possible node index in the graph.
919template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
920const NodeIndexType
923
924// The maximum possible number of arcs in the graph.
925// (The maximum index is kMaxNumArcs-1, since indices start at 0.)
926template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
927const ArcIndexType
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.
948template <typename NodeIndexType, typename ArcIndexType, typename DerivedGraph>
950 : public StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph> {
952 friend class StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph>;
953
954 protected:
961
962 public:
963#if !SWIG
966
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) {
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 }
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 {
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 {
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.
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) {
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.
1186template <typename NodeIndexType, typename ArcIndexType>
1188 : public EbertGraphBase<NodeIndexType, ArcIndexType,
1189 EbertGraph<NodeIndexType, ArcIndexType> > {
1190 typedef EbertGraphBase<NodeIndexType, ArcIndexType,
1193 friend class EbertGraphBase<NodeIndexType, ArcIndexType,
1194 EbertGraph<NodeIndexType, ArcIndexType> >;
1195 friend class StarGraphBase<NodeIndexType, ArcIndexType,
1196 EbertGraph<NodeIndexType, ArcIndexType> >;
1197
1200 using Base::Initialize;
1203
1205 using Base::head_;
1206 using Base::max_num_arcs_;
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 {
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 {
1399 return std::max(arc, Opposite(arc));
1400 }
1401
1402 // Returns the arc in reverse direction.
1403 ArcIndexType ReverseArc(const ArcIndexType arc) const {
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;
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.
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 {
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);
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 {
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) {
1529 const NodeIndexType tail = head_[Opposite(arc)];
1532 first_incident_arc_.Set(tail, arc);
1533 const NodeIndexType head = head_[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.
1562template <typename NodeIndexType, typename ArcIndexType>
1564 : public EbertGraphBase<NodeIndexType, ArcIndexType,
1565 ForwardEbertGraph<NodeIndexType, ArcIndexType> > {
1566 typedef EbertGraphBase<NodeIndexType, ArcIndexType,
1569 friend class EbertGraphBase<NodeIndexType, ArcIndexType,
1570 ForwardEbertGraph<NodeIndexType, ArcIndexType> >;
1571 friend class StarGraphBase<NodeIndexType, ArcIndexType,
1572 ForwardEbertGraph<NodeIndexType, ArcIndexType> >;
1573
1575 using Base::Initialize;
1578
1580 using Base::head_;
1581 using Base::max_num_arcs_;
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 {
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.
1650 for (ArcIndexType arc = kFirstArc; arc < max_num_arcs_; ++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 }
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) {
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 {
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) {
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) {
1793 first_incident_arc_.Set(tail, arc);
1794 const NodeIndexType head = head_[arc];
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) {
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.
1848template <typename GraphType>
1850 static constexpr bool has_reverse_arcs = true;
1851 static constexpr bool is_dynamic = true;
1852};
1853
1854template <typename NodeIndexType, typename ArcIndexType>
1855struct graph_traits<ForwardEbertGraph<NodeIndexType, ArcIndexType> > {
1856 static constexpr bool has_reverse_arcs = false;
1857 static constexpr bool is_dynamic = true;
1858};
1859
1860template <typename NodeIndexType, typename ArcIndexType>
1861struct graph_traits<ForwardStaticGraph<NodeIndexType, ArcIndexType> > {
1862 static constexpr bool has_reverse_arcs = false;
1863 static constexpr bool is_dynamic = false;
1864};
1865
1866namespace 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.
1872template <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.
1882template <typename GraphType>
1883struct 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.
1895template <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.
1905template <typename GraphType>
1906struct 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
1916template <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
1939template <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
1956namespace 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!
1963template <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.
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!
2023template <typename GraphType>
2024class 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
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
2064template <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.
2088template <typename GraphType>
2089bool 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_
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
#define CHECK(condition)
Definition: base/logging.h:491
#define DCHECK_LE(val1, val2)
Definition: base/logging.h:888
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:890
#define DCHECK_LT(val1, val2)
Definition: base/logging.h:889
#define LOG(severity)
Definition: base/logging.h:416
#define DCHECK(condition)
Definition: base/logging.h:885
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:886
AnnotatedGraphBuildManager(typename GraphType::NodeIndex num_nodes, typename GraphType::ArcIndex num_arcs, bool sort_arcs)
Definition: ebert_graph.h:2069
bool operator()(typename GraphType::ArcIndex a, typename GraphType::ArcIndex b) const
Definition: ebert_graph.h:1945
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
void operator=(const IncomingArcIterator &iterator)
Definition: ebert_graph.h:1320
IncomingArcIterator(const EbertGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: ebert_graph.h:1310
IncomingArcIterator(const EbertGraph &graph, NodeIndexType node)
Definition: ebert_graph.h:1301
OutgoingOrOppositeIncomingArcIterator(const EbertGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: ebert_graph.h:1251
OutgoingOrOppositeIncomingArcIterator(const EbertGraph &graph, NodeIndexType node)
Definition: ebert_graph.h:1240
void operator=(const OutgoingOrOppositeIncomingArcIterator &iterator)
Definition: ebert_graph.h:1260
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
Definition: ebert_graph.h:1067
bool Unseen(ArcIndexType permutation_element) const override
Definition: ebert_graph.h:1092
CycleHandlerForAnnotatedArcs(PermutationCycleHandler< ArcIndexType > *annotation_handler, DerivedGraph *graph)
Definition: ebert_graph.h:1051
void SetIndexFromTemp(ArcIndexType destination) const override
Definition: ebert_graph.h:1076
void SetSeen(ArcIndexType *permutation_element) const override
Definition: ebert_graph.h:1088
static const NodeIndexType kNilNode
Definition: ebert_graph.h:217
ZVector< ArcIndexType > next_adjacent_arc_
Definition: ebert_graph.h:1148
bool IsNodeValid(NodeIndexType node) const
Definition: ebert_graph.h:280
static const ArcIndexType kFirstArc
Definition: ebert_graph.h:226
ArcIndexType NextOutgoingArc(const NodeIndexType unused_node, const ArcIndexType arc) const
Definition: ebert_graph.h:1139
ZVector< ArcIndexType > first_incident_arc_
Definition: ebert_graph.h:503
static const ArcIndexType kMaxNumArcs
Definition: ebert_graph.h:236
bool Reserve(NodeIndexType new_max_num_nodes, ArcIndexType new_max_num_arcs)
Definition: ebert_graph.h:979
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Definition: ebert_graph.h:1002
ZVector< NodeIndexType > head_
Definition: ebert_graph.h:499
ArcIndexType end_arc_index() const
Definition: ebert_graph.h:253
void Initialize(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
Definition: ebert_graph.h:1113
ArcIndexType FirstOutgoingOrOppositeIncomingArc(const NodeIndexType node) const
Definition: ebert_graph.h:1124
void GroupForwardArcsByFunctor(const ArcIndexTypeStrictWeakOrderingFunctor &compare, PermutationCycleHandler< ArcIndexType > *annotation_handler)
Definition: ebert_graph.h:1023
static const ArcIndexType kNilArc
Definition: ebert_graph.h:220
static const NodeIndexType kMaxNumNodes
Definition: ebert_graph.h:231
static const NodeIndexType kFirstNode
Definition: ebert_graph.h:223
ArcIndexType NextAdjacentArc(const ArcIndexType arc) const
Definition: ebert_graph.h:1132
bool IsOutgoingOrOppositeIncoming(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:1430
bool IsDirect(const ArcIndexType arc) const
Definition: ebert_graph.h:1418
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:1436
NodeIndexType DirectArcHead(const ArcIndexType arc) const
Definition: ebert_graph.h:1392
bool CheckArcValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:1372
ArcIndexType Opposite(const ArcIndexType arc) const
Definition: ebert_graph.h:1410
bool IsOutgoing(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:1441
std::string DebugString() const
Definition: ebert_graph.h:1459
bool IsReverse(const ArcIndexType arc) const
Definition: ebert_graph.h:1424
ArcIndexType ReverseArc(const ArcIndexType arc) const
Definition: ebert_graph.h:1403
ArcIndexType DirectArc(const ArcIndexType arc) const
Definition: ebert_graph.h:1397
NodeIndexType Tail(const ArcIndexType arc) const
Definition: ebert_graph.h:1377
EbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
Definition: ebert_graph.h:1229
bool CheckArcBounds(const ArcIndexType arc) const
Definition: ebert_graph.h:1364
NodeIndexType DirectArcTail(const ArcIndexType arc) const
Definition: ebert_graph.h:1385
ForwardEbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
Definition: ebert_graph.h:1604
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:1639
bool CheckArcValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:1621
bool CheckTailIndexValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:1626
NodeIndexType Tail(const ArcIndexType arc) const
Definition: ebert_graph.h:1632
bool CheckArcBounds(const ArcIndexType arc) const
Definition: ebert_graph.h:1613
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
Definition: ebert_graph.h:587
CycleHandlerForAnnotatedArcs(PermutationCycleHandler< ArcIndexType > *annotation_handler, NodeIndexType *data)
Definition: ebert_graph.h:576
void SetIndexFromTemp(ArcIndexType destination) const override
Definition: ebert_graph.h:593
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
Definition: ebert_graph.h:764
bool CheckArcValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:779
bool CheckTailIndexValidity(const ArcIndexType arc) const
Definition: ebert_graph.h:784
ArcIndexType NextOutgoingArc(const NodeIndexType node, ArcIndexType arc) const
Definition: ebert_graph.h:789
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
NodeIndexType Tail(const ArcIndexType arc) const
Definition: ebert_graph.h:757
bool CheckArcBounds(const ArcIndexType arc) const
Definition: ebert_graph.h:771
void Apply(IndexType permutation[], int permutation_start, int permutation_end)
virtual void SetIndexFromTemp(IndexType destination) const =0
virtual void SetTempFromIndex(IndexType source)=0
virtual void SetIndexFromIndex(IndexType source, IndexType destination) const =0
PermutationIndexComparisonByArcHead(const ZVector< NodeIndexType > &head)
Definition: ebert_graph.h:522
bool operator()(ArcIndexType a, ArcIndexType b) const
Definition: ebert_graph.h:526
void operator=(const OutgoingArcIterator &iterator)
Definition: ebert_graph.h:387
OutgoingArcIterator(const DerivedGraph &graph, NodeIndexType node, ArcIndexType arc)
Definition: ebert_graph.h:378
OutgoingArcIterator(const DerivedGraph &graph, NodeIndexType node)
Definition: ebert_graph.h:369
static const NodeIndexType kNilNode
Definition: ebert_graph.h:217
ArcIndexType NextArc(const ArcIndexType arc) const
Definition: ebert_graph.h:473
NodeIndexType max_num_nodes() const
Definition: ebert_graph.h:256
bool IsNodeValid(NodeIndexType node) const
Definition: ebert_graph.h:280
static const ArcIndexType kFirstArc
Definition: ebert_graph.h:226
ArcIndexType num_arcs() const
Definition: ebert_graph.h:242
NodeIndexType Head(const ArcIndexType arc) const
Definition: ebert_graph.h:298
ZVector< ArcIndexType > first_incident_arc_
Definition: ebert_graph.h:503
std::string ArcDebugString(const ArcIndexType arc) const
Definition: ebert_graph.h:311
static const ArcIndexType kMaxNumArcs
Definition: ebert_graph.h:236
NodeIndexType num_nodes() const
Definition: ebert_graph.h:238
ArcIndexType max_num_arcs() const
Definition: ebert_graph.h:260
std::string NodeDebugString(const NodeIndexType node) const
Definition: ebert_graph.h:303
ZVector< NodeIndexType > head_
Definition: ebert_graph.h:499
ArcIndexType end_arc_index() const
Definition: ebert_graph.h:253
static const ArcIndexType kNilArc
Definition: ebert_graph.h:220
ArcIndexType max_end_arc_index() const
Definition: ebert_graph.h:272
static const NodeIndexType kMaxNumNodes
Definition: ebert_graph.h:231
NodeIndexType end_node_index() const
Definition: ebert_graph.h:248
NodeIndexType StartNode(NodeIndexType node) const
Definition: ebert_graph.h:440
ArcIndexType FirstOutgoingArc(const NodeIndexType node) const
Definition: ebert_graph.h:480
static const NodeIndexType kFirstNode
Definition: ebert_graph.h:223
NodeIndexType max_end_node_index() const
Definition: ebert_graph.h:265
NodeIndexType NextNode(const NodeIndexType node) const
Definition: ebert_graph.h:459
ArcIndexType StartArc(ArcIndexType arc) const
Definition: ebert_graph.h:446
ArcIndexType LookUpArc(const NodeIndexType tail, const NodeIndexType head) const
Definition: ebert_graph.h:286
bool BuildTailArrayFromAdjacencyListsIfForwardGraph() const
Definition: ebert_graph.h:1921
GraphType * Graph(PermutationCycleHandler< typename GraphType::ArcIndex > *client_cycle_handler)
Definition: ebert_graph.h:2043
bool Reserve(const typename GraphType::NodeIndex new_max_num_nodes, const typename GraphType::ArcIndex new_max_num_arcs)
Definition: ebert_graph.h:2032
GraphType::ArcIndex AddArc(const typename GraphType::NodeIndex tail, const typename GraphType::NodeIndex head)
Definition: ebert_graph.h:2037
GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, typename GraphType::ArcIndex max_num_arcs, bool sort_arcs)
Definition: ebert_graph.h:2026
GraphType::ArcIndex AddArc(typename GraphType::NodeIndex tail, typename GraphType::NodeIndex head)
Definition: ebert_graph.h:1973
GraphType * Graph(PermutationCycleHandler< typename GraphType::ArcIndex > *client_cycle_handler)
Definition: ebert_graph.h:1992
GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, typename GraphType::ArcIndex max_num_arcs, bool sort_arcs)
Definition: ebert_graph.h:1966
int64_t b
int64_t a
Collection of objects used to extend the Constraint Solver library.
ZVector< FlowQuantity > QuantityArray
Definition: ebert_graph.h:210
ZVector< NodeIndex > NodeIndexArray
Definition: ebert_graph.h:208
ForwardStaticGraph< NodeIndex, ArcIndex > ForwardStarStaticGraph
Definition: ebert_graph.h:207
ForwardEbertGraph< NodeIndex, ArcIndex > ForwardStarGraph
Definition: ebert_graph.h:206
bool BuildLineGraph(const GraphType &graph, GraphType *const line_graph)
Definition: ebert_graph.h:2089
ZVector< CostValue > CostArray
Definition: ebert_graph.h:211
ZVector< ArcIndex > ArcIndexArray
Definition: ebert_graph.h:209
EbertGraph< NodeIndex, ArcIndex > StarGraph
Definition: ebert_graph.h:205
int64_t tail
int64_t head
static constexpr bool has_reverse_arcs
Definition: ebert_graph.h:1850
static constexpr bool is_dynamic
Definition: ebert_graph.h:1851