159#ifndef UTIL_GRAPH_GRAPH_H_
160#define UTIL_GRAPH_GRAPH_H_
170#include <type_traits>
173#include "absl/base/attributes.h"
174#include "absl/debugging/leak_check.h"
175#include "absl/log/check.h"
176#include "absl/types/span.h"
185template <
typename IndexT,
typename T>
188template <
typename IndexT,
typename T>
204template <
typename Impl,
typename NodeIndexType = int32_t,
205 typename ArcIndexType = int32_t,
bool HasNegativeReverseArcs =
false>
243 return node >= NodeIndexType(0) && node <
num_nodes_;
249 return (HasNegativeReverseArcs ? -
num_arcs_ : ArcIndexType(0)) <= arc &&
288 static_assert(std::numeric_limits<NodeIndexType>::is_specialized);
290 std::numeric_limits<NodeIndexType>::max();
291 static_assert(std::numeric_limits<ArcIndexType>::is_specialized);
293 std::numeric_limits<ArcIndexType>::max();
304 virtual void Build(std::vector<ArcIndexType>* permutation) {
305 if (permutation !=
nullptr) permutation->clear();
316 std::vector<ArcIndexType>* permutation);
329template <
typename Graph,
typename ArcIterator,
typename PropertyT,
332#
if __cplusplus < 201703L
333 : public
std::iterator<
std::input_iterator_tag, PropertyT>
341#if __cplusplus >= 201703L && __cplusplus < 202002L
342 using iterator_category = std::input_iterator_tag;
343 using pointer = PropertyT*;
344 using reference = PropertyT&;
350 : arc_it_(
std::move(arc_it)), graph_(&
graph) {}
366 return l.arc_it_ == r.arc_it_;
380template <
typename Graph,
typename ArcIterator>
386template <
typename Graph,
typename ArcIterator>
389 &Graph::OppositeArc>;
395template <
typename ArcIndexType>
397 return ArcIndexType(-1) < ArcIndexType(0);
401template <
typename IndexT,
typename T>
405 return std::vector<T>::operator[](
static_cast<size_t>(index));
408 return std::vector<T>::operator[](
static_cast<size_t>(index));
411 void resize(IndexT index,
const T& value) {
412 return std::vector<T>::resize(
static_cast<size_t>(index), value);
416 return std::vector<T>::reserve(
static_cast<size_t>(index));
419 void assign(IndexT index,
const T& value) {
420 return std::vector<T>::assign(
static_cast<size_t>(index), value);
423 IndexT
size()
const {
return IndexT(std::vector<T>::size()); }
440template <
typename IndexT,
typename T>
445 SVector() : base_(nullptr), size_(0), capacity_(0) {}
452 if (capacity_ < other.size_) {
456 capacity_ = other.size_;
457 base_ = Allocate(capacity_);
458 CHECK(base_ !=
nullptr);
459 base_ +=
static_cast<ptrdiff_t
>(capacity_);
465 CopyInternal(other, std::is_integral<T>());
482 DCHECK_GE(n, -size_);
483 return base_[
static_cast<ptrdiff_t
>(n)];
488 DCHECK_GE(n, -size_);
489 return base_[
static_cast<ptrdiff_t
>(n)];
494 for (IndexT i = -n; i < -size_; ++i) {
495 new (base_ +
static_cast<ptrdiff_t
>(i)) T();
497 for (IndexT i = size_; i < n; ++i) {
498 new (base_ +
static_cast<ptrdiff_t
>(i)) T();
500 for (IndexT i = -size_; i < -n; ++i) {
501 base_[
static_cast<ptrdiff_t
>(i)].~T();
503 for (IndexT i = n; i < size_; ++i) {
504 base_[
static_cast<ptrdiff_t
>(i)].~T();
511 T*
data()
const {
return base_; }
513 const T*
begin()
const {
return base_; }
514 const T*
end()
const {
return base_ +
static_cast<ptrdiff_t
>(size_); }
517 std::swap(base_, x.base_);
518 std::swap(size_, x.size_);
519 std::swap(capacity_, x.capacity_);
523 DCHECK_GE(n, IndexT(0));
526 const IndexT new_capacity = std::min(n,
max_size());
527 T* new_storage = Allocate(new_capacity);
528 CHECK(new_storage !=
nullptr);
529 T* new_base = new_storage +
static_cast<ptrdiff_t
>(new_capacity);
532 for (ptrdiff_t i =
static_cast<ptrdiff_t
>(-size_);
533 i < static_cast<ptrdiff_t>(size_); ++i) {
534 new (new_base + i) T(std::move(base_[i]));
536 IndexT saved_size = size_;
540 capacity_ = new_capacity;
546 void grow(
const T& left = T(),
const T& right = T()) {
547 if (size_ == capacity_) {
552 reserve(NewCapacity(IndexT(1)));
553 new (base_ +
static_cast<ptrdiff_t
>(size_)) T(right_copy);
554 new (base_ -
static_cast<ptrdiff_t
>(size_) - 1) T(left_copy);
557 new (base_ +
static_cast<ptrdiff_t
>(size_)) T(right);
558 new (base_ -
static_cast<ptrdiff_t
>(size_) - 1) T(left);
563 IndexT
size()
const {
return size_; }
567 IndexT
max_size()
const {
return std::numeric_limits<IndexT>::max(); }
570 if (base_ ==
nullptr)
return;
572 if (capacity_ > IndexT(0)) {
573 free(base_ -
static_cast<ptrdiff_t
>(capacity_));
575 capacity_ = IndexT(0);
583 void CopyInternal(
const SVector& other, std::true_type) {
584 std::memcpy(base_ -
static_cast<ptrdiff_t
>(other.size_),
585 other.base_ -
static_cast<ptrdiff_t
>(other.size_),
586 2LL *
static_cast<ptrdiff_t
>(other.size_) *
sizeof(T));
591 void CopyInternal(
const SVector& other, std::false_type) {
592 for (IndexT i = -size_; i < size_; ++i) {
593 new (base_ +
static_cast<ptrdiff_t
>(i))
594 T(other.base_[
static_cast<ptrdiff_t
>(i)]);
599 return absl::IgnoreLeak(
static_cast<T*
>(
603 IndexT NewCapacity(IndexT delta) {
605 double candidate = 1.3 *
static_cast<size_t>(capacity_);
606 if (candidate >
static_cast<size_t>(
max_size())) {
607 candidate =
static_cast<size_t>(
max_size());
609 IndexT new_capacity(candidate);
610 if (new_capacity > capacity_ + delta) {
613 return capacity_ + delta;
630template <
typename Graph>
634 using NeighborRangeType = std::decay_t<
635 decltype(std::declval<Graph>()[std::declval<Graph>().size()])>;
640 std::decay_t<decltype(*(std::declval<NeighborRangeType>().begin()))>;
661template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
663 NodeIndexType, ArcIndexType, false> {
683 if (num_nodes > NodeIndexType(0)) {
684 this->
AddNode(num_nodes - NodeIndexType(1));
691 void AddNode(NodeIndexType node);
699 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
702 NodeIndexType
Tail(ArcIndexType arc)
const;
703 NodeIndexType
Head(ArcIndexType arc)
const;
716 ArcIndexType
OutDegree(NodeIndexType node)
const;
731 NodeIndexType node, ArcIndexType from)
const {
734 DCHECK_EQ(
Tail(from), node);
769template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
771 NodeIndexType, ArcIndexType, false> {
783 StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
785 : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
788 if (num_nodes > NodeIndexType(0)) {
789 this->
AddNode(num_nodes - NodeIndexType(1));
794 template <
class ArcContainer>
796 const ArcContainer& arcs);
799 class OutgoingArcIterator;
801 NodeIndexType
Head(ArcIndexType arc)
const;
802 NodeIndexType
Tail(ArcIndexType arc)
const;
803 ArcIndexType
OutDegree(NodeIndexType node)
const;
808 ArcIndexType from)
const {
809 DCHECK_GE(from, start_[node]);
810 const ArcIndexType limit = DirectArcLimit(node);
818 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
822 void AddNode(NodeIndexType node);
823 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
825 void Build(std::vector<ArcIndexType>* permutation)
final;
827 bool IsBuilt() const final {
return is_built_; }
830 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
833 return start_[node + NodeIndexType(1)];
838 NodeIndexType last_tail_seen_;
841 internal::Vector<NodeIndexType, ArcIndexType> start_;
842 internal::Vector<ArcIndexType, NodeIndexType> head_;
843 internal::Vector<ArcIndexType, NodeIndexType> tail_;
852template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
854 :
public BaseGraph<ReverseArcListGraph<NodeIndexType, ArcIndexType>,
855 NodeIndexType, ArcIndexType, true> {
857 "ArcIndexType must be signed");
860 NodeIndexType, ArcIndexType,
true>
874 if (num_nodes > NodeIndexType(0)) {
875 this->
AddNode(num_nodes - NodeIndexType(1));
879 NodeIndexType
Head(ArcIndexType arc)
const;
880 NodeIndexType
Tail(ArcIndexType arc)
const;
917 NodeIndexType node, ArcIndexType from)
const {
920 DCHECK_GE(from, ArcIndexType(0));
921 DCHECK_EQ(
Tail(from), node);
930 NodeIndexType node, ArcIndexType from)
const {
943 NodeIndexType node)
const {
949 NodeIndexType node, ArcIndexType from)
const {
952 DCHECK_LT(from, ArcIndexType(0));
953 DCHECK_EQ(
Tail(from), node);
960 ArcIndexType from)
const;
970 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
988template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
990 :
public BaseGraph<ReverseArcStaticGraph<NodeIndexType, ArcIndexType>,
991 NodeIndexType, ArcIndexType, true> {
993 "ArcIndexType must be signed");
996 NodeIndexType, ArcIndexType,
true>
1008 : is_built_(false) {
1011 if (num_nodes > NodeIndexType(0)) {
1012 this->
AddNode(num_nodes - NodeIndexType(1));
1018 NodeIndexType
Head(ArcIndexType arc)
const;
1019 NodeIndexType
Tail(ArcIndexType arc)
const;
1026 class OutgoingOrOppositeIncomingArcIterator;
1037 ArcIndexType from)
const {
1038 DCHECK_GE(from, start_[node]);
1039 const ArcIndexType limit = DirectArcLimit(node);
1046 ReverseArcLimit(node));
1049 NodeIndexType node, ArcIndexType from)
const {
1050 DCHECK_GE(from, reverse_start_[node]);
1051 const ArcIndexType limit = ReverseArcLimit(node);
1063 NodeIndexType node, ArcIndexType from)
const {
1076 ArcIndexType from)
const;
1081 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
1085 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
1087 void Build(std::vector<ArcIndexType>* permutation)
final;
1092 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
1095 return start_[node + NodeIndexType(1)];
1097 ArcIndexType ReverseArcLimit(NodeIndexType node)
const {
1100 return reverse_start_[node + NodeIndexType(1)];
1106 internal::Vector<NodeIndexType, ArcIndexType> start_;
1109 internal::Vector<NodeIndexType, ArcIndexType> reverse_start_;
1110 internal::SVector<ArcIndexType, NodeIndexType> head_;
1111 internal::SVector<ArcIndexType, ArcIndexType> opposite_;
1124template <
class IntVector,
class Array>
1125void Permute(
const IntVector& permutation, Array* array_to_permute) {
1126 if (permutation.empty()) {
1129 const auto size = permutation.size();
1130 auto& array = *array_to_permute;
1132 typename std::iterator_traits<
decltype(std::begin(array))>::value_type;
1133 std::vector<ElementType> temp(size);
1134 auto array_begin = std::begin(array);
1135 std::copy_n(array_begin, size, temp.begin());
1136 for (
size_t i = 0; i < permutation.size(); ++i) {
1137 *(array_begin +
static_cast<size_t>(permutation[i])) = temp[i];
1143template <
typename Impl,
typename NodeIndexType,
typename ArcIndexType,
1144 bool HasNegativeReverseArcs>
1145IntegerRange<NodeIndexType>
1151template <
typename Impl,
typename NodeIndexType,
typename ArcIndexType,
1152 bool HasNegativeReverseArcs>
1159template <
typename Impl,
typename NodeIndexType,
typename ArcIndexType,
1160 bool HasNegativeReverseArcs>
1161NodeIndexType
BaseGraph<Impl, NodeIndexType, ArcIndexType,
1168template <
typename Impl,
typename NodeIndexType,
typename ArcIndexType,
1169 bool HasNegativeReverseArcs>
1170ArcIndexType
BaseGraph<Impl, NodeIndexType, ArcIndexType,
1176template <
typename Impl,
typename NodeIndexType,
typename ArcIndexType,
1177 bool HasNegativeReverseArcs>
1178void BaseGraph<Impl, NodeIndexType, ArcIndexType,
1189template <
typename Impl,
typename NodeIndexType,
typename ArcIndexType,
1190 bool HasNegativeReverseArcs>
1194 ArcIndexType sum(0);
1195 for (NodeIndexType i(0); i <
num_nodes_; ++i) {
1196 ArcIndexType temp = (*v)[i];
1209template <
typename Impl,
typename NodeIndexType,
typename ArcIndexType,
1210 bool HasNegativeReverseArcs>
1215 std::vector<ArcIndexType>* permutation) {
1220 NodeIndexType last_tail_seen(0);
1221 bool permutation_needed =
false;
1222 for (ArcIndexType i(0); i <
num_arcs_; ++i) {
1223 NodeIndexType tail = (*head)[i];
1224 if (!permutation_needed) {
1225 permutation_needed = tail < last_tail_seen;
1226 last_tail_seen = tail;
1234 if (!permutation_needed) {
1235 for (ArcIndexType i(0); i <
num_arcs_; ++i) {
1236 (*head)[i] = (*head)[~i];
1238 if (permutation !=
nullptr) {
1239 permutation->clear();
1246 std::vector<ArcIndexType> perm(
static_cast<size_t>(
num_arcs_));
1247 for (ArcIndexType i(0); i <
num_arcs_; ++i) {
1248 perm[
static_cast<size_t>(i)] = (*start)[(*head)[i]]++;
1253 for (NodeIndexType i =
num_nodes_ - NodeIndexType(1); i > NodeIndexType(0);
1255 (*start)[i] = (*start)[i - NodeIndexType(1)];
1257 (*start)[NodeIndexType(0)] = ArcIndexType(0);
1261 for (ArcIndexType i(0); i <
num_arcs_; ++i) {
1262 (*head)[perm[
static_cast<size_t>(i)]] = (*head)[~i];
1264 if (permutation !=
nullptr) {
1265 permutation->swap(perm);
1278#define DEFINE_RANGE_BASED_ARC_ITERATION(c, t) \
1279 template <typename NodeIndexType, typename ArcIndexType> \
1280 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1281 c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1282 return BeginEndWrapper<t##ArcIterator>( \
1283 t##ArcIterator(*this, node), \
1284 t##ArcIterator(*this, node, Base::kNilArc)); \
1286 template <typename NodeIndexType, typename ArcIndexType> \
1287 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1288 c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1289 NodeIndexType node, ArcIndexType from) const { \
1290 return BeginEndWrapper<t##ArcIterator>( \
1291 t##ArcIterator(*this, node, from), \
1292 t##ArcIterator(*this, node, Base::kNilArc)); \
1297#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1298 using iterator_category = std::input_iterator_tag; \
1299 using difference_type = ptrdiff_t; \
1300 using pointer = const ArcIndexType*; \
1301 using value_type = ArcIndexType; \
1302 using reference = value_type; \
1303 bool operator!=(const iterator_class_name& other) const { \
1304 return this->index_ != other.index_; \
1306 bool operator==(const iterator_class_name& other) const { \
1307 return this->index_ == other.index_; \
1309 ArcIndexType operator*() const { return this->Index(); } \
1310 iterator_class_name& operator++() { \
1314 iterator_class_name operator++(int) { \
1322template <
typename NodeIndexType,
typename ArcIndexType>
1324 ArcIndexType arc)
const {
1329template <
typename NodeIndexType,
typename ArcIndexType>
1331 ArcIndexType arc)
const {
1336template <
typename NodeIndexType,
typename ArcIndexType>
1338 NodeIndexType node)
const {
1339 ArcIndexType degree(0);
1340 for (
auto arc ABSL_ATTRIBUTE_UNUSED :
OutgoingArcs(node)) ++degree;
1344template <
typename NodeIndexType,
typename ArcIndexType>
1346 if (node < num_nodes_)
return;
1347 DCHECK(!const_capacities_ || node < node_capacity_);
1348 num_nodes_ = node + NodeIndexType(1);
1352template <
typename NodeIndexType,
typename ArcIndexType>
1354 NodeIndexType tail, NodeIndexType head) {
1355 DCHECK_GE(tail, NodeIndexType(0));
1356 DCHECK_GE(head, NodeIndexType(0));
1357 AddNode(tail > head ? tail : head);
1358 head_.push_back(head);
1359 tail_.push_back(tail);
1360 next_.push_back(start_[tail]);
1361 start_[tail] = num_arcs_;
1362 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1366template <
typename NodeIndexType,
typename ArcIndexType>
1368 Base::ReserveNodes(bound);
1369 if (bound <= num_nodes_)
return;
1370 start_.reserve(bound);
1373template <
typename NodeIndexType,
typename ArcIndexType>
1375 Base::ReserveArcs(bound);
1376 if (bound <= num_arcs_)
return;
1377 head_.reserve(bound);
1378 tail_.reserve(bound);
1379 next_.reserve(bound);
1384template <
typename NodeIndexType,
typename ArcIndexType>
1385template <
class ArcContainer>
1388 const ArcContainer& arcs) {
1390 for (
const auto& [from,
to] : arcs) g.AddArc(from,
to);
1395template <
typename NodeIndexType,
typename ArcIndexType>
1396absl::Span<const NodeIndexType>
1398 return absl::Span<const NodeIndexType>(
1399 head_.data() +
static_cast<size_t>(start_[node]),
1400 static_cast<size_t>(DirectArcLimit(node) - start_[node]));
1403template <
typename NodeIndexType,
typename ArcIndexType>
1405 NodeIndexType node)
const {
1406 return DirectArcLimit(node) - start_[node];
1409template <
typename NodeIndexType,
typename ArcIndexType>
1411 NodeIndexType bound) {
1413 if (bound <= num_nodes_)
return;
1414 start_.reserve(bound + NodeIndexType(1));
1417template <
typename NodeIndexType,
typename ArcIndexType>
1419 Base::ReserveArcs(bound);
1420 if (bound <= num_arcs_)
return;
1421 head_.reserve(bound);
1422 tail_.reserve(bound);
1425template <
typename NodeIndexType,
typename ArcIndexType>
1427 if (node < num_nodes_)
return;
1428 DCHECK(!const_capacities_ || node < node_capacity_) << node;
1429 num_nodes_ = node + NodeIndexType(1);
1430 start_.resize(num_nodes_ + NodeIndexType(1), ArcIndexType(0));
1433template <
typename NodeIndexType,
typename ArcIndexType>
1435 NodeIndexType tail, NodeIndexType head) {
1436 DCHECK_GE(tail, NodeIndexType(0));
1437 DCHECK_GE(head, NodeIndexType(0));
1439 AddNode(tail > head ? tail : head);
1440 if (arc_in_order_) {
1441 if (tail >= last_tail_seen_) {
1443 last_tail_seen_ = tail;
1445 arc_in_order_ =
false;
1448 tail_.push_back(tail);
1449 head_.push_back(head);
1450 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1454template <
typename NodeIndexType,
typename ArcIndexType>
1456 ArcIndexType arc)
const {
1461template <
typename NodeIndexType,
typename ArcIndexType>
1463 ArcIndexType arc)
const {
1480template <
typename NodeIndexType,
typename ArcIndexType>
1482 std::vector<ArcIndexType>* permutation) {
1484 if (is_built_)
return;
1486 node_capacity_ = num_nodes_;
1487 arc_capacity_ = num_arcs_;
1489 if (num_nodes_ == NodeIndexType(0)) {
1494 if (arc_in_order_) {
1495 if (permutation !=
nullptr) {
1496 permutation->clear();
1498 this->ComputeCumulativeSum(&start_);
1504 start_.assign(num_nodes_ + NodeIndexType(1), ArcIndexType(0));
1505 for (ArcIndexType
i(0);
i < num_arcs_; ++
i) {
1508 this->ComputeCumulativeSum(&start_);
1512 std::vector<ArcIndexType> perm(
static_cast<size_t>(num_arcs_));
1513 for (ArcIndexType
i(0);
i < num_arcs_; ++
i) {
1514 perm[
static_cast<size_t>(
i)] = start_[tail_[i]]++;
1518 CHECK_EQ(tail_.size(), num_arcs_);
1520 for (ArcIndexType
i(0);
i < num_arcs_; ++
i) {
1521 head_[perm[
static_cast<size_t>(
i)]] = tail_[i];
1524 if (permutation !=
nullptr) {
1525 permutation->swap(perm);
1529 DCHECK_GE(num_nodes_, NodeIndexType(1));
1530 for (NodeIndexType i = num_nodes_ - NodeIndexType(1);
i > NodeIndexType(0);
1532 start_[
i] = start_[
i - NodeIndexType(1)];
1534 start_[NodeIndexType(0)] = ArcIndexType(0);
1537 for (
const NodeIndexType node : Base::AllNodes()) {
1538 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1546 OutgoingOrOppositeIncoming);
1548template <
typename NodeIndexType,
typename ArcIndexType>
1550 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1552 NodeIndexType node)
const {
1561template <
typename NodeIndexType,
typename ArcIndexType>
1563 NodeIndexType node)
const {
1564 ArcIndexType degree(0);
1565 for (
auto arc ABSL_ATTRIBUTE_UNUSED :
OutgoingArcs(node)) ++degree;
1569template <
typename NodeIndexType,
typename ArcIndexType>
1571 NodeIndexType node)
const {
1572 ArcIndexType degree(0);
1577template <
typename NodeIndexType,
typename ArcIndexType>
1579 ArcIndexType arc)
const {
1584template <
typename NodeIndexType,
typename ArcIndexType>
1586 ArcIndexType arc)
const {
1591template <
typename NodeIndexType,
typename ArcIndexType>
1593 ArcIndexType arc)
const {
1597template <
typename NodeIndexType,
typename ArcIndexType>
1599 NodeIndexType bound) {
1601 if (bound <= num_nodes_)
return;
1602 start_.reserve(bound);
1603 reverse_start_.reserve(bound);
1606template <
typename NodeIndexType,
typename ArcIndexType>
1608 ArcIndexType bound) {
1610 if (bound <= num_arcs_)
return;
1611 head_.reserve(bound);
1612 next_.reserve(bound);
1615template <
typename NodeIndexType,
typename ArcIndexType>
1617 NodeIndexType node) {
1618 if (node < num_nodes_)
return;
1619 DCHECK(!const_capacities_ || node < node_capacity_);
1620 num_nodes_ = node + NodeIndexType(1);
1625template <
typename NodeIndexType,
typename ArcIndexType>
1627 NodeIndexType tail, NodeIndexType head) {
1628 DCHECK_GE(tail, NodeIndexType(0));
1629 DCHECK_GE(head, NodeIndexType(0));
1630 AddNode(tail > head ? tail : head);
1631 head_.grow(tail, head);
1632 next_.grow(reverse_start_[head], start_[tail]);
1633 start_[tail] = num_arcs_;
1634 reverse_start_[head] = ~num_arcs_;
1635 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1639template <
typename NodeIndexType,
typename ArcIndexType>
1641 ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
1645 : graph_(&
graph), index_(
graph.reverse_start_[node]), node_(node) {
1646 DCHECK(
graph.IsNodeValid(node));
1650 NodeIndexType node, ArcIndexType arc)
1651 : graph_(&
graph), index_(arc), node_(node) {
1652 DCHECK(
graph.IsNodeValid(node));
1657 ArcIndexType Index()
const {
return index_; }
1660 if (index_ < ArcIndexType(0)) {
1661 index_ = graph_->next_[index_];
1663 index_ = graph_->start_[node_];
1666 index_ = graph_->next_[index_];
1674 ArcIndexType index_;
1675 NodeIndexType node_;
1681 OutgoingOrOppositeIncoming);
1683template <
typename NodeIndexType,
typename ArcIndexType>
1685 NodeIndexType node)
const {
1686 return DirectArcLimit(node) - start_[node];
1689template <
typename NodeIndexType,
typename ArcIndexType>
1691 NodeIndexType node)
const {
1692 return ReverseArcLimit(node) - reverse_start_[node];
1695template <
typename NodeIndexType,
typename ArcIndexType>
1696absl::Span<const NodeIndexType>
1698 NodeIndexType node)
const {
1699 return absl::Span<const NodeIndexType>(
1700 head_.data() +
static_cast<size_t>(start_[node]),
1701 static_cast<size_t>(DirectArcLimit(node) - start_[node]));
1704template <
typename NodeIndexType,
typename ArcIndexType>
1706 ArcIndexType arc)
const {
1709 return opposite_[arc];
1712template <
typename NodeIndexType,
typename ArcIndexType>
1714 ArcIndexType arc)
const {
1720template <
typename NodeIndexType,
typename ArcIndexType>
1722 ArcIndexType arc)
const {
1727template <
typename NodeIndexType,
typename ArcIndexType>
1729 ArcIndexType bound) {
1731 if (bound <= num_arcs_)
return;
1732 head_.reserve(bound);
1735template <
typename NodeIndexType,
typename ArcIndexType>
1737 NodeIndexType node) {
1738 if (node < num_nodes_)
return;
1739 DCHECK(!const_capacities_ || node < node_capacity_);
1740 num_nodes_ = node + NodeIndexType(1);
1743template <
typename NodeIndexType,
typename ArcIndexType>
1745 NodeIndexType tail, NodeIndexType head) {
1746 DCHECK_GE(tail, NodeIndexType(0));
1747 DCHECK_GE(head, NodeIndexType(0));
1748 AddNode(tail > head ? tail : head);
1752 head_.grow(head, tail);
1753 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1757template <
typename NodeIndexType,
typename ArcIndexType>
1759 std::vector<ArcIndexType>* permutation) {
1761 if (is_built_)
return;
1763 node_capacity_ = num_nodes_;
1764 arc_capacity_ = num_arcs_;
1766 if (num_nodes_ == NodeIndexType(0)) {
1769 this->BuildStartAndForwardHead(&head_, &start_, permutation);
1772 reverse_start_.assign(num_nodes_ + NodeIndexType(1), ArcIndexType(0));
1773 for (ArcIndexType i(0); i < num_arcs_; ++i) {
1774 reverse_start_[head_[i]]++;
1776 this->ComputeCumulativeSum(&reverse_start_);
1780 opposite_.reserve(num_arcs_);
1781 for (ArcIndexType i(0); i < num_arcs_; ++i) {
1783 opposite_.grow(ArcIndexType(0), reverse_start_[head_[i]]++ - num_arcs_);
1787 DCHECK_GE(num_nodes_, NodeIndexType(1));
1788 reverse_start_[num_nodes_] = ArcIndexType(0);
1789 for (NodeIndexType i = num_nodes_ - NodeIndexType(1);
i > NodeIndexType(0);
1791 reverse_start_[
i] = reverse_start_[
i - NodeIndexType(1)] - num_arcs_;
1793 if (num_nodes_ != NodeIndexType(0)) {
1794 reverse_start_[NodeIndexType(0)] = -num_arcs_;
1798 for (ArcIndexType
i(0);
i < num_arcs_; ++
i) {
1799 opposite_[opposite_[
i]] =
i;
1801 for (
const NodeIndexType node : Base::AllNodes()) {
1802 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1803 head_[opposite_[arc]] = node;
1808template <
typename NodeIndexType,
typename ArcIndexType>
1810 NodeIndexType, ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
1815 first_limit_(
graph.ReverseArcLimit(node)),
1816 next_start_(
graph.start_[node]),
1817 limit_(
graph.DirectArcLimit(node)) {
1818 if (index_ == first_limit_) index_ = next_start_;
1819 DCHECK(
graph.IsNodeValid(node));
1820 DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1823 NodeIndexType node, ArcIndexType arc)
1824 : first_limit_(
graph.ReverseArcLimit(node)),
1825 next_start_(
graph.start_[node]),
1826 limit_(
graph.DirectArcLimit(node)) {
1828 DCHECK(
graph.IsNodeValid(node));
1829 DCHECK((index_ >=
graph.reverse_start_[node] && index_ < first_limit_) ||
1830 (index_ >= next_start_));
1833 ArcIndexType Index()
const {
return index_; }
1834 bool Ok()
const {
return index_ != limit_; }
1838 if (index_ == first_limit_) {
1839 index_ = next_start_;
1846 ArcIndexType index_;
1847 const ArcIndexType first_limit_;
1848 const ArcIndexType next_start_;
1849 const ArcIndexType limit_;
1855template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
1857 :
public BaseGraph<CompleteGraph<NodeIndexType, ArcIndexType>,
1858 NodeIndexType, ArcIndexType, false> {
1860 ArcIndexType,
false>
1880 NodeIndexType
Head(ArcIndexType arc)
const;
1881 NodeIndexType
Tail(ArcIndexType arc)
const;
1885 ArcIndexType from)
const;
1888 const ::util::math::ConstantDivisor<std::make_unsigned_t<ArcIndexType>>
1892template <
typename NodeIndexType,
typename ArcIndexType>
1894 ArcIndexType arc)
const {
1899template <
typename NodeIndexType,
typename ArcIndexType>
1901 ArcIndexType arc)
const {
1906template <
typename NodeIndexType,
typename ArcIndexType>
1908 NodeIndexType node)
const {
1912template <
typename NodeIndexType,
typename ArcIndexType>
1915 NodeIndexType node)
const {
1916 DCHECK_LT(node, num_nodes_);
1918 static_cast<ArcIndexType
>(num_nodes_) * node,
1919 static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
1922template <
typename NodeIndexType,
typename ArcIndexType>
1925 NodeIndexType node, ArcIndexType from)
const {
1926 DCHECK_LT(node, num_nodes_);
1928 from,
static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
1931template <
typename NodeIndexType,
typename ArcIndexType>
1934 NodeIndexType node)
const {
1935 DCHECK_LT(node, num_nodes_);
1942template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
1944 :
public BaseGraph<CompleteBipartiteGraph<NodeIndexType, ArcIndexType>,
1945 NodeIndexType, ArcIndexType, false> {
1947 NodeIndexType, ArcIndexType,
false>
1961 : left_nodes_(left_nodes),
1962 right_nodes_(right_nodes),
1966 divisor_(right_nodes > 1 ? right_nodes : 2) {
1967 this->
Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
1969 num_nodes_ = left_nodes + right_nodes;
1970 num_arcs_ = left_nodes * right_nodes;
1976 ArcIndexType
GetArc(NodeIndexType left_node, NodeIndexType right_node)
const;
1978 NodeIndexType
Head(ArcIndexType arc)
const;
1979 NodeIndexType
Tail(ArcIndexType arc)
const;
1980 ArcIndexType
OutDegree(NodeIndexType node)
const;
1983 ArcIndexType from)
const;
1987 const NodeIndexType left_nodes_;
1988 const NodeIndexType right_nodes_;
1990 const ::util::math::ConstantDivisor<std::make_unsigned_t<ArcIndexType>>
1994template <
typename NodeIndexType,
typename ArcIndexType>
1996 NodeIndexType left_node, NodeIndexType right_node)
const {
1997 DCHECK_LT(left_node, left_nodes_);
1998 DCHECK_GE(right_node, left_nodes_);
1999 DCHECK_LT(right_node, num_nodes_);
2000 return left_node *
static_cast<ArcIndexType
>(right_nodes_) +
2001 (right_node - left_nodes_);
2004template <
typename NodeIndexType,
typename ArcIndexType>
2006 ArcIndexType arc)
const {
2009 return right_nodes_ > 1 ? left_nodes_ + arc % divisor_ : left_nodes_;
2012template <
typename NodeIndexType,
typename ArcIndexType>
2014 ArcIndexType arc)
const {
2017 return right_nodes_ > 1 ? arc / divisor_ : arc;
2020template <
typename NodeIndexType,
typename ArcIndexType>
2022 NodeIndexType node)
const {
2023 return (node < left_nodes_) ? right_nodes_ : 0;
2026template <
typename NodeIndexType,
typename ArcIndexType>
2029 NodeIndexType node)
const {
2030 if (node < left_nodes_) {
2032 static_cast<ArcIndexType
>(right_nodes_) * node,
2033 static_cast<ArcIndexType
>(right_nodes_) * (node + 1));
2039template <
typename NodeIndexType,
typename ArcIndexType>
2042 NodeIndexType node, ArcIndexType from)
const {
2043 if (node < left_nodes_) {
2045 from,
static_cast<ArcIndexType
>(right_nodes_) * (node + 1));
2051template <
typename NodeIndexType,
typename ArcIndexType>
2054 NodeIndexType node)
const {
2055 if (node < left_nodes_) {
2067#undef DEFINE_RANGE_BASED_ARC_ITERATION
2068#undef DEFINE_STL_ITERATOR_FUNCTIONS
const ::util::math::ConstantDivisor< std::make_unsigned_t< int64_t > > divisor_
OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
ReverseArcListGraph()=default
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
void ReserveArcs(ArcIndexType bound) override
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ArcIndexType OppositeArc(ArcIndexType arc) const
void AddNode(NodeIndexType node)
NodeIndexType Tail(ArcIndexType arc) const
ArcIndexType OutDegree(NodeIndexType node) const
void ReserveNodes(NodeIndexType bound) override
ArcIndexType InDegree(NodeIndexType node) const
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)
IntegerRange< ArcIndex > AllForwardArcs() const
NodeIndexType num_nodes() const
ArcIndexType num_arcs() const
ArcIndexType arc_capacity() const
void ComputeCumulativeSum(internal::Vector< NodeIndexType, ArcIndexType > *v)
virtual bool IsBuilt() const
BaseGraph & operator=(const BaseGraph &)=default
virtual void Build(std::vector< ArcIndexType > *permutation)
static constexpr ArcIndexType kNilArc
void BuildStartAndForwardHead(internal::SVector< ArcIndexType, NodeIndexType > *head, internal::Vector< NodeIndexType, ArcIndexType > *start, std::vector< ArcIndexType > *permutation)
NodeIndexType size() const
IntegerRange< NodeIndex > AllNodes() const
void Reserve(NodeIndexType node_capacity, ArcIndexType arc_capacity)
virtual void ReserveNodes(NodeIndexType bound)
static constexpr bool kHasNegativeReverseArcs
bool IsNodeValid(NodeIndexType node) const
NodeIndexType node_capacity_
static constexpr NodeIndexType kNilNode
bool IsArcValid(ArcIndexType arc) const
virtual void ReserveArcs(ArcIndexType bound)
NodeIndexType node_capacity() const
BaseGraph(const BaseGraph &)=default
ArcIndexType arc_capacity_
virtual ~BaseGraph()=default
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)
NodeIndexType Head(ArcIndexType arc) const
ListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
void AddNode(NodeIndexType node)
bool IsArcValid(ArcIndexType arc) const
ArcHeadIterator< ListGraph, OutgoingArcIterator > OutgoingHeadIterator
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Tail(ArcIndexType arc) const
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
ReverseArcListGraph()=default
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) 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
bool IsArcValid(ArcIndexType arc) 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
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)
bool IsArcValid(ArcIndexType arc) const
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
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
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
bool IsBuilt() const final
void ReserveArcs(ArcIndexType bound) override
ArcIndexType OutDegree(NodeIndexType node) const
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 Build(std::vector< ArcIndexType > *permutation) final
void AddNode(NodeIndexType node)
IntegerRange< ArcIndexType > OppositeIncomingArcs(NodeIndexType node) const
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
bool IsArcValid(ArcIndexType arc) const
static StaticGraph FromArcs(NodeIndexType num_nodes, const ArcContainer &arcs)
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)
bool IsBuilt() const final
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)
SVector & operator=(const SVector &other)
SVector & operator=(SVector &&other) noexcept
SVector(SVector &&other) noexcept
const T & operator[](IndexT n) const
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()
ArcPropertyIterator< Graph, ArcIterator, typename Graph::ArcIndex, &Graph::OppositeArc > ArcOppositeArcIterator
ArcPropertyIterator< Graph, ArcIterator, typename Graph::NodeIndex, &Graph::Head > ArcHeadIterator
void Permute(const IntVector &permutation, Array *array_to_permute)
trees with all degrees equal to
std::decay_t< decltype(*(std::declval< NeighborRangeType >().begin()))> NodeIndex