Google OR-Tools: ortools/graph/graph.h Source File
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>
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;
1022 ArcIndexType OutDegree(NodeIndexType node) const;
1023 ArcIndexType InDegree(NodeIndexType node) const;
1026 class OutgoingOrOppositeIncomingArcIterator;
1037 ArcIndexType from) const {
1038 DCHECK_GE(from, start_[node]);
1049 NodeIndexType node, ArcIndexType from) const {
1050 DCHECK_GE(from, reverse_start_[node]);
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;
1089 bool IsBuilt() const final { return is_built_; }
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>
1193 DCHECK_EQ(v->size(), num_nodes_ + NodeIndexType(1));
1195 for (NodeIndexType i(0); i < num_nodes_; ++i) {
1196 ArcIndexType temp = (*v)[i];
1201 (*v)[num_nodes_] = sum;
1209template <typename Impl, typename NodeIndexType, typename ArcIndexType,
1210 bool HasNegativeReverseArcs>
1215 std::vector<ArcIndexType>* permutation) {
1219 start->assign(num_nodes_ + NodeIndexType(1), ArcIndexType(0));
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;
1234 if (!permutation_needed) {
1235 for (ArcIndexType i(0); i < num_arcs_; ++i) {
1236 (*head)[i] = (*head)[~i];
1238 if (permutation != nullptr) {
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]]++;
1252 DCHECK_GE(num_nodes_, NodeIndexType(1));
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];
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), \
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++() { \
1322template <typename NodeIndexType, typename ArcIndexType>
1324 ArcIndexType arc) const {
1331 ArcIndexType arc) const {
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);
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;
1373template <typename NodeIndexType, typename ArcIndexType>
1375 Base::ReserveArcs(bound);
1376 if (bound <= num_arcs_) return;
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>
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;
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);
1441 if (tail >= last_tail_seen_) {
1450 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1454template <typename NodeIndexType, typename ArcIndexType>
1456 ArcIndexType arc) const {
1463 ArcIndexType arc) const {
1480template <typename NodeIndexType, typename ArcIndexType>
1482 std::vector<ArcIndexType>* permutation) {
1483 DCHECK(!is_built_);
1486 node_capacity_ = num_nodes_;
1487 arc_capacity_ = num_arcs_;
1489 if (num_nodes_ == NodeIndexType(0)) {
1495 if (permutation != nullptr) {
1498 this->ComputeCumulativeSum(&start_);
1504 start_.assign(num_nodes_ + NodeIndexType(1), ArcIndexType(0));
1505 for (ArcIndexType i(0); i < num_arcs_; ++i) {
1506 start_[tail_[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) {
1529 DCHECK_GE(num_nodes_, NodeIndexType(1));
1530 for (NodeIndexType i = num_nodes_ - NodeIndexType(1); i > NodeIndexType(0);
1531 --i) {
1532 start_[i] = start_[i - NodeIndexType(1)];
1534 start_[NodeIndexType(0)] = ArcIndexType(0);
1537 for (const NodeIndexType node : Base::AllNodes()) {
1546 OutgoingOrOppositeIncoming);
1548template <typename NodeIndexType, typename ArcIndexType>
1550 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1552 NodeIndexType node) const {
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 {
1586 ArcIndexType arc) const {
1593 ArcIndexType arc) const {
1601 if (bound <= num_nodes_) return;
1603 reverse_start_.reserve(bound);
1606template <typename NodeIndexType, typename ArcIndexType>
1618 if (node < num_nodes_) return;
1619 DCHECK(!const_capacities_ || node < node_capacity_);
1620 num_nodes_ = node + NodeIndexType(1);
1622 reverse_start_.resize(num_nodes_, Base::kNilArc);
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);
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>
1645 : graph_(&graph), index_(graph.reverse_start_[node]), node_(node) {
1646 DCHECK(graph.IsNodeValid(node));
1651 : graph_(&graph), index_(arc), node_(node) {
1652 DCHECK(graph.IsNodeValid(node));
1656 bool Ok() const { return index_ != Base::kNilArc; }
1657 ArcIndexType Index() const { return index_; }
1660 if (index_ < ArcIndexType(0)) {
1661 index_ = graph_->next_[index_];
1663 index_ = graph_->start_[node_];
1686 return DirectArcLimit(node) - start_[node];
1689template <typename NodeIndexType, typename ArcIndexType>
1692 return ReverseArcLimit(node) - reverse_start_[node];
1695template <typename NodeIndexType, typename ArcIndexType>
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>
1707 DCHECK(is_built_);
1712template <typename NodeIndexType, typename ArcIndexType>
1715 DCHECK(is_built_);
1720template <typename NodeIndexType, typename ArcIndexType>
1738 if (node < num_nodes_) return;
1739 DCHECK(!const_capacities_ || node < node_capacity_);
1740 num_nodes_ = node + NodeIndexType(1);
1743template <typename NodeIndexType, typename ArcIndexType>
1746 DCHECK_GE(tail, NodeIndexType(0));
1747 DCHECK_GE(head, NodeIndexType(0));
1748 AddNode(tail > head ? tail : head);
1753 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1757template <typename NodeIndexType, typename ArcIndexType>
1760 DCHECK(!is_built_);
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);
1790 --i) {
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>
1814 : index_(graph.reverse_start_[node]),
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_));
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_) ||
1834 bool Ok() const { return index_ != limit_; }
1847 const ArcIndexType first_limit_;
1848 const ArcIndexType next_start_;
1858 NodeIndexType, ArcIndexType, false> {
1881 NodeIndexType Tail(ArcIndexType arc) const;
1882 ArcIndexType OutDegree(NodeIndexType node) const;
1885 ArcIndexType from) const;
1888 const ::util::math::ConstantDivisor<std::make_unsigned_t<ArcIndexType>>
1892template <typename NodeIndexType, typename ArcIndexType>
1894 ArcIndexType arc) const {
1901 ArcIndexType arc) const {
1908 NodeIndexType node) const {
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>
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;
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 {
2065}
2067#undef DEFINE_RANGE_BASED_ARC_ITERATION