routing.VehicleVar conflicts with routing.AddDisjunction

57 views
Skip to first unread message

Mr.Pickle

unread,
Sep 16, 2021, 3:47:40 AM9/16/21
to or-tools-discuss
Previously my model has a disjunction function which is useful to allow dropping nodes and partial solution if any constraints are not met.

def allow_dropping(routing,data,manager):
# Allow to drop nodes.
global penalty
penalty = 1000000
for node in range(1, len(data.locations)-1):
routing.AddDisjunction([manager.NodeToIndex(node)], penalty)


Recently, I have added an exra constraint by limiting the types of vehicle visiting certain nodes (suggested approach is presented here: #2718) and the actual full codes implemented in my model is below:

def genTruckSubList(data):
global truck_all
global truck_4M2
global truck_5M2
global truck_6M8
global truck_7M6
global truck_9M6
global truck_13M
truck_all = []
truck_4M2 = []
truck_5M2 = []
truck_6M8 = []
truck_7M6 = []
truck_9M6 = []
truck_13M = []
global dist_all
global dist_4M2
global dist_5M2
global dist_6M8
global dist_7M6
global dist_9M6
global dist_13M
dist_all = []
dist_4M2 = []
dist_5M2 = []
dist_6M8 = []
dist_7M6 = []
dist_9M6 = []
dist_13M = []

for index, capacity in enumerate(capacity_vector()):
truck_all.append(index)
if capacity <= CAP_4M2:
                        #generate list of nodes that can be visited by 4.2meter truck
truck_4M2.append(index)
                        #generate the max driving distance for 4.2meter truck
dist_4M2.append(180)
if capacity > CAP_4M2 and capacity <= CAP_5M2:
truck_5M2.append(index)
dist_5M2.append(180)
if capacity > CAP_5M2 and capacity <= CAP_6M8:
truck_6M8.append(index)
dist_6M8.append(220)
if capacity > CAP_6M8 and capacity <= CAP_7M6:
truck_7M6.append(index)
dist_7M6.append(250)
if capacity > CAP_7M6 and capacity <= CAP_9M6:
truck_9M6.append(index)
dist_9M6.append(250)
if capacity > CAP_9M6 and capacity <= CAP_13M:
truck_13M.append(index)
dist_13M.append(220)

dist_all = dist_4M2+dist_5M2+dist_6M8+dist_7M6+dist_9M6+dist_13M


def limitMaxLength(data,manager,routing):
if "cargo_max_length" in data.df.columns and len(data.df["cargo_max_length"].tolist()) > 0:
for i, row in data.df.iterrows():
model_id = mapID_reverse(data.map, row["ID"])
index = manager.NodeToIndex(model_id)
length = row["cargo_max_length"]
if length < 4.2:
routing.VehicleVar(index).SetValues(truck_all)
continue
if length >= 4.2 and length < 5.2:
routing.VehicleVar(index).SetValues(truck_5M2+truck_6M8+truck_7M6+truck_9M6+truck_13M)
continue
if length >= 5.2 and length < 6.8:
routing.VehicleVar(index).SetValues(truck_6M8+truck_7M6+truck_9M6+truck_13M)
continue
if length >= 6.8 and length < 7.6:
routing.VehicleVar(index).SetValues(truck_7M6+truck_9M6+truck_13M)
continue
if length >= 7.6 and length < 9.6:
routing.VehicleVar(index).SetValues(truck_9M6+truck_13M)
continue
if length >= 9.6 and length < 13:
routing.VehicleVar(index).SetValues(truck_13M)
continue
if length >= 13:
routing.VehicleVar(index).SetValues([-1])
continue
The model main function settings are as below:

def main():
"""Entry point of the program"""
# Instantiate the data problem.
data = DataProblem()

# Create Routing Model
manager = pywrapcp.RoutingIndexManager(data.num_locations, data.num_vehicles, data.starts, data.ends)
# manager = pywrapcp.RoutingIndexManager(data.num_locations, data.num_vehicles, data.depot)
routing = pywrapcp.RoutingModel(manager)


# Add Max Length Limit constraint
genTruckSubList(data)
limitMaxLength(data,manager,routing)
# Add Distance constraint
dist_evaluator = CreateDistanceEvaluator(data,manager)
distance_callback_index = routing.RegisterTransitCallback(dist_evaluator.distance_evaluator)
dist_evaluator.define_total_cost(data,routing,manager)
add_distance_dimension(routing, distance_callback_index, data, manager)
# Add Capacity constraint
demand_evaluator = CreateDemandEvaluator(data, manager).demand_evaluator
demand_callback_index = routing.RegisterUnaryTransitCallback(demand_evaluator)
add_capacity_constraints(routing, data, demand_callback_index, manager)
# Add Cubic Meters constraint
cm3_evaluator = CreateCM3Evaluator(data, manager).cm3_evaluator
cm3_callback_index = routing.RegisterUnaryTransitCallback(cm3_evaluator)
add_cm3_constraints(routing, data, cm3_callback_index)
# Add Time Window constraint
time_evaluator = CreateTimeEvaluator(data, manager).time_evaluator
time_callback_index = routing.RegisterTransitCallback(time_evaluator)
add_time_window_constraints(routing, data, time_callback_index, manager)
# Allow dropping nodes if solution infeasible
allow_dropping(routing, data, manager)


I found if the constaint function "limitMaxLength(data,manager,routing)" is in place, the model will not find a solution, even the allow_dropping() is there. However, if I try to comment out the "limitMaxLength(data,manager,routing)", the model works perfectly and dropped nodes sucessfully that with distance exceed the allowed vehicle driving distance.

Therefore, I suspect there is some conflicts between the use of "routing.AddDisjunction" and "routing.VehicleVar" in imitMaxLength(data,manager,routing), which prevents the model running in correct way to find the solution.

Mr.Pickle

unread,
Sep 16, 2021, 4:14:43 AM9/16/21
to or-tools-discuss
Reply all
Reply to author
Forward
0 new messages