161#ifndef UTIL_GRAPH_GRAPH_H_
162#define UTIL_GRAPH_GRAPH_H_
172#include <type_traits>
175#include "absl/base/attributes.h"
176#include "absl/debugging/leak_check.h"
177#include "absl/log/check.h"
178#include "absl/types/span.h"
187template <
typename IndexT,
typename T>
190template <
typename IndexT,
typename T>
206template <
typename NodeIndexType = int32_t,
typename ArcIndexType = int32_t,
207 bool HasNegativeReverseArcs =
false>
244 return node >= NodeIndexType(0) && node <
num_nodes_;
250 return (HasNegativeReverseArcs ? -
num_arcs_ : ArcIndexType(0)) <= arc &&
289 static_assert(std::numeric_limits<NodeIndexType>::is_specialized);
291 std::numeric_limits<NodeIndexType>::max();
292 static_assert(std::numeric_limits<ArcIndexType>::is_specialized);
294 std::numeric_limits<ArcIndexType>::max();
302 std::vector<ArcIndexType>* permutation);
315template <
typename Graph,
typename ArcIterator,
typename PropertyT,
318#
if __cplusplus < 201703L
319 : public
std::iterator<
std::input_iterator_tag, PropertyT>
327#if __cplusplus >= 201703L && __cplusplus < 202002L
328 using iterator_category = std::input_iterator_tag;
329 using pointer = PropertyT*;
330 using reference = PropertyT&;
336 : arc_it_(
std::move(arc_it)), graph_(&
graph) {}
352 return l.arc_it_ == r.arc_it_;
366template <
typename Graph,
typename ArcIterator>
372template <
typename Graph,
typename ArcIterator>
375 &Graph::OppositeArc>;
381template <
typename ArcIndexType>
383 return ArcIndexType(-1) < ArcIndexType(0);
387template <
typename IndexT,
typename T>
391 return std::vector<T>::operator[](
static_cast<size_t>(index));
394 return std::vector<T>::operator[](
static_cast<size_t>(index));
397 void resize(IndexT index,
const T& value) {
398 return std::vector<T>::resize(
static_cast<size_t>(index), value);
402 return std::vector<T>::reserve(
static_cast<size_t>(index));
405 void assign(IndexT index,
const T& value) {
406 return std::vector<T>::assign(
static_cast<size_t>(index), value);
409 IndexT
size()
const {
return IndexT(std::vector<T>::size()); }
426template <
typename IndexT,
typename T>
431 SVector() : base_(nullptr), size_(0), capacity_(0) {}
438 if (capacity_ < other.size_) {
442 capacity_ = other.size_;
443 base_ = Allocate(capacity_);
444 CHECK(base_ !=
nullptr);
445 base_ +=
static_cast<ptrdiff_t
>(capacity_);
451 CopyInternal(other, std::is_integral<T>());
468 DCHECK_GE(n, -size_);
469 return base_[
static_cast<ptrdiff_t
>(n)];
474 DCHECK_GE(n, -size_);
475 return base_[
static_cast<ptrdiff_t
>(n)];
480 for (IndexT i = -n; i < -size_; ++i) {
481 new (base_ +
static_cast<ptrdiff_t
>(i)) T();
483 for (IndexT i = size_; i < n; ++i) {
484 new (base_ +
static_cast<ptrdiff_t
>(i)) T();
486 for (IndexT i = -size_; i < -n; ++i) {
487 base_[
static_cast<ptrdiff_t
>(i)].~T();
489 for (IndexT i = n; i < size_; ++i) {
490 base_[
static_cast<ptrdiff_t
>(i)].~T();
497 T*
data()
const {
return base_; }
499 const T*
begin()
const {
return base_; }
500 const T*
end()
const {
return base_ +
static_cast<ptrdiff_t
>(size_); }
503 std::swap(base_, x.base_);
504 std::swap(size_, x.size_);
505 std::swap(capacity_, x.capacity_);
509 DCHECK_GE(n, IndexT(0));
512 const IndexT new_capacity = std::min(n,
max_size());
513 T* new_storage = Allocate(new_capacity);
514 CHECK(new_storage !=
nullptr);
515 T* new_base = new_storage +
static_cast<ptrdiff_t
>(new_capacity);
518 for (ptrdiff_t i =
static_cast<ptrdiff_t
>(-size_);
519 i < static_cast<ptrdiff_t>(size_); ++i) {
520 new (new_base + i) T(std::move(base_[i]));
522 IndexT saved_size = size_;
526 capacity_ = new_capacity;
532 void grow(
const T& left = T(),
const T& right = T()) {
533 if (size_ == capacity_) {
538 reserve(NewCapacity(IndexT(1)));
539 new (base_ +
static_cast<ptrdiff_t
>(size_)) T(right_copy);
540 new (base_ -
static_cast<ptrdiff_t
>(size_) - 1) T(left_copy);
543 new (base_ +
static_cast<ptrdiff_t
>(size_)) T(right);
544 new (base_ -
static_cast<ptrdiff_t
>(size_) - 1) T(left);
549 IndexT
size()
const {
return size_; }
553 IndexT
max_size()
const {
return std::numeric_limits<IndexT>::max(); }
556 if (base_ ==
nullptr)
return;
558 if (capacity_ > IndexT(0)) {
559 free(base_ -
static_cast<ptrdiff_t
>(capacity_));
561 capacity_ = IndexT(0);
569 void CopyInternal(
const SVector& other, std::true_type) {
570 std::memcpy(base_ -
static_cast<ptrdiff_t
>(other.size_),
571 other.base_ -
static_cast<ptrdiff_t
>(other.size_),
572 2LL *
static_cast<ptrdiff_t
>(other.size_) *
sizeof(T));
577 void CopyInternal(
const SVector& other, std::false_type) {
578 for (IndexT i = -size_; i < size_; ++i) {
579 new (base_ +
static_cast<ptrdiff_t
>(i))
580 T(other.base_[
static_cast<ptrdiff_t
>(i)]);
585 return absl::IgnoreLeak(
static_cast<T*
>(
589 IndexT NewCapacity(IndexT delta) {
591 double candidate = 1.3 *
static_cast<size_t>(capacity_);
592 if (candidate >
static_cast<size_t>(
max_size())) {
593 candidate =
static_cast<size_t>(
max_size());
595 IndexT new_capacity(candidate);
596 if (new_capacity > capacity_ + delta) {
599 return capacity_ + delta;
616template <
typename Graph>
620 using NeighborRangeType = std::decay_t<
621 decltype(std::declval<Graph>()[std::declval<Graph>().size()])>;
626 std::decay_t<decltype(*(std::declval<NeighborRangeType>().begin()))>;
641template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
660 if (num_nodes > NodeIndexType(0)) {
661 this->
AddNode(num_nodes - NodeIndexType(1));
668 void AddNode(NodeIndexType node);
676 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
687 void Build(std::vector<ArcIndexType>* permutation);
690 NodeIndexType
Tail(ArcIndexType arc)
const;
691 NodeIndexType
Head(ArcIndexType arc)
const;
704 ArcIndexType
OutDegree(NodeIndexType node)
const;
719 NodeIndexType node, ArcIndexType from)
const {
722 DCHECK_EQ(
Tail(from), node);
757template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
768 StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
770 : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
773 if (num_nodes > NodeIndexType(0)) {
774 this->
AddNode(num_nodes - NodeIndexType(1));
779 template <
class ArcContainer>
781 const ArcContainer& arcs);
784 class OutgoingArcIterator;
786 NodeIndexType
Head(ArcIndexType arc)
const;
787 NodeIndexType
Tail(ArcIndexType arc)
const;
788 ArcIndexType
OutDegree(NodeIndexType node)
const;
793 ArcIndexType from)
const {
794 DCHECK_GE(from, start_[node]);
795 const ArcIndexType limit = DirectArcLimit(node);
803 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
807 void AddNode(NodeIndexType node);
808 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
811 void Build(std::vector<ArcIndexType>* permutation);
814 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
817 return start_[node + NodeIndexType(1)];
822 NodeIndexType last_tail_seen_;
825 internal::Vector<NodeIndexType, ArcIndexType> start_;
826 internal::Vector<ArcIndexType, NodeIndexType> head_;
827 internal::Vector<ArcIndexType, NodeIndexType> tail_;
836template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
838 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
840 "ArcIndexType must be signed");
855 if (num_nodes > NodeIndexType(0)) {
856 this->
AddNode(num_nodes - NodeIndexType(1));
860 NodeIndexType
Head(ArcIndexType arc)
const;
861 NodeIndexType
Tail(ArcIndexType arc)
const;
882 ArcIndexType
OutDegree(NodeIndexType node)
const;
883 ArcIndexType
InDegree(NodeIndexType node)
const;
898 NodeIndexType node, ArcIndexType from)
const {
901 DCHECK_GE(from, ArcIndexType(0));
902 DCHECK_EQ(
Tail(from), node);
911 NodeIndexType node, ArcIndexType from)
const {
924 NodeIndexType node)
const {
930 NodeIndexType node, ArcIndexType from)
const {
933 DCHECK_LT(from, ArcIndexType(0));
934 DCHECK_EQ(
Tail(from), node);
941 ArcIndexType from)
const;
950 void AddNode(NodeIndexType node);
951 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
954 void Build(std::vector<ArcIndexType>* permutation);
972template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
974 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
976 "ArcIndexType must be signed");
992 if (num_nodes > NodeIndexType(0)) {
993 this->
AddNode(num_nodes - NodeIndexType(1));
999 NodeIndexType
Head(ArcIndexType arc)
const;
1000 NodeIndexType
Tail(ArcIndexType arc)
const;
1007 class OutgoingOrOppositeIncomingArcIterator;
1018 ArcIndexType from)
const {
1019 DCHECK_GE(from, start_[node]);
1020 const ArcIndexType limit = DirectArcLimit(node);
1027 ReverseArcLimit(node));
1030 NodeIndexType node, ArcIndexType from)
const {
1031 DCHECK_GE(from, reverse_start_[node]);
1032 const ArcIndexType limit = ReverseArcLimit(node);
1044 NodeIndexType node, ArcIndexType from)
const {
1057 ArcIndexType from)
const;
1062 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
1066 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
1069 void Build(std::vector<ArcIndexType>* permutation);
1072 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
1075 return start_[node + NodeIndexType(1)];
1077 ArcIndexType ReverseArcLimit(NodeIndexType node)
const {
1080 return reverse_start_[node + NodeIndexType(1)];
1086 internal::Vector<NodeIndexType, ArcIndexType> start_;
1089 internal::Vector<NodeIndexType, ArcIndexType> reverse_start_;
1090 internal::SVector<ArcIndexType, NodeIndexType> head_;
1091 internal::SVector<ArcIndexType, ArcIndexType> opposite_;
1104template <
class IntVector,
class Array>
1105void Permute(
const IntVector& permutation, Array* array_to_permute) {
1106 if (permutation.empty()) {
1109 const auto size = permutation.size();
1110 auto& array = *array_to_permute;
1112 typename std::iterator_traits<
decltype(std::begin(array))>::value_type;
1113 std::vector<ElementType> temp(size);
1114 auto array_begin = std::begin(array);
1115 std::copy_n(array_begin, size, temp.begin());
1116 for (
size_t i = 0; i < permutation.size(); ++i) {
1117 *(array_begin +
static_cast<size_t>(permutation[i])) = temp[i];
1123template <
typename NodeIndexType,
typename ArcIndexType,
1124 bool HasNegativeReverseArcs>
1125IntegerRange<NodeIndexType> BaseGraph<
1126 NodeIndexType, ArcIndexType, HasNegativeReverseArcs>
::AllNodes()
const {
1130template <
typename NodeIndexType,
typename ArcIndexType,
1131 bool HasNegativeReverseArcs>
1138template <
typename NodeIndexType,
typename ArcIndexType,
1139 bool HasNegativeReverseArcs>
1140NodeIndexType
BaseGraph<NodeIndexType, ArcIndexType,
1147template <
typename NodeIndexType,
typename ArcIndexType,
1148 bool HasNegativeReverseArcs>
1149ArcIndexType
BaseGraph<NodeIndexType, ArcIndexType,
1155template <
typename NodeIndexType,
typename ArcIndexType,
1156 bool HasNegativeReverseArcs>
1157void BaseGraph<NodeIndexType, ArcIndexType,
1168template <
typename NodeIndexType,
typename ArcIndexType,
1169 bool HasNegativeReverseArcs>
1173 ArcIndexType sum(0);
1174 for (NodeIndexType i(0); i <
num_nodes_; ++i) {
1175 ArcIndexType temp = (*v)[i];
1188template <
typename NodeIndexType,
typename ArcIndexType,
1189 bool HasNegativeReverseArcs>
1194 std::vector<ArcIndexType>* permutation) {
1199 NodeIndexType last_tail_seen(0);
1200 bool permutation_needed =
false;
1201 for (ArcIndexType i(0); i <
num_arcs_; ++i) {
1202 NodeIndexType tail = (*head)[i];
1203 if (!permutation_needed) {
1204 permutation_needed = tail < last_tail_seen;
1205 last_tail_seen = tail;
1213 if (!permutation_needed) {
1214 for (ArcIndexType i(0); i <
num_arcs_; ++i) {
1215 (*head)[i] = (*head)[~i];
1217 if (permutation !=
nullptr) {
1218 permutation->clear();
1225 std::vector<ArcIndexType> perm(
static_cast<size_t>(
num_arcs_));
1226 for (ArcIndexType i(0); i <
num_arcs_; ++i) {
1227 perm[
static_cast<size_t>(i)] = (*start)[(*head)[i]]++;
1232 for (NodeIndexType i =
num_nodes_ - NodeIndexType(1); i > NodeIndexType(0);
1234 (*start)[i] = (*start)[i - NodeIndexType(1)];
1236 (*start)[NodeIndexType(0)] = ArcIndexType(0);
1240 for (ArcIndexType i(0); i <
num_arcs_; ++i) {
1241 (*head)[perm[
static_cast<size_t>(i)]] = (*head)[~i];
1243 if (permutation !=
nullptr) {
1244 permutation->swap(perm);
1257#define DEFINE_RANGE_BASED_ARC_ITERATION(c, t) \
1258 template <typename NodeIndexType, typename ArcIndexType> \
1259 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1260 c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1261 return BeginEndWrapper<t##ArcIterator>( \
1262 t##ArcIterator(*this, node), \
1263 t##ArcIterator(*this, node, Base::kNilArc)); \
1265 template <typename NodeIndexType, typename ArcIndexType> \
1266 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1267 c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1268 NodeIndexType node, ArcIndexType from) const { \
1269 return BeginEndWrapper<t##ArcIterator>( \
1270 t##ArcIterator(*this, node, from), \
1271 t##ArcIterator(*this, node, Base::kNilArc)); \
1276#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1277 using iterator_category = std::input_iterator_tag; \
1278 using difference_type = ptrdiff_t; \
1279 using pointer = const ArcIndexType*; \
1280 using value_type = ArcIndexType; \
1281 using reference = value_type; \
1282 bool operator!=(const iterator_class_name& other) const { \
1283 return this->index_ != other.index_; \
1285 bool operator==(const iterator_class_name& other) const { \
1286 return this->index_ == other.index_; \
1288 ArcIndexType operator*() const { return this->Index(); } \
1289 iterator_class_name& operator++() { \
1293 iterator_class_name operator++(int) { \
1301template <
typename NodeIndexType,
typename ArcIndexType>
1303 ArcIndexType arc)
const {
1308template <
typename NodeIndexType,
typename ArcIndexType>
1310 ArcIndexType arc)
const {
1315template <
typename NodeIndexType,
typename ArcIndexType>
1317 NodeIndexType node)
const {
1318 ArcIndexType degree(0);
1319 for (
auto arc ABSL_ATTRIBUTE_UNUSED :
OutgoingArcs(node)) ++degree;
1323template <
typename NodeIndexType,
typename ArcIndexType>
1325 if (node < num_nodes_)
return;
1326 DCHECK(!const_capacities_ || node < node_capacity_);
1327 num_nodes_ = node + NodeIndexType(1);
1331template <
typename NodeIndexType,
typename ArcIndexType>
1333 NodeIndexType tail, NodeIndexType head) {
1334 DCHECK_GE(tail, NodeIndexType(0));
1335 DCHECK_GE(head, NodeIndexType(0));
1336 AddNode(tail > head ? tail : head);
1337 head_.push_back(head);
1338 tail_.push_back(tail);
1339 next_.push_back(start_[tail]);
1340 start_[tail] = num_arcs_;
1341 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1345template <
typename NodeIndexType,
typename ArcIndexType>
1347 Base::ReserveNodes(bound);
1348 if (bound <= num_nodes_)
return;
1349 start_.reserve(bound);
1352template <
typename NodeIndexType,
typename ArcIndexType>
1354 Base::ReserveArcs(bound);
1355 if (bound <= num_arcs_)
return;
1356 head_.reserve(bound);
1357 tail_.reserve(bound);
1358 next_.reserve(bound);
1361template <
typename NodeIndexType,
typename ArcIndexType>
1363 std::vector<ArcIndexType>* permutation) {
1364 if (permutation !=
nullptr) {
1365 permutation->clear();
1371template <
typename NodeIndexType,
typename ArcIndexType>
1372template <
class ArcContainer>
1373StaticGraph<NodeIndexType, ArcIndexType>
1375 const ArcContainer& arcs) {
1377 for (
const auto& [from,
to] : arcs) g.AddArc(from,
to);
1382template <
typename NodeIndexType,
typename ArcIndexType>
1383absl::Span<const NodeIndexType>
1385 return absl::Span<const NodeIndexType>(
1386 head_.data() +
static_cast<size_t>(start_[node]),
1387 static_cast<size_t>(DirectArcLimit(node) - start_[node]));
1390template <
typename NodeIndexType,
typename ArcIndexType>
1392 NodeIndexType node)
const {
1393 return DirectArcLimit(node) - start_[node];
1396template <
typename NodeIndexType,
typename ArcIndexType>
1398 NodeIndexType bound) {
1400 if (bound <= num_nodes_)
return;
1401 start_.reserve(bound + NodeIndexType(1));
1404template <
typename NodeIndexType,
typename ArcIndexType>
1406 Base::ReserveArcs(bound);
1407 if (bound <= num_arcs_)
return;
1408 head_.reserve(bound);
1409 tail_.reserve(bound);
1412template <
typename NodeIndexType,
typename ArcIndexType>
1414 if (node < num_nodes_)
return;
1415 DCHECK(!const_capacities_ || node < node_capacity_) << node;
1416 num_nodes_ = node + NodeIndexType(1);
1417 start_.resize(num_nodes_ + NodeIndexType(1), ArcIndexType(0));
1420template <
typename NodeIndexType,
typename ArcIndexType>
1422 NodeIndexType tail, NodeIndexType head) {
1423 DCHECK_GE(tail, NodeIndexType(0));
1424 DCHECK_GE(head, NodeIndexType(0));
1426 AddNode(tail > head ? tail : head);
1427 if (arc_in_order_) {
1428 if (tail >= last_tail_seen_) {
1430 last_tail_seen_ = tail;
1432 arc_in_order_ =
false;
1435 tail_.push_back(tail);
1436 head_.push_back(head);
1437 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1441template <
typename NodeIndexType,
typename ArcIndexType>
1443 ArcIndexType arc)
const {
1448template <
typename NodeIndexType,
typename ArcIndexType>
1450 ArcIndexType arc)
const {
1467template <
typename NodeIndexType,
typename ArcIndexType>
1469 std::vector<ArcIndexType>* permutation) {
1471 if (is_built_)
return;
1473 node_capacity_ = num_nodes_;
1474 arc_capacity_ = num_arcs_;
1476 if (num_nodes_ == NodeIndexType(0)) {
1481 if (arc_in_order_) {
1482 if (permutation !=
nullptr) {
1483 permutation->clear();
1485 this->ComputeCumulativeSum(&start_);
1491 start_.assign(num_nodes_ + NodeIndexType(1), ArcIndexType(0));
1492 for (ArcIndexType
i(0);
i < num_arcs_; ++
i) {
1495 this->ComputeCumulativeSum(&start_);
1499 std::vector<ArcIndexType> perm(
static_cast<size_t>(num_arcs_));
1500 for (ArcIndexType
i(0);
i < num_arcs_; ++
i) {
1501 perm[
static_cast<size_t>(
i)] = start_[tail_[i]]++;
1505 CHECK_EQ(tail_.size(), num_arcs_);
1507 for (ArcIndexType
i(0);
i < num_arcs_; ++
i) {
1508 head_[perm[
static_cast<size_t>(
i)]] = tail_[i];
1511 if (permutation !=
nullptr) {
1512 permutation->swap(perm);
1516 DCHECK_GE(num_nodes_, NodeIndexType(1));
1517 for (NodeIndexType i = num_nodes_ - NodeIndexType(1);
i > NodeIndexType(0);
1519 start_[
i] = start_[
i - NodeIndexType(1)];
1521 start_[NodeIndexType(0)] = ArcIndexType(0);
1524 for (
const NodeIndexType node : Base::AllNodes()) {
1525 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1533 OutgoingOrOppositeIncoming);
1535template <
typename NodeIndexType,
typename ArcIndexType>
1537 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1539 NodeIndexType node)
const {
1548template <
typename NodeIndexType,
typename ArcIndexType>
1550 NodeIndexType node)
const {
1551 ArcIndexType degree(0);
1552 for (
auto arc ABSL_ATTRIBUTE_UNUSED :
OutgoingArcs(node)) ++degree;
1556template <
typename NodeIndexType,
typename ArcIndexType>
1558 NodeIndexType node)
const {
1559 ArcIndexType degree(0);
1564template <
typename NodeIndexType,
typename ArcIndexType>
1566 ArcIndexType arc)
const {
1571template <
typename NodeIndexType,
typename ArcIndexType>
1573 ArcIndexType arc)
const {
1578template <
typename NodeIndexType,
typename ArcIndexType>
1580 ArcIndexType arc)
const {
1584template <
typename NodeIndexType,
typename ArcIndexType>
1586 NodeIndexType bound) {
1588 if (bound <= num_nodes_)
return;
1589 start_.reserve(bound);
1590 reverse_start_.reserve(bound);
1593template <
typename NodeIndexType,
typename ArcIndexType>
1595 ArcIndexType bound) {
1597 if (bound <= num_arcs_)
return;
1598 head_.reserve(bound);
1599 next_.reserve(bound);
1602template <
typename NodeIndexType,
typename ArcIndexType>
1604 NodeIndexType node) {
1605 if (node < num_nodes_)
return;
1606 DCHECK(!const_capacities_ || node < node_capacity_);
1607 num_nodes_ = node + NodeIndexType(1);
1612template <
typename NodeIndexType,
typename ArcIndexType>
1614 NodeIndexType tail, NodeIndexType head) {
1615 DCHECK_GE(tail, NodeIndexType(0));
1616 DCHECK_GE(head, NodeIndexType(0));
1617 AddNode(tail > head ? tail : head);
1618 head_.grow(tail, head);
1619 next_.grow(reverse_start_[head], start_[tail]);
1620 start_[tail] = num_arcs_;
1621 reverse_start_[head] = ~num_arcs_;
1622 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1626template <
typename NodeIndexType,
typename ArcIndexType>
1628 std::vector<ArcIndexType>* permutation) {
1629 if (permutation !=
nullptr) {
1630 permutation->clear();
1634template <
typename NodeIndexType,
typename ArcIndexType>
1635class ReverseArcListGraph<NodeIndexType,
1636 ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
1640 : graph_(&
graph), index_(
graph.reverse_start_[node]), node_(node) {
1641 DCHECK(
graph.IsNodeValid(node));
1645 NodeIndexType node, ArcIndexType arc)
1646 : graph_(&
graph), index_(arc), node_(node) {
1647 DCHECK(
graph.IsNodeValid(node));
1652 ArcIndexType Index()
const {
return index_; }
1655 if (index_ < ArcIndexType(0)) {
1656 index_ = graph_->next_[index_];
1658 index_ = graph_->start_[node_];
1661 index_ = graph_->next_[index_];
1669 ArcIndexType index_;
1670 NodeIndexType node_;
1676 OutgoingOrOppositeIncoming);
1678template <
typename NodeIndexType,
typename ArcIndexType>
1680 NodeIndexType node)
const {
1681 return DirectArcLimit(node) - start_[node];
1684template <
typename NodeIndexType,
typename ArcIndexType>
1686 NodeIndexType node)
const {
1687 return ReverseArcLimit(node) - reverse_start_[node];
1690template <
typename NodeIndexType,
typename ArcIndexType>
1691absl::Span<const NodeIndexType>
1693 NodeIndexType node)
const {
1694 return absl::Span<const NodeIndexType>(
1695 head_.data() +
static_cast<size_t>(start_[node]),
1696 static_cast<size_t>(DirectArcLimit(node) - start_[node]));
1699template <
typename NodeIndexType,
typename ArcIndexType>
1701 ArcIndexType arc)
const {
1704 return opposite_[arc];
1707template <
typename NodeIndexType,
typename ArcIndexType>
1709 ArcIndexType arc)
const {
1715template <
typename NodeIndexType,
typename ArcIndexType>
1717 ArcIndexType arc)
const {
1722template <
typename NodeIndexType,
typename ArcIndexType>
1724 ArcIndexType bound) {
1726 if (bound <= num_arcs_)
return;
1727 head_.reserve(bound);
1730template <
typename NodeIndexType,
typename ArcIndexType>
1732 NodeIndexType node) {
1733 if (node < num_nodes_)
return;
1734 DCHECK(!const_capacities_ || node < node_capacity_);
1735 num_nodes_ = node + NodeIndexType(1);
1738template <
typename NodeIndexType,
typename ArcIndexType>
1740 NodeIndexType tail, NodeIndexType head) {
1741 DCHECK_GE(tail, NodeIndexType(0));
1742 DCHECK_GE(head, NodeIndexType(0));
1743 AddNode(tail > head ? tail : head);
1747 head_.grow(head, tail);
1748 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1752template <
typename NodeIndexType,
typename ArcIndexType>
1754 std::vector<ArcIndexType>* permutation) {
1756 if (is_built_)
return;
1758 node_capacity_ = num_nodes_;
1759 arc_capacity_ = num_arcs_;
1761 if (num_nodes_ == NodeIndexType(0)) {
1764 this->BuildStartAndForwardHead(&head_, &start_, permutation);
1767 reverse_start_.assign(num_nodes_ + NodeIndexType(1), ArcIndexType(0));
1768 for (ArcIndexType i(0); i < num_arcs_; ++i) {
1769 reverse_start_[head_[i]]++;
1771 this->ComputeCumulativeSum(&reverse_start_);
1775 opposite_.reserve(num_arcs_);
1776 for (ArcIndexType i(0); i < num_arcs_; ++i) {
1778 opposite_.grow(ArcIndexType(0), reverse_start_[head_[i]]++ - num_arcs_);
1782 DCHECK_GE(num_nodes_, NodeIndexType(1));
1783 reverse_start_[num_nodes_] = ArcIndexType(0);
1784 for (NodeIndexType i = num_nodes_ - NodeIndexType(1);
i > NodeIndexType(0);
1786 reverse_start_[
i] = reverse_start_[
i - NodeIndexType(1)] - num_arcs_;
1788 if (num_nodes_ != NodeIndexType(0)) {
1789 reverse_start_[NodeIndexType(0)] = -num_arcs_;
1793 for (ArcIndexType
i(0);
i < num_arcs_; ++
i) {
1794 opposite_[opposite_[
i]] =
i;
1796 for (
const NodeIndexType node : Base::AllNodes()) {
1797 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1798 head_[opposite_[arc]] = node;
1803template <
typename NodeIndexType,
typename ArcIndexType>
1805 NodeIndexType, ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
1810 first_limit_(
graph.ReverseArcLimit(node)),
1811 next_start_(
graph.start_[node]),
1812 limit_(
graph.DirectArcLimit(node)) {
1813 if (index_ == first_limit_) index_ = next_start_;
1814 DCHECK(
graph.IsNodeValid(node));
1815 DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1818 NodeIndexType node, ArcIndexType arc)
1819 : first_limit_(
graph.ReverseArcLimit(node)),
1820 next_start_(
graph.start_[node]),
1821 limit_(
graph.DirectArcLimit(node)) {
1823 DCHECK(
graph.IsNodeValid(node));
1824 DCHECK((index_ >=
graph.reverse_start_[node] && index_ < first_limit_) ||
1825 (index_ >= next_start_));
1828 ArcIndexType Index()
const {
return index_; }
1829 bool Ok()
const {
return index_ != limit_; }
1833 if (index_ == first_limit_) {
1834 index_ = next_start_;
1841 ArcIndexType index_;
1842 const ArcIndexType first_limit_;
1843 const ArcIndexType next_start_;
1844 const ArcIndexType limit_;
1850template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
1871 NodeIndexType
Head(ArcIndexType arc)
const;
1872 NodeIndexType
Tail(ArcIndexType arc)
const;
1876 ArcIndexType from)
const;
1879 const ::util::math::ConstantDivisor<std::make_unsigned_t<ArcIndexType>>
1883template <
typename NodeIndexType,
typename ArcIndexType>
1885 ArcIndexType arc)
const {
1890template <
typename NodeIndexType,
typename ArcIndexType>
1892 ArcIndexType arc)
const {
1897template <
typename NodeIndexType,
typename ArcIndexType>
1899 NodeIndexType node)
const {
1903template <
typename NodeIndexType,
typename ArcIndexType>
1906 NodeIndexType node)
const {
1907 DCHECK_LT(node, num_nodes_);
1909 static_cast<ArcIndexType
>(num_nodes_) * node,
1910 static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
1913template <
typename NodeIndexType,
typename ArcIndexType>
1916 NodeIndexType node, ArcIndexType from)
const {
1917 DCHECK_LT(node, num_nodes_);
1919 from,
static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
1922template <
typename NodeIndexType,
typename ArcIndexType>
1925 NodeIndexType node)
const {
1926 DCHECK_LT(node, num_nodes_);
1933template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
1935 :
public BaseGraph<NodeIndexType, ArcIndexType, false> {
1949 : left_nodes_(left_nodes),
1950 right_nodes_(right_nodes),
1954 divisor_(right_nodes > 1 ? right_nodes : 2) {
1955 this->
Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
1957 num_nodes_ = left_nodes + right_nodes;
1958 num_arcs_ = left_nodes * right_nodes;
1964 ArcIndexType
GetArc(NodeIndexType left_node, NodeIndexType right_node)
const;
1966 NodeIndexType
Head(ArcIndexType arc)
const;
1967 NodeIndexType
Tail(ArcIndexType arc)
const;
1968 ArcIndexType
OutDegree(NodeIndexType node)
const;
1971 ArcIndexType from)
const;
1975 const NodeIndexType left_nodes_;
1976 const NodeIndexType right_nodes_;
1978 const ::util::math::ConstantDivisor<std::make_unsigned_t<ArcIndexType>>
1982template <
typename NodeIndexType,
typename ArcIndexType>
1984 NodeIndexType left_node, NodeIndexType right_node)
const {
1985 DCHECK_LT(left_node, left_nodes_);
1986 DCHECK_GE(right_node, left_nodes_);
1987 DCHECK_LT(right_node, num_nodes_);
1988 return left_node *
static_cast<ArcIndexType
>(right_nodes_) +
1989 (right_node - left_nodes_);
1992template <
typename NodeIndexType,
typename ArcIndexType>
1994 ArcIndexType arc)
const {
1997 return right_nodes_ > 1 ? left_nodes_ + arc % divisor_ : left_nodes_;
2000template <
typename NodeIndexType,
typename ArcIndexType>
2002 ArcIndexType arc)
const {
2005 return right_nodes_ > 1 ? arc / divisor_ : arc;
2008template <
typename NodeIndexType,
typename ArcIndexType>
2010 NodeIndexType node)
const {
2011 return (node < left_nodes_) ? right_nodes_ : 0;
2014template <
typename NodeIndexType,
typename ArcIndexType>
2017 NodeIndexType node)
const {
2018 if (node < left_nodes_) {
2020 static_cast<ArcIndexType
>(right_nodes_) * node,
2021 static_cast<ArcIndexType
>(right_nodes_) * (node + 1));
2027template <
typename NodeIndexType,
typename ArcIndexType>
2030 NodeIndexType node, ArcIndexType from)
const {
2031 if (node < left_nodes_) {
2033 from,
static_cast<ArcIndexType
>(right_nodes_) * (node + 1));
2039template <
typename NodeIndexType,
typename ArcIndexType>
2042 NodeIndexType node)
const {
2043 if (node < left_nodes_) {
2055#undef DEFINE_RANGE_BASED_ARC_ITERATION
2056#undef DEFINE_STL_ITERATOR_FUNCTIONS
const ::util::math::ConstantDivisor< std::make_unsigned_t< int64_t > > divisor_
ArcPropertyIterator operator++(int)
ArcPropertyIterator()=default
ArcPropertyIterator & operator++()
std::ptrdiff_t difference_type
friend bool operator!=(const ArcPropertyIterator &l, const ArcPropertyIterator &r)
friend bool operator==(const ArcPropertyIterator &l, const ArcPropertyIterator &r)
value_type operator*() const
ArcPropertyIterator(const Graph &graph, ArcIterator arc_it)
NodeIndexType num_nodes() const
bool IsArcValid(ArcIndexType arc) const
NodeIndexType node_capacity() const
Capacity reserved for future nodes, always >= num_nodes_.
static constexpr NodeIndexType kNilNode
static constexpr ArcIndexType kNilArc
ArcIndexType arc_capacity() const
Capacity reserved for future arcs, always >= num_arcs_.
static constexpr bool kHasNegativeReverseArcs
IntegerRange< ArcIndex > AllForwardArcs() const
ArcIndexType arc_capacity_
BaseGraph(const BaseGraph &)=default
virtual void ReserveNodes(NodeIndexType bound)
NodeIndexType size() const
void ComputeCumulativeSum(internal::Vector< NodeIndexType, ArcIndexType > *v)
Functions commented when defined because they are implementation details.
virtual void ReserveArcs(ArcIndexType bound)
void BuildStartAndForwardHead(internal::SVector< ArcIndexType, NodeIndexType > *head, internal::Vector< NodeIndexType, ArcIndexType > *start, std::vector< ArcIndexType > *permutation)
void Reserve(NodeIndexType node_capacity, ArcIndexType arc_capacity)
NodeIndexType node_capacity_
BaseGraph & operator=(const BaseGraph &)=default
ArcIndexType num_arcs() const
Returns the number of valid arcs in the graph.
IntegerRange< NodeIndex > AllNodes() const
BaseGraph implementation -------------------------------------------------—.
virtual ~BaseGraph()=default
bool IsNodeValid(NodeIndexType node) const
Returns true if the given node is a valid node of the graph.
ArcIndexType GetArc(NodeIndexType left_node, NodeIndexType right_node) const
NodeIndexType Tail(ArcIndexType arc) const
CompleteBipartiteGraph(NodeIndexType left_nodes, NodeIndexType right_nodes)
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
const ::util::math::ConstantDivisor< std::make_unsigned_t< ArcIndexType > > divisor_
ArcIndexType OutDegree(NodeIndexType node) const
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
CompleteGraph(NodeIndexType num_nodes)
Builds a complete graph with num_nodes nodes.
NodeIndexType Head(ArcIndexType arc) const
ListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
bool IsArcValid(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
void AddNode(NodeIndexType node)
ArcHeadIterator< ListGraph, OutgoingArcIterator > OutgoingHeadIterator
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Tail(ArcIndexType arc) const
Returns the tail/head of a valid arc.
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ArcIndexType OutDegree(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
void ReserveNodes(NodeIndexType bound) override
ChasingIterator< ArcIndexType, Base::kNilArc, OutgoingArcIteratorTag > OutgoingArcIterator
void ReserveArcs(ArcIndexType bound) override
OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
bool IsArcValid(ArcIndexType arc) const
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ChasingIterator< ArcIndexType, Base::kNilArc, OutgoingArcIteratorTag > OutgoingArcIterator
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
void ReserveArcs(ArcIndexType bound) override
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ReverseArcListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcOppositeArcIterator< ReverseArcListGraph, OppositeIncomingArcIterator > IncomingArcIterator
ArcIndexType OppositeArc(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
ChasingIterator< ArcIndexType, Base::kNilArc, OppositeIncomingArcIteratorTag > OppositeIncomingArcIterator
ArcIndexType OutDegree(NodeIndexType node) const
ReverseArcListGraph<>::OutDegree() and InDegree() work in O(degree).
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void ReserveNodes(NodeIndexType bound) override
ArcHeadIterator< ReverseArcListGraph, OutgoingArcIterator > OutgoingHeadIterator
ArcIndexType InDegree(NodeIndexType node) const
OutgoingOrOppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
IntegerRangeIterator< ArcIndexType > OppositeIncomingArcIterator
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
bool IsArcValid(ArcIndexType arc) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OppositeArc(ArcIndexType arc) const
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
void Build(std::vector< ArcIndexType > *permutation)
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
void ReserveArcs(ArcIndexType bound) override
ArcIndexType OutDegree(NodeIndexType node) const
ReverseArcStaticGraph<>::OutDegree() and InDegree() work in O(1).
ArcIndexType InDegree(NodeIndexType node) const
IntegerRangeIterator< ArcIndexType > OutgoingArcIterator
ReverseArcStaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
ArcOppositeArcIterator< ReverseArcStaticGraph, OppositeIncomingArcIterator > IncomingArcIterator
IntegerRange< ArcIndexType > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
IntegerRange< ArcIndexType > OppositeIncomingArcs(NodeIndexType node) const
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
static StaticGraph FromArcs(NodeIndexType num_nodes, const ArcContainer &arcs)
Shortcut to directly create a finalized graph, i.e. Build() is called.
bool IsArcValid(ArcIndexType arc) const
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
void ReserveArcs(ArcIndexType bound) override
void ReserveNodes(NodeIndexType bound) override
void AddNode(NodeIndexType node)
StaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
void grow(const T &left=T(), const T &right=T())
void swap(SVector< IndexT, T > &x) noexcept
SVector(const SVector &other)
Copy constructor and assignment operator.
SVector & operator=(const SVector &other)
SVector & operator=(SVector &&other) noexcept
SVector(SVector &&other) noexcept
Move constructor and move assignment operator.
const T & operator[](IndexT n) const
Allows indexing into a vector with an edge or node index.
void reserve(IndexT index)
T & operator[](IndexT index)
void assign(IndexT index, const T &value)
const T & operator[](IndexT index) const
void resize(IndexT index, const T &value)
#define DEFINE_RANGE_BASED_ARC_ITERATION(c, t)
#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name)
dual_gradient T(y - `dual_solution`) class DiagonalTrustRegionProblemFromQp
constexpr bool IsSigned()
A collections of i/o utilities for the Graph classes in ./graph.h.
ArcPropertyIterator< Graph, ArcIterator, typename Graph::ArcIndex, &Graph::OppositeArc > ArcOppositeArcIterator
An iterator that iterates on the opposite arcs of another iterator.
ArcPropertyIterator< Graph, ArcIterator, typename Graph::NodeIndex, &Graph::Head > ArcHeadIterator
An iterator that iterates on the heads of the arcs of another iterator.
void Permute(const IntVector &permutation, Array *array_to_permute)
ListGraph Graph
Defining the simplest Graph interface as Graph for convenience.
trees with all degrees equal to
std::decay_t< decltype(*(std::declval< NeighborRangeType >().begin()))> NodeIndex
The index type for nodes of the graph.
Do not use directly. See instead the arc iteration functions below.