From 2caae2985cbcc164289f9a464ab245d5eb14d22d Mon Sep 17 00:00:00 2001 From: Laurent Perron Date: Tue, 25 Oct 2022 20:30:41 +0200 Subject: [PATCH] polish/reindent graph python wrappers and samples --- ortools/graph/connected_components.h | 38 ++++++++++++------- ortools/graph/python/linear_sum_assignment.cc | 1 - ortools/graph/python/min_cost_flow.cc | 4 +- .../assignment_linear_sum_assignment.py | 10 +++-- .../graph/samples/simple_max_flow_program.py | 4 +- .../samples/simple_min_cost_flow_program.py | 4 +- 6 files changed, 37 insertions(+), 24 deletions(-) diff --git a/ortools/graph/connected_components.h b/ortools/graph/connected_components.h index 829d40106d..898a1f16ef 100644 --- a/ortools/graph/connected_components.h +++ b/ortools/graph/connected_components.h @@ -54,6 +54,12 @@ #include "ortools/base/ptr_util.h" namespace util { +// Generic version of GetConnectedComponents() (see below) that supports other +// integer types, e.g. int64_t for huge graphs with more than 2^31 nodes. +template +std::vector GetConnectedComponentsTpl(NodeType num_nodes, + const UndirectedGraph& graph); + // Finds the connected components of the graph, using BFS internally. // Works on any *undirected* graph class whose nodes are dense integers and that // supports the [] operator for adjacency lists: graph[x] must be an integer @@ -71,7 +77,9 @@ namespace util { // GetConnectedComponents(graph); // returns [0, 0, 1, 0, 1, 0]. template std::vector GetConnectedComponents(int num_nodes, - const UndirectedGraph& graph); + const UndirectedGraph& graph) { + return GetConnectedComponentsTpl(num_nodes, graph); +} } // namespace util // NOTE(user): The rest of the functions below should also be in namespace @@ -320,20 +328,23 @@ class ConnectedComponentsFinder { // Implementations of the method templates // ============================================================================= namespace util { -template -std::vector GetConnectedComponents(int num_nodes, - const UndirectedGraph& graph) { - std::vector component_of_node(num_nodes, -1); - std::vector bfs_queue; - int num_components = 0; - for (int src = 0; src < num_nodes; ++src) { - if (component_of_node[src] >= 0) continue; +template +std::vector GetConnectedComponentsTpl(NodeType num_nodes, + const UndirectedGraph& graph) { + // We use 'num_nodes' as special component id meaning 'unknown', because + // it's of the right type, and -1 is tricky to use with unsigned ints. + std::vector component_of_node(num_nodes, num_nodes); + std::vector bfs_queue; + NodeType num_components = 0; + for (NodeType src = 0; src < num_nodes; ++src) { + if (component_of_node[src] != num_nodes) continue; bfs_queue.push_back(src); component_of_node[src] = num_components; - for (int num_visited = 0; num_visited < bfs_queue.size(); ++num_visited) { - const int node = bfs_queue[num_visited]; - for (const int neighbor : graph[node]) { - if (component_of_node[neighbor] >= 0) continue; + for (size_t num_visited = 0; num_visited < bfs_queue.size(); + ++num_visited) { + const NodeType node = bfs_queue[num_visited]; + for (const NodeType neighbor : graph[node]) { + if (component_of_node[neighbor] != num_nodes) continue; component_of_node[neighbor] = num_components; bfs_queue.push_back(neighbor); } @@ -343,6 +354,7 @@ std::vector GetConnectedComponents(int num_nodes, } return component_of_node; } + } // namespace util #endif // UTIL_GRAPH_CONNECTED_COMPONENTS_H_ diff --git a/ortools/graph/python/linear_sum_assignment.cc b/ortools/graph/python/linear_sum_assignment.cc index 2d2b00f200..937963474c 100644 --- a/ortools/graph/python/linear_sum_assignment.cc +++ b/ortools/graph/python/linear_sum_assignment.cc @@ -12,7 +12,6 @@ // limitations under the License. #include "ortools/graph/assignment.h" - #include "pybind11/numpy.h" #include "pybind11/pybind11.h" #include "pybind11/stl.h" diff --git a/ortools/graph/python/min_cost_flow.cc b/ortools/graph/python/min_cost_flow.cc index c8af1581fb..b9dfcd1624 100644 --- a/ortools/graph/python/min_cost_flow.cc +++ b/ortools/graph/python/min_cost_flow.cc @@ -47,8 +47,8 @@ PYBIND11_MODULE(min_cost_flow, m) { smcf.def("optimal_cost", &SimpleMinCostFlow::OptimalCost); smcf.def("maximum_flow", &SimpleMinCostFlow::MaximumFlow); smcf.def("flow", &SimpleMinCostFlow::Flow, arg("arc")); - smcf.def("flows", - pybind11::vectorize(&SimpleMinCostFlow::Flow)); + smcf.def("flows", pybind11::vectorize(&SimpleMinCostFlow::Flow)); + pybind11::enum_(smcf, "Status") .value("BAD_COST_RANGE", MinCostFlowBase::Status::BAD_COST_RANGE) .value("BAD_RESULT", MinCostFlowBase::Status::BAD_RESULT) diff --git a/ortools/graph/samples/assignment_linear_sum_assignment.py b/ortools/graph/samples/assignment_linear_sum_assignment.py index 622903abc2..eb6a822e2d 100755 --- a/ortools/graph/samples/assignment_linear_sum_assignment.py +++ b/ortools/graph/samples/assignment_linear_sum_assignment.py @@ -15,9 +15,9 @@ # [START program] """Solve assignment problem using linear assignment solver.""" # [START import] -from ortools.graph.python import linear_sum_assignment - import numpy as np + +from ortools.graph.python import linear_sum_assignment # [END import] @@ -35,8 +35,10 @@ def main(): [45, 110, 95, 115], ]) - # Let's transform this into 3 parallel vectors (start_nodes, end_nodes, arc_costs) - end_nodes_unraveled, start_nodes_unraveled = np.meshgrid(np.arange(costs.shape[1]),np.arange(costs.shape[0])) + # Let's transform this into 3 parallel vectors (start_nodes, end_nodes, + # arc_costs) + end_nodes_unraveled, start_nodes_unraveled = np.meshgrid( + np.arange(costs.shape[1]), np.arange(costs.shape[0])) start_nodes = start_nodes_unraveled.ravel() end_nodes = end_nodes_unraveled.ravel() arc_costs = costs.ravel() diff --git a/ortools/graph/samples/simple_max_flow_program.py b/ortools/graph/samples/simple_max_flow_program.py index 23a525aa17..a936c61d4f 100755 --- a/ortools/graph/samples/simple_max_flow_program.py +++ b/ortools/graph/samples/simple_max_flow_program.py @@ -15,9 +15,9 @@ # [START program] """From Taha 'Introduction to Operations Research', example 6.4-2.""" # [START import] -from ortools.graph.python import max_flow - import numpy as np + +from ortools.graph.python import max_flow # [END import] diff --git a/ortools/graph/samples/simple_min_cost_flow_program.py b/ortools/graph/samples/simple_min_cost_flow_program.py index 71a2d47342..ae77a1d9eb 100755 --- a/ortools/graph/samples/simple_min_cost_flow_program.py +++ b/ortools/graph/samples/simple_min_cost_flow_program.py @@ -15,9 +15,9 @@ # [START program] """From Bradley, Hax and Maganti, 'Applied Mathematical Programming', figure 8.1.""" # [START import] -from ortools.graph.python import min_cost_flow - import numpy as np + +from ortools.graph.python import min_cost_flow # [END import]