我是Google OR工具的新手,当从Jupyter Notebook
调用时,我设法使其中一个示例可以工作。但是,当我使用此工作代码并将其打包到python模块中的函数中时,我开始遇到RunTimeError
。
我在用:
似乎我缺少使python工具包中提供OR工具的功能。我查找了类似的错误,并遇到了更新
distance_callback
函数的建议。但是我使用的功能还是建议的版本。Jupyter笔记本中的工作代码
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def distance_callback(from_index, to_index):
"""Returns the distance between the two nodes."""
# Convert from routing variable Index to distance matrix NodeIndex.
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data['distance_matrix'][from_node][to_node]
def get_solution(manager, routing, assignment):
index = routing.Start(0)
output = [manager.IndexToNode(index)]
while not routing.IsEnd(index):
previous_index = index
index = assignment.Value(routing.NextVar(index))
output.append(manager.IndexToNode(index))
return np.array(output)
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(
len(data['distance_matrix']), data['num_vehicles'], data['depot']
)
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
# Define cost of each arc.
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
)
search_parameters.time_limit.seconds = 30
# Solve the problem.
assignment = routing.SolveWithParameters(search_parameters)
x = get_solution(manager, routing, assignment)
python模块中包含的功能
def packaged_function(data):
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(
len(data['distance_matrix']), data['num_vehicles'], data['depot']
)
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
# Define cost of each arc.
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
)
search_parameters.time_limit.seconds = 30
# Solve the problem.
assignment = routing.SolveWithParameters(search_parameters)
return (manager, routing, assignment)
从Jupyter调用函数
from package_name.router import packaged_function
output = packaged_function(data)
当我以这种方式执行 call 时,我会遇到一些错误,即:
RuntimeError Traceback (most recent call last)
RuntimeError: SWIG std::function invocation failed.
The above exception was the direct cause of the following exception:
SystemError Traceback (most recent call last)
/usr/local/lib/python3.6/site-packages/ortools/constraint_solver/pywrapcp.py in <lambda>(self, name, value)
2135 __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-> 2136 __setattr__ = lambda self, name, value: _swig_setattr(self, Assignment, name, value)
2137 __swig_getmethods__ = {}
/usr/local/lib/python3.6/site-packages/ortools/constraint_solver/pywrapcp.py in _swig_setattr(self, class_type, name, value)
70 def _swig_setattr(self, class_type, name, value):
---> 71 return _swig_setattr_nondynamic(self, class_type, name, value, 0)
72
/usr/local/lib/python3.6/site-packages/ortools/constraint_solver/pywrapcp.py in _swig_setattr_nondynamic(self, class_type, name, value, static)
54 if (name == "this"):
---> 55 if type(value).__name__ == 'SwigPyObject':
56 self.__dict__[name] = value
SystemError: <class 'type'> returned a result with an error set
The above exception was the direct cause of the following exception:
SystemError Traceback (most recent call last)
233
234 # Solve the problem.
--> 235 assignment = routing.SolveWithParameters(search_parameters)
236
237 return (manager, routing, assignment)
/usr/local/lib/python3.6/site-packages/ortools/constraint_solver/pywrapcp.py in SolveWithParameters(self, search_parameters, solutions)
3423
3424 def SolveWithParameters(self, search_parameters: 'operations_research::RoutingSearchParameters const &', solutions: 'std::vector< operations_research::Assignment const * > *'=None) -> "operations_research::Assignment const *":
-> 3425 return _pywrapcp.RoutingModel_SolveWithParameters(self, search_parameters, solutions)
3426
3427 def SolveFromAssignmentWithParameters(self, assignment: 'Assignment', search_parameters: 'operations_research::RoutingSearchParameters const &', solutions: 'std::vector< operations_research::Assignment const * > *'=None) -> "operations_research::Assignment const *":
SystemError: <built-in function RoutingModel_SolveWithParameters> returned a result with an error set
最佳答案
您必须在packaged_function()
中移动distance_callback定义
例如
package_function.py:
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def packaged_function(data):
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(
len(data['distance_matrix']), data['num_vehicles'], data['depot']
)
def distance_callback(from_index, to_index):
"""Returns the distance between the two nodes."""
# Convert from routing variable Index to distance matrix NodeIndex.
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data['distance_matrix'][from_node][to_node]
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
# Define cost of each arc.
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
)
search_parameters.time_limit.seconds = 30
# Solve the problem.
assignment = routing.SolveWithParameters(search_parameters)
return (manager, routing, assignment)
和test.py:
from packaged_function import packaged_function as pf
def print_solution(manager, routing, assignment):
"""Prints assignment on console."""
print('Objective: {} miles'.format(assignment.ObjectiveValue()))
index = routing.Start(0)
plan_output = 'Route for vehicle 0:\n'
route_distance = 0
while not routing.IsEnd(index):
plan_output += ' {} ->'.format(manager.IndexToNode(index))
previous_index = index
index = assignment.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
plan_output += ' {}\n'.format(manager.IndexToNode(index))
print(plan_output)
plan_output += 'Route distance: {}miles\n'.format(route_distance)
def main():
data = {}
data['distance_matrix'] = [
[0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972],
[2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579],
[713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260],
[1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987],
[1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371],
[1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999],
[2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701],
[213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099],
[2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600],
[875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162],
[1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200],
[2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504],
[1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0],
] # yapf: disable
data['num_vehicles'] = 1
data['depot'] = 0
(manager, routing, assignment) = pf(data)
print_solution(manager, routing, assignment)
if __name__ == '__main__':
main()
输出
python test.py
Objective: 7293 miles
Route for vehicle 0:
0 -> 7 -> 2 -> 3 -> 4 -> 12 -> 6 -> 8 -> 1 -> 11 -> 10 -> 5 -> 9 -> 0
注意:如果我将
distance_callback
移到def packaged_function()
之前,我可以重现您的错误关于python - 从Python包中调用Python OR-tools函数不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55862927/