google ortools vrp set break fails - or-tools
I modified the original vrptw.py sample and want to set break for couple vehicles/routes.
from __future__ import print_function
from ortools.constraint_solver import pywrapcp
from ortools.constraint_solver import routing_enums_pb2
def create_data_model():
"""Stores the data for the problem."""
data = {}
data['time_matrix'] = [
[0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7],
[6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14],
[9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9],
[8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16],
[7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14],
[3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8],
[6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5],
[2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10],
[3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6],
[2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5],
[6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4],
[6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10],
[4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8],
[4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6],
[5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2],
[9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9],
[7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0],
]
import numpy as np
# data['time_matrix'] = np.full(np.array(data['time_matrixs']).shape, fill_value=1)
# data['time_matrix'] = np.array(data['time_matrixs'])[np.array(data['time_matrixs']) == 0] == 0
data['time_windows'] = [
(0, 10), # depot
(7, 12), # 1
(10, 15), # 2
(16, 18), # 3
(10, 13), # 4
(5, 30), # 5
(5, 10), # 6
(5, 30), # 7
(5, 10), # 8
(5, 10), # 9
(10, 16), # 10
(10, 20), # 11
(5, 30), # 12
(5, 11), # 13
(7, 30), # 14
(10, 19), # 15
(11, 15), # 16
]
data['num_vehicles'] = 4
data['depot'] = 0
return data
def print_solution(data, manager, routing, assignment):
"""Prints assignment on console."""
time_dimension = routing.GetDimensionOrDie('Time')
total_time = 0
print('Breaks:')
intervals = assignment.IntervalVarContainer()
for i in range(intervals.Size()):
brk = intervals.Element(i)
if brk.PerformedValue() == 1:
print('{}: Start({}) Duration({})'.format(
brk.Var().Name(),
brk.StartValue(),
brk.DurationValue()))
else:
print('{}: Unperformed'.format(brk.Var().Name()))
print()
for vehicle_id in range(data['num_vehicles']):
index = routing.Start(vehicle_id)
plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
while not routing.IsEnd(index):
time_var = time_dimension.CumulVar(index)
slack_var = time_dimension.SlackVar(index)
plan_output += '{0} Time({1},{2}) Slack({3},{4}) -> '.format(
manager.IndexToNode(index), assignment.Min(time_var),
assignment.Max(time_var), assignment.Min(slack_var), assignment.Max(slack_var))
index = assignment.Value(routing.NextVar(index))
time_var = time_dimension.CumulVar(index)
plan_output += '{0} Time({1},{2})\n'.format(manager.IndexToNode(index),
assignment.Min(time_var),
assignment.Max(time_var))
plan_output += 'Time of the route: {}min\n'.format(
assignment.Min(time_var))
print(plan_output)
total_time += assignment.Min(time_var)
print('Total time of all routes: {}min'.format(total_time))
slack_var = time_dimension.SlackVar(int(2))
print(slack_var.Bound())
if slack_var.Bound():
slack_min = assignment.Min(slack_var)
slack_max = assignment.Max(slack_var)
# print("assignment.Min(slack_var): ", assignment.Value(slack_var))
def main():
"""Solve the VRP with time windows."""
data = create_data_model()
manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']), data['num_vehicles'], data['depot'])
routing = pywrapcp.RoutingModel(manager)
def time_callback(from_index, to_index):
"""Returns the travel time between the two nodes."""
# Convert from routing variable Index to time matrix NodeIndex.
if from_index == to_index: return 0
return 1
# from_node = manager.IndexToNode(from_index)
# to_node = manager.IndexToNode(to_index)
# return data['time_matrix'][from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(time_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
time = 'Time'
routing.AddDimension(
transit_callback_index,
30*100, # allow waiting time
50, # maximum time per vehicle
False, # Don't force start cumul to zero.
time)
time_dimension = routing.GetDimensionOrDie(time)
# Add breaks TODO Uncomment
node_visit_transit = {}
for n in range(routing.Size()):
if n >= len(data['time_windows']):
node_visit_transit[n] = 0
else:
node_visit_transit[n] = 0 # int(data['demands'][n] * data['time_per_demand_unit'])
break_intervals = {}
# for v in xrange(data['num_vehicles']):
for v in [0,1]:
# vehicle_break = data['breaks'][v]
break_intervals[v] = [
routing.solver().FixedDurationIntervalVar(
0, 0, 1, False, 'Break for vehicle {}'.format(v))
]
time_dimension.SetBreakIntervalsOfVehicle(
break_intervals[v], v, node_visit_transit)
# Add time window constraints for each location except depot.
for location_idx, time_window in enumerate(data['time_windows']):
if location_idx == 0:
continue
index = manager.NodeToIndex(location_idx)
time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1])
routing.AddToAssignment(time_dimension.SlackVar(index))
# Add time window constraints for each vehicle start node.
for vehicle_id in range(data['num_vehicles']):
index = routing.Start(vehicle_id)
time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0], data['time_windows'][0][1])
routing.AddToAssignment(time_dimension.SlackVar(index))
for i in range(data['num_vehicles']):
routing.AddVariableMinimizedByFinalizer(
time_dimension.CumulVar(routing.Start(i)))
routing.AddVariableMinimizedByFinalizer(
time_dimension.CumulVar(routing.End(i)))
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
search_parameters.time_limit.seconds = 5
# search_parameters.log_search = True
assignment = routing.SolveWithParameters(search_parameters)
if assignment:
print_solution(data, manager, routing, assignment)
if __name__ == '__main__':
main()
Note:
Transit time is exactly 1
number of vehicles: 4
The break is at the beging
The problem is when I set break (node_visit_transit=1) for more than 2 vehicles, it stucks.
Could you please explain what's wrong with code and why it stuck?
P.S. When I set break for only one vehicle[ex:0 and 1], the output is as following:
Breaks:
Break for vehicle 0: Start(0) Duration(1)
Break for vehicle 1: Start(0) Duration(1)
Route for vehicle 0:
0 Time(1,1) Slack(0,0) -> 0 Time(2,2)
Time of the route: 2min
Route for vehicle 1:
0 Time(1,1) Slack(16,16) -> 0 Time(18,18)
Time of the route: 18min
Route for vehicle 2:
0 Time(0,0) Slack(4,6) -> 13 Time(5,7) Slack(0,2) -> 9 Time(6,8) Slack(0,2) -> 8 Time(7,9) Slack(0,2) -> 6 Time(8,10) Slack(0,2) -> 2 Time(10,11) Slack(0,1) -> 1 Time(11,12) Slack(0,1) -> 4 Time(12,13) Slack(2,3) -> 3 Time(16,16) Slack(0,0) -> 0 Time(17,17)
Time of the route: 17min
Route for vehicle 3:
0 Time(0,0) Slack(10,10) -> 16 Time(11,11) Slack(0,0) -> 15 Time(12,12) Slack(0,0) -> 14 Time(13,13) Slack(0,0) -> 12 Time(14,14) Slack(0,0) -> 11 Time(15,15) Slack(0,0) -> 10 Time(16,16) Slack(0,0) -> 7 Time(17,17) Slack(0,0) -> 5 Time(18,18) Slack(0,0) -> 0 Time(19,19)
Time of the route: 19min
Total time of all routes: 56min
False
Please note, The slack and time for route 2 and 3 of depot is strange
Related
how do I concatenate the results of a concatenated array?
I have two matrices (dfs): A = [1 2 3 4 5 6 7 8 9 10 11 12] and B = [1, 2, 3] and I want matrix C to be repeating each row in A, B times. for example, first row, 1,2,3,4 needs to be repeated once, second row: 5,6,7,8 twice and last row three times: C = [1 2 3 4 5 6 7 8 5 6 7 8 9 10 11 12 9 10 11 12 9 10 11 12] my code for i in range(0,2401): g = pd.concat([df1.iloc[[i]]]*z[i], ignore_index=True) partially does this, except only gives me the 3 times last row part, I need to concatenate each concatenation. below gives me what I want but its not clean, i.e. indices are not ignored and messy. result = [] for i in range(0,2401): g = pd.concat([df1.iloc[[i]]]*z[i], ignore_index=True) result.append(g)
If you write your matrices like: A = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] B = [1, 2, 3] C = [] You can iterate through B and add to C like: for i in range(len(B)): index = 0 while index < B[i]: C.append(A[i]) index += 1 Which has an output: [[1, 2, 3, 4], [5, 6, 7, 8], [5, 6, 7, 8], [9, 10, 11, 12], [9, 10, 11, 12], [9, 10, 11, 12]] I hope this helps!
Getting the matrix value given a vector of indices along each axis
I have a Matlab matrix M with size: [70 5 3 2 10 9 5 3 21]; I have a vector with a coordinates that I want to read of that matrix: [5, 1, 1, 2, 3, 4, 1, 2, 1]; MWE example of what I am trying to get: M = rand(70 5 3 2 10 9 5 3 21); coordinates = [5, 1, 1, 2, 3, 4, 1, 2, 1]; % Output desired: M(5, 1, 1, 2, 3, 4, 1, 2, 1) %Current attempt: M(coordinates) Clearly M(coordinates) <> M(5, 1, 1, 2, 3, 4, 1, 2, 1). Is there a way of doing this?
It's a bit awkward, but you can convert the array to a cell array, and then to a comma-separated list: M = rand(70, 5, 3, 2, 10, 9, 5, 3, 21); coordinates = [5, 1, 1, 2, 3, 4, 1, 2, 1]; coords_cell = num2cell(coordinates); result = M(coords_cell{:});
How to check if a list of lists contains any of the elements from another list
I'm trying to make a sample lottery checker. I'm using python. x = [1,2,3,4,5, y = [[1,2,3,4,5,6] # 6 numbers hit ,[1,2,3,4,6,7] # 5 numbers hit ,[2,3,4,6,7,8] # 4 numbers hit ,[4,5,6,7,8,9] # 3 numbers hit ,[1,2,7,8,9,10] # 2 numbers hit ,[4,7,8,9,10,11] # 1 number hit ,[7,8,9,10,11,12]] output: (including the number of hits) [1,2,3,4,5,6] 6 number hit [1,2,3,4,6,7] 5 numbers hit [2,3,4,6,7,8] 4 numbers hit [4,5,6,7,8,9] 3 numbers hit [1,2,7,8,9,10] 2 numbers hit [4,7,8,9,10,11] 1 number hit I tried using the any() function but only returned true or false. please help.
Data: x = [1,2,3,4,5,6] y = [[1,2,3,4,5,6] # 6 numbers hit ,[1,2,3,4,6,7] # 5 numbers hit ,[2,3,4,6,7,8] # 4 numbers hit ,[4,5,6,7,8,9] # 3 numbers hit ,[1,2,7,8,9,10] # 2 numbers hit ,[4,7,8,9,10,11] # 1 number hit ,[7,8,9,10,11,12]] Code: for ticket in y: print(ticket) count = 0 for item in x: if item in ticket: count += 1 print(count, " numbers hit!") Output: [1, 2, 3, 4, 5, 6] 6 numbers hit! [1, 2, 3, 4, 6, 7] 5 numbers hit! [2, 3, 4, 6, 7, 8] 4 numbers hit! [4, 5, 6, 7, 8, 9] 3 numbers hit! [1, 2, 7, 8, 9, 10] 2 numbers hit! [4, 7, 8, 9, 10, 11] 1 numbers hit! [7, 8, 9, 10, 11, 12] 0 numbers hit!
find and match multiple values in the same row in array in matlab
I have a data set consists of the following (which are head values for a finite difference groundwater flow model consists of 200 row, 200 column, and 5 layers) , "id", "k", "i", "j", "f", "Active" 1, 1, 1, 1, 1, 313, 0 2, 2, 1, 1, 2, 315.2.0, 0 3, 3, 1, 1, 3, 301.24, 0 4, 4, 1, 1, 4, 306.05, 0 5, 5, 1, 1, 5, -999.0, 0 6, 6, 1, 1, 6, -999.0, 0 7, 7, 1, 1, 7, 310.57, 0 8, 8, 1, 1, 8, -999.0, 0 9, 9, 1, 1, 9, -999.0, 0 . . . 200000, 200000, 5, 200, 200, -999.0, 0 let us assume that I need to find the row that has a specific i,j,k for example I want to find the row which has i=100, j=50, k=3 to store the value f for multiple i,j,k I've tried to use find but it finds only the location for a specific item I know it can be done using for & if but it will be time demanding Is there a fast way to do so using matlab?
Lets suppose your text file has the following data "id", "k", "i", "j", "f", "Active" 1, 1, 1, 1, 313, 0 2, 1, 1, 2, 315.2.0, 0 3, 1, 1, 3, 301.24, 0 4, 1, 1, 4, 306.05, 0 5, 1, 1, 5, -999.0, 0 6, 1, 1, 6, -999.0, 0 7, 1, 1, 7, 310.57, 0 8, 1, 1, 8, -999.0, 0 9, 1, 1, 9, -999.0, 0 First read the file through >> fileID = fopen('testfileaccess.txt'); >> C = textscan(fileID,'%s %s %s %s %s %s','Delimiter',',') You will get 6 cells representing each column C = Columns 1 through 5 {10x1 cell} {10x1 cell} {10x1 cell} {10x1 cell} {10x1 cell} Column 6 {10x1 cell} >> Matrix= [str2double(C{2}).';str2double(C{3}).';str2double(C{4}).';].' the above code will result the i j and k in a matrix with each row representing each variable Matrix = NaN NaN NaN 1 1 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 then if you want to find for example k = 1 , i = 1 and j = 8 you use find() find(Matrix(:,1) == 1 & Matrix(:,2) == 1 & Matrix(:,3) == 8) and there you have it ans = 8 8th row
row = jcount*kcount*(i-1) + kcount*(j-1) + k In your case: row = 200*5*(i-1) + 5*(j-1) + k
Evaluate optimal replacement algorithm for 5 frames
Question: Consider the following page reference string: 1, 2, 3, 4, 2, 1, 5, 6, 2, 1, 2, 3, 7, 6, 3, 2, 1, 2, 3, 6. How many page faults would occur for the optimal page replacement algorithms, assuming five frames? Remember all frames are initially empty, so your first unique pages will all cost one fault each. I am not quite sure what would happen: 1 -> 1 2 -> 1, 2 3 -> 1, 2, 3 4 -> 1, 2, 3, 4, 2 -> What happens here?? 1 ...etc (with the rest of the reference string)
There will be 7 page faults in total. 1 -> 1 2 -> 1, 2 3 -> 1, 2, 3 4 -> 1, 2, 3, 4 2 -> 1, 2, 3, 4 (This is a hit 2 is already in the memory) 1 -> 1, 2, 3, 4 5 -> 1, 2, 3, 4, 5 (This is a miss but we have 5 frames.) 6 -> 1, 2, 3, 6, 5 (4 will be replaced as it is not required in future) ...