14#ifndef OR_TOOLS_GRAPH_EBERT_GRAPH_H_
15#define OR_TOOLS_GRAPH_EBERT_GRAPH_H_
178#include "absl/strings/str_cat.h"
188template <
typename NodeIndexType,
typename ArcIndexType>
190template <
typename NodeIndexType,
typename ArcIndexType>
191class ForwardEbertGraph;
192template <
typename NodeIndexType,
typename ArcIndexType>
193class ForwardStaticGraph;
213template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
287 const NodeIndexType
head)
const {
289 arc = ThisAsDerived()->NextOutgoingArc(
tail,
arc)) {
298 NodeIndexType
Head(
const ArcIndexType
arc)
const {
299 DCHECK(ThisAsDerived()->CheckArcValidity(
arc));
307 return absl::StrCat(
static_cast<int64_t
>(node));
315 return absl::StrCat(
static_cast<int64_t
>(
arc));
330 void Next() { head_ = graph_.NextNode(head_); }
333 NodeIndexType
Index()
const {
return head_; }
337 const DerivedGraph& graph_;
353 void Next() { arc_ = graph_.NextArc(arc_); }
356 ArcIndexType
Index()
const {
return arc_; }
360 const DerivedGraph& graph_;
388 DCHECK(&iterator.graph_ == &graph_);
389 node_ = iterator.node_;
390 arc_ = iterator.arc_;
398 arc_ = graph_.NextOutgoingArc(node_, arc_);
403 ArcIndexType
Index()
const {
return arc_; }
408 bool CheckInvariant()
const {
412 DCHECK(graph_.IsOutgoing(arc_, node_));
417 const DerivedGraph& graph_;
459 NodeIndexType
NextNode(
const NodeIndexType node)
const {
461 const NodeIndexType next_node = node + 1;
474 DCHECK(ThisAsDerived()->CheckArcValidity(
arc));
475 const ArcIndexType next_arc =
arc + 1;
482 return ThisAsDerived()->FindNextOutgoingArc(
483 ThisAsDerived()->FirstOutgoingOrOppositeIncomingArc(node));
508 inline const DerivedGraph* ThisAsDerived()
const {
509 return static_cast<const DerivedGraph*
>(
this);
514 inline DerivedGraph* ThisAsDerived() {
515 return static_cast<DerivedGraph*
>(
this);
519template <
typename NodeIndexType,
typename ArcIndexType>
527 return head_[
a] < head_[
b];
534template <
typename NodeIndexType,
typename ArcIndexType>
537 ForwardStaticGraph<NodeIndexType, ArcIndexType> > {
580 annotation_handler_(annotation_handler) {}
588 ArcIndexType destination)
const override {
624 const bool sort_arcs_by_head,
625 std::vector<std::pair<NodeIndexType, NodeIndexType> >* client_input_arcs,
630 client_cycle_handler) {
636 std::vector<std::pair<NodeIndexType, NodeIndexType> >& input_arcs =
653 num_nodes_,
static_cast<NodeIndexType
>(input_arcs[
arc].first + 1));
655 num_nodes_,
static_cast<NodeIndexType
>(input_arcs[
arc].second + 1));
658 for (NodeIndexType node = 0; node <
num_nodes; ++node) {
665 std::unique_ptr<ArcIndexType[]> arc_permutation;
666 if (client_cycle_handler !=
nullptr) {
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;
683 for (ArcIndexType input_arc = 0; input_arc <
num_arcs; ++input_arc) {
684 NodeIndexType
tail = input_arcs[input_arc].first;
687 input_arcs[input_arc].first =
static_cast<NodeIndexType
>(
arc);
689 for (ArcIndexType input_arc = 0; input_arc <
num_arcs; ++input_arc) {
691 static_cast<ArcIndexType
>(input_arcs[input_arc].first);
692 NodeIndexType
head = input_arcs[input_arc].second;
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;
716 if (sort_arcs_by_head) {
718 if (client_cycle_handler !=
nullptr) {
719 for (NodeIndexType node = 0; node <
num_nodes; ++node) {
722 &arc_permutation[begin], &arc_permutation[
end],
728 for (NodeIndexType node = 0; node <
num_nodes; ++node) {
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);
744 if (client_cycle_handler !=
nullptr &&
num_arcs > 0) {
757 NodeIndexType
Tail(
const ArcIndexType
arc)
const {
760 return (*tail_)[
arc];
786 (arc <= tail_->max_index()));
790 ArcIndexType
arc)
const {
804 std::string result =
"Arcs:(node) :\n";
809 result +=
"Node:First arc :\n";
821 if (tail_ ==
nullptr) {
822 if (!RepresentationClean()) {
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;
858 bool IsDirect()
const {
return true; }
859 bool RepresentationClean()
const {
return true; }
860 bool IsOutgoing(
const NodeIndexType node,
861 const ArcIndexType unused_arc)
const {
866 ArcIndexType FirstOutgoingOrOppositeIncomingArc(NodeIndexType node)
const {
867 DCHECK(RepresentationClean());
874 ArcIndexType FindNextOutgoingArc(ArcIndexType
arc)
const {
894 std::unique_ptr<ZVector<NodeIndexType> > tail_;
898template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
903template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
909template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
914template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
919template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
926template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
948template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
950 :
public StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph> {
952 friend class StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph>;
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) {
983 if (new_max_num_arcs < 0 || new_max_num_arcs >
kMaxNumArcs) {
991 ThisAsDerived()->ReserveInternal(new_max_num_nodes, new_max_num_arcs);
1022 template <
typename ArcIndexTypeStrictWeakOrderingFunctor>
1024 const ArcIndexTypeStrictWeakOrderingFunctor& compare,
1026 std::unique_ptr<ArcIndexType[]> arc_permutation(
1032 arc_permutation[i] = i;
1045 ThisAsDerived()->BuildRepresentation();
1053 DerivedGraph* graph)
1054 : annotation_handler_(annotation_handler),
1060 if (annotation_handler_ !=
nullptr) {
1063 head_temp_ = graph_->Head(source);
1064 tail_temp_ = graph_->Tail(source);
1068 ArcIndexType destination)
const override {
1069 if (annotation_handler_ !=
nullptr) {
1072 graph_->SetHead(destination, graph_->Head(source));
1073 graph_->SetTail(destination, graph_->Tail(source));
1077 if (annotation_handler_ !=
nullptr) {
1080 graph_->SetHead(destination, head_temp_);
1081 graph_->SetTail(destination, tail_temp_);
1088 void SetSeen(ArcIndexType* permutation_element)
const override {
1089 *permutation_element =
kNilArc;
1092 bool Unseen(ArcIndexType permutation_element)
const override {
1093 return permutation_element !=
kNilArc;
1100 DerivedGraph* graph_;
1101 NodeIndexType head_temp_;
1102 NodeIndexType tail_temp_;
1115 LOG(DFATAL) <<
"Could not reserve memory for "
1125 const NodeIndexType node)
const {
1134 DCHECK(ThisAsDerived()->CheckArcValidity(
arc));
1140 const ArcIndexType
arc)
const {
1141 DCHECK(ThisAsDerived()->CheckArcValidity(
arc));
1158 inline const DerivedGraph* ThisAsDerived()
const {
1159 return static_cast<const DerivedGraph*
>(
this);
1164 inline DerivedGraph* ThisAsDerived() {
1165 return static_cast<DerivedGraph*
>(
this);
1178 void SetHead(
const ArcIndexType
arc,
const NodeIndexType
head) {
1186template <
typename NodeIndexType,
typename ArcIndexType>
1189 EbertGraph<NodeIndexType, ArcIndexType> > {
1246 DCHECK(CheckInvariant());
1252 NodeIndexType node, ArcIndexType
arc)
1256 DCHECK(CheckInvariant());
1261 DCHECK(&iterator.graph_ == &graph_);
1262 node_ = iterator.node_;
1263 arc_ = iterator.arc_;
1272 DCHECK(CheckInvariant());
1276 ArcIndexType
Index()
const {
return arc_; }
1281 bool CheckInvariant()
const {
1292 NodeIndexType node_;
1304 arc_(graph_.
StartArc(graph_.FirstIncomingArc(node))) {
1305 DCHECK(CheckInvariant());
1316 DCHECK(CheckInvariant());
1321 DCHECK(&iterator.graph_ == &graph_);
1322 node_ = iterator.node_;
1323 arc_ = iterator.arc_;
1331 arc_ = graph_.NextIncomingArc(arc_);
1332 DCHECK(CheckInvariant());
1343 bool CheckInvariant()
const {
1354 NodeIndexType node_;
1377 NodeIndexType
Tail(
const ArcIndexType
arc)
const {
1411 const ArcIndexType opposite = ~arc;
1431 NodeIndexType node)
const {
1461 std::string result =
"Arcs:(node, next arc) :\n";
1466 result +=
"Node:First arc :\n";
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);
1497 ArcIndexType FirstIncomingArc(
const NodeIndexType node)
const {
1504 ArcIndexType NextIncomingArc(
const ArcIndexType
arc)
const {
1512 void RecordArc(ArcIndexType
arc, NodeIndexType
tail, NodeIndexType
head) {
1521 void SetTail(
const ArcIndexType
arc,
const NodeIndexType
tail) {
1527 void Attach(ArcIndexType
arc) {
1540 ArcIndexType FindNextOutgoingArc(ArcIndexType
arc)
const {
1550 ArcIndexType FindNextIncomingArc(ArcIndexType
arc)
const {
1562template <
typename NodeIndexType,
typename ArcIndexType>
1565 ForwardEbertGraph<NodeIndexType, ArcIndexType> > {
1628 (arc <= tail_->max_index());
1632 NodeIndexType
Tail(
const ArcIndexType
arc)
const {
1635 return (*tail_)[
arc];
1652 Attach((*tail_)[
arc],
arc);
1661 if (tail_ ==
nullptr) {
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;
1701 std::string result =
"Arcs:(node, next arc) :\n";
1706 result +=
"Node:First arc :\n";
1723 void ReserveTailArray(ArcIndexType new_max_num_arcs) {
1724 if (tail_ !=
nullptr) {
1728 if (tail_->Reserve(
kFirstArc, new_max_num_arcs - 1)) {
1729 for (ArcIndexType
arc = tail_->max_index() + 1;
arc < new_max_num_arcs;
1760 void ReserveInternal(NodeIndexType new_max_num_nodes,
1761 ArcIndexType new_max_num_arcs) {
1768 ReserveTailArray(new_max_num_arcs);
1773 void RecordArc(ArcIndexType
arc, NodeIndexType
tail, NodeIndexType
head) {
1781 void SetTail(
const ArcIndexType
arc,
const NodeIndexType
tail) {
1789 void Attach(NodeIndexType
tail, ArcIndexType
arc) {
1798 if (tail_ !=
nullptr) {
1805 ArcIndexType FindNextOutgoingArc(ArcIndexType
arc)
const {
1814 bool IsOutgoing(
const ArcIndex unused_arc,
1822 bool IsDirect(
const ArcIndex unused_arc)
const {
return true; }
1839 std::unique_ptr<ZVector<NodeIndexType> > tail_;
1848template <
typename GraphType>
1854template <
typename NodeIndexType,
typename ArcIndexType>
1860template <
typename NodeIndexType,
typename ArcIndexType>
1866namespace or_internal {
1872template <
typename GraphType,
bool has_reverse_arcs>
1882template <
typename GraphType>
1895template <
typename GraphType,
bool has_reverse_arcs>
1905template <
typename GraphType>
1916template <
typename GraphType>
1924 tail_array_builder(graph_);
1925 return tail_array_builder.BuildTailArray();
1931 tail_array_releaser(graph_);
1932 tail_array_releaser.ReleaseTailArray();
1939template <
typename GraphType>
1947 return ((graph_.Tail(
a) < graph_.Tail(
b)) ||
1948 ((graph_.Tail(
a) == graph_.Tail(
b)) &&
1949 (graph_.Head(
a) < graph_.Head(
b))));
1953 const GraphType& graph_;
1956namespace or_internal {
1963template <
typename GraphType,
bool is_dynamic>
1969 : num_arcs_(0), sort_arcs_(sort_arcs) {
1970 Reserve(max_num_nodes, max_num_arcs);
1978 if (num_arcs_ < max_num_arcs_ &&
1979 tail < GraphType::kFirstNode + max_num_nodes_ &&
1980 head < GraphType::kFirstNode + max_num_nodes_) {
1982 arcs_.push_back(std::make_pair(
tail,
head));
1987 return GraphType::kNilArc;
1993 client_cycle_handler) {
1994 GraphType* graph =
new GraphType(max_num_nodes_, num_arcs_, sort_arcs_,
1995 &arcs_, client_cycle_handler);
2003 max_num_nodes_ = new_max_num_nodes;
2004 max_num_arcs_ = new_max_num_arcs;
2005 arcs_.reserve(new_max_num_arcs);
2014 std::pair<typename GraphType::NodeIndex, typename GraphType::NodeIndex> >
2017 const bool sort_arcs_;
2023template <
typename GraphType>
2029 : graph_(new GraphType(max_num_nodes, max_num_arcs)),
2030 sort_arcs_(sort_arcs) {}
2034 return graph_->Reserve(new_max_num_nodes, new_max_num_arcs);
2044 client_cycle_handler) {
2049 graph_->GroupForwardArcsByFunctor(arc_ordering, client_cycle_handler);
2052 GraphType* result = graph_;
2058 GraphType*
const graph_;
2059 const bool sort_arcs_;
2064template <
typename GraphType>
2067 GraphType, graph_traits<GraphType>::is_dynamic> {
2074 num_nodes, num_arcs, sort_arcs) {}
2088template <
typename GraphType>
2090 if (line_graph ==
nullptr) {
2091 LOG(DFATAL) <<
"line_graph must not be NULL";
2094 if (line_graph->num_nodes() != 0) {
2095 LOG(DFATAL) <<
"line_graph must be empty";
2098 typedef typename GraphType::ArcIterator ArcIterator;
2099 typedef typename GraphType::OutgoingArcIterator OutgoingArcIterator;
2102 for (ArcIterator arc_iterator(graph); arc_iterator.Ok();
2103 arc_iterator.Next()) {
2106 for (OutgoingArcIterator iterator(graph,
head); iterator.Ok();
2111 line_graph->Reserve(graph.num_arcs(), num_arcs);
2112 for (ArcIterator arc_iterator(graph); arc_iterator.Ok();
2113 arc_iterator.Next()) {
2116 for (OutgoingArcIterator iterator(graph,
head); iterator.Ok();
2118 line_graph->AddArc(
arc, iterator.Index());
#define DCHECK_LE(val1, val2)
#define DCHECK_GE(val1, val2)
#define DCHECK_LT(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
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
ArcFunctorOrderingByTailAndHead(const GraphType &graph)
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
void SetIndexFromTemp(ArcIndexType destination) const override
void SetTempFromIndex(ArcIndexType source) override
void operator=(const IncomingArcIterator &iterator)
IncomingArcIterator(const EbertGraph &graph, NodeIndexType node, ArcIndexType arc)
IncomingArcIterator(const EbertGraph &graph, NodeIndexType node)
ArcIndexType Index() const
OutgoingOrOppositeIncomingArcIterator(const EbertGraph &graph, NodeIndexType node, ArcIndexType arc)
OutgoingOrOppositeIncomingArcIterator(const EbertGraph &graph, NodeIndexType node)
ArcIndexType Index() const
void operator=(const OutgoingOrOppositeIncomingArcIterator &iterator)
~CycleHandlerForAnnotatedArcs() override
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
bool Unseen(ArcIndexType permutation_element) const override
CycleHandlerForAnnotatedArcs(PermutationCycleHandler< ArcIndexType > *annotation_handler, DerivedGraph *graph)
void SetTempFromIndex(ArcIndexType source) override
void SetIndexFromTemp(ArcIndexType destination) const override
void SetSeen(ArcIndexType *permutation_element) const override
static const NodeIndexType kNilNode
ZVector< ArcIndexType > next_adjacent_arc_
bool IsNodeValid(NodeIndexType node) const
ArcIndexType max_num_arcs_
static const ArcIndexType kFirstArc
ArcIndexType NextOutgoingArc(const NodeIndexType unused_node, const ArcIndexType arc) const
ZVector< ArcIndexType > first_incident_arc_
static const ArcIndexType kMaxNumArcs
bool Reserve(NodeIndexType new_max_num_nodes, ArcIndexType new_max_num_arcs)
bool representation_clean_
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ZVector< NodeIndexType > head_
ArcIndexType end_arc_index() const
void Initialize(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
ArcIndexType FirstOutgoingOrOppositeIncomingArc(const NodeIndexType node) const
void GroupForwardArcsByFunctor(const ArcIndexTypeStrictWeakOrderingFunctor &compare, PermutationCycleHandler< ArcIndexType > *annotation_handler)
static const ArcIndexType kNilArc
static const NodeIndexType kMaxNumNodes
NodeIndexType max_num_nodes_
static const NodeIndexType kFirstNode
ArcIndexType NextAdjacentArc(const ArcIndexType arc) const
bool IsOutgoingOrOppositeIncoming(ArcIndexType arc, NodeIndexType node) const
bool IsDirect(const ArcIndexType arc) const
void BuildRepresentation()
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
NodeIndexType DirectArcHead(const ArcIndexType arc) const
bool CheckArcValidity(const ArcIndexType arc) const
ArcIndexType Opposite(const ArcIndexType arc) const
bool IsOutgoing(ArcIndexType arc, NodeIndexType node) const
std::string DebugString() const
bool IsReverse(const ArcIndexType arc) const
ArcIndexType ReverseArc(const ArcIndexType arc) const
ArcIndexType DirectArc(const ArcIndexType arc) const
NodeIndexType Tail(const ArcIndexType arc) const
EbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
bool CheckArcBounds(const ArcIndexType arc) const
NodeIndexType DirectArcTail(const ArcIndexType arc) const
ForwardEbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs)
void BuildRepresentation()
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
bool CheckArcValidity(const ArcIndexType arc) const
bool CheckTailIndexValidity(const ArcIndexType arc) const
std::string DebugString() const
NodeIndexType Tail(const ArcIndexType arc) const
bool CheckArcBounds(const ArcIndexType arc) const
bool TailArrayComplete() const
void SetIndexFromIndex(ArcIndexType source, ArcIndexType destination) const override
CycleHandlerForAnnotatedArcs(PermutationCycleHandler< ArcIndexType > *annotation_handler, NodeIndexType *data)
void SetTempFromIndex(ArcIndexType source) override
void SetIndexFromTemp(ArcIndexType destination) const override
bool IsIncoming(ArcIndexType arc, NodeIndexType node) const
bool CheckArcValidity(const ArcIndexType arc) const
bool CheckTailIndexValidity(const ArcIndexType arc) const
ArcIndexType NextOutgoingArc(const NodeIndexType node, 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)
std::string DebugString() const
NodeIndexType Tail(const ArcIndexType arc) const
bool CheckArcBounds(const ArcIndexType arc) const
bool TailArrayComplete() const
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)
bool operator()(ArcIndexType a, ArcIndexType b) const
ArcIterator(const DerivedGraph &graph)
ArcIndexType Index() const
NodeIterator(const DerivedGraph &graph)
NodeIndexType Index() const
void operator=(const OutgoingArcIterator &iterator)
ArcIndexType Index() const
OutgoingArcIterator(const DerivedGraph &graph, NodeIndexType node, ArcIndexType arc)
OutgoingArcIterator(const DerivedGraph &graph, NodeIndexType node)
static const NodeIndexType kNilNode
ArcIndexType NextArc(const ArcIndexType arc) const
NodeIndexType max_num_nodes() const
bool IsNodeValid(NodeIndexType node) const
ArcIndexType max_num_arcs_
static const ArcIndexType kFirstArc
ArcIndexType num_arcs() const
NodeIndexType Head(const ArcIndexType arc) const
ZVector< ArcIndexType > first_incident_arc_
std::string ArcDebugString(const ArcIndexType arc) const
static const ArcIndexType kMaxNumArcs
NodeIndexType num_nodes() const
ArcIndexType max_num_arcs() const
std::string NodeDebugString(const NodeIndexType node) const
ZVector< NodeIndexType > head_
ArcIndexType end_arc_index() const
static const ArcIndexType kNilArc
ArcIndexType max_end_arc_index() const
static const NodeIndexType kMaxNumNodes
NodeIndexType max_num_nodes_
NodeIndexType end_node_index() const
NodeIndexType StartNode(NodeIndexType node) const
ArcIndexType FirstOutgoingArc(const NodeIndexType node) const
static const NodeIndexType kFirstNode
NodeIndexType max_end_node_index() const
NodeIndexType NextNode(const NodeIndexType node) const
ArcIndexType StartArc(ArcIndexType arc) const
ArcIndexType LookUpArc(const NodeIndexType tail, const NodeIndexType head) const
bool BuildTailArrayFromAdjacencyListsIfForwardGraph() const
TailArrayManager(GraphType *g)
void ReleaseTailArrayIfForwardGraph() const
int64_t max_index() const
bool Reserve(int64_t new_min_index, int64_t new_max_index)
void Set(int64_t index, T value)
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)
GraphType::ArcIndex AddArc(const typename GraphType::NodeIndex tail, const typename GraphType::NodeIndex head)
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)
GraphType * Graph(PermutationCycleHandler< typename GraphType::ArcIndex > *client_cycle_handler)
GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, typename GraphType::ArcIndex max_num_arcs, bool sort_arcs)
Collection of objects used to extend the Constraint Solver library.
ZVector< FlowQuantity > QuantityArray
ZVector< NodeIndex > NodeIndexArray
ForwardStaticGraph< NodeIndex, ArcIndex > ForwardStarStaticGraph
ForwardEbertGraph< NodeIndex, ArcIndex > ForwardStarGraph
bool BuildLineGraph(const GraphType &graph, GraphType *const line_graph)
ZVector< CostValue > CostArray
ZVector< ArcIndex > ArcIndexArray
EbertGraph< NodeIndex, ArcIndex > StarGraph
std::optional< int64_t > end
static constexpr bool has_reverse_arcs
static constexpr bool is_dynamic
bool BuildTailArray() const
TailArrayBuilder(GraphType *graph)
bool BuildTailArray() const
TailArrayBuilder(GraphType *unused_graph)
void ReleaseTailArray() const
TailArrayReleaser(GraphType *graph)
void ReleaseTailArray() const
TailArrayReleaser(GraphType *unused_graph)