问题描述
使用OR工具,我试图为每个交付的多个取货问题建模,并提出分离,即只有当所有取货都在交付到达之前就已固化,并且无法让求解器找到部分解决方案时,才可以实现交付。 在下面的玩具示例中,求解器可以在给定的MAX_ROUTE_TIME限制内完成前两个拾取及其交付时返回空解决方案。我是否正确设置每次交付的多功能取纸器?
我尝试了以下方法,但未成功:
import numpy as np
from ortools.constraint_solver import routing_enums_pb2,pywrapcp
manager = pywrapcp.RoutingIndexManager(7,1,0)
routing = pywrapcp.RoutingModel(manager)
dim_name = 'Time'
durations = np.array(
[[ 0,100,100],[ 1,[100,0]])
def duration_callback(from_index,to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return durations[from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(duration_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
MAX_ROUTE_TIME = 400
routing.AddDimension(transit_callback_index,MAX_ROUTE_TIME,True,dim_name)
time_dimension = routing.GetDimensionorDie(dim_name)
pickups_deliveries = [
(1,3),(2,(4,6),(5,6)
]
for pickup,delivery in pickups_deliveries:
pickup_index = manager.NodetoIndex(pickup)
delivery_index = manager.NodetoIndex(delivery)
routing.AddPickupAndDelivery(pickup_index,delivery_index)
routing.solver().Add(routing.VehicleVar(pickup_index) == routing.VehicleVar(delivery_index))
routing.solver().Add(time_dimension.CumulVar(pickup_index) <= time_dimension.CumulVar(delivery_index))
for node in range(1,7):
routing.Adddisjunction([manager.NodetoIndex(node)],10000000)
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC
search_parameters.local_search_Metaheuristic = routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
search_parameters.lns_time_limit.seconds = 2
search_parameters.time_limit.seconds = 5
solution = routing.solveWithParameters(search_parameters)
vehicle_id = 0
index = routing.Start(vehicle_id)
node = manager.IndexToNode(index)
while not routing.IsEnd(index):
prevIoUs_node = node
prevIoUs_index = index
index = solution.Value(routing.Nextvar(index))
node = manager.IndexToNode(index)
print(prevIoUs_node,node,durations[prevIoUs_node,node])
解决方法
您必须复制节点// Register your collectors
elapsed := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "gogrinder_elapsed_ms",Help: "Current time elapsed of gogrinder teststep",},[]string{"teststep","user","iteration","timestamp"})
prometheus.MustRegister(elapsed)
// Remove Go collector
prometheus.Unregister(prometheus.NewGoCollector())
和3
,即该节点不能属于两个不同的P&D ...
非常丑陋的修复(我使用了Python 3.6+ f字符串语法(^ v ^)):
6
可能的输出:
...
manager = pywrapcp.RoutingIndexManager(7+2,1,0)
...
def duration_callback(from_index,to_index):
from_node = manager.IndexToNode(from_index)
if from_node == 7:
from_node = 3
if from_node == 8:
from_node = 6
to_node = manager.IndexToNode(to_index)
if to_node == 7:
to_node = 3
if to_node == 8:
to_node = 6
return durations[from_node][to_node]
...
for node in range(1,9):
routing.AddDisjunction([manager.NodeToIndex(node)],10000000)
...
print(f"objective: {solution.ObjectiveValue()}")
# Display dropped nodes.
dropped_nodes = 'Dropped nodes:'
for node in range(routing.Size()):
if routing.IsStart(node) or routing.IsEnd(node):
continue
if solution.Value(routing.NextVar(node)) == node:
dropped_nodes += ' {}'.format(manager.IndexToNode(node))
print(dropped_nodes)
vehicle_id = 0
index = routing.Start(vehicle_id)
node = manager.IndexToNode(index)
while not routing.IsEnd(index):
previous_node = node
pmap = previous_node
if pmap == 7:
pmap = 3
if pmap == 8:
pmap = 6
previous_index = index
index = solution.Value(routing.NextVar(index))
node = manager.IndexToNode(index)
nmap = node
if nmap == 7:
nmap = 3
if nmap == 8:
nmap = 6
print(f"{previous_node} -> {node} ({durations[pmap,nmap]})")
,
在这种情况下,我想放弃整个交货
在这种情况下,可以在每个节点[1,2,3]
或[4,5,6]
上使用一个析取,而不是每个节点使用一个析取。
routing.AddDisjunction([manager.NodeToIndex(i) for i in (1,3,7)],10000000,4)
routing.AddDisjunction([manager.NodeToIndex(i) for i in (4,6,8)],4)
#for node in range(1,9):
# routing.AddDisjunction([manager.NodeToIndex(node)],10000000)
可能的输出:
[127]─[~/work/tmp/issue]
[>_<]─mizux@nuc10i7 %./so_2020_09_06_2.py
objective: 10000004
Dropped nodes: 4 5 6 8
0 -> 2 (1)
2 -> 1 (1)
1 -> 7 (1)
7 -> 3 (0)
3 -> 0 (1)
[0]─[~/work/tmp/issue]
[^v^]─mizux@nuc10i7 %