Closed Stepka closed 3 years ago
Don't get it, Using CP-SAT solver (in sat directory) you try to solve a scheduling probleme...
Actually, in constraint_solver you have two "stages" the first one which is the CP solver and on top of it you have the VRP Solver (using the CP solver internally).
In you second example you try to solve it using the VRP/TSP Solver which is not really intended for this.
Also you set the number of vehicle to 4
so you can do 4 "tasks" (i.e. visiting locations) in parallel...
It is just simplified test. In real task I have more complex vrptw problem with scheduling. In my case I need to constraint SlackVars on a group of the nodes with routing.solver().Cumulative().
If you want more details:
And both tests shows how I think I can add constraits for SlackVars(). I just make IntrevalVars that shouls match with SlackVars and constrain them using Cumulative() function.
But when I use CP-SAT solver all is work perfectly. But when I try to do same things using Routing solver - it is does not work.
P.S. incrementing num of vehicles to 6 has no effect too.
This code works fine on the CP solver
def main(): """Solve the VRP with time windows.""" data = create_data_model()
solver = pywrapcp.Solver('')
# 1 CREATE INTERVALS
intervals = []
starts = []
durations = []
for i in range(len(data['starts'])):
interval = solver.IntervalVar(
data['starts'][i][0], data['starts'][i][1],
data['durations'][i][0], data['durations'][i][1],
data['ends'][i][0], data['ends'][i][1], False, 'interval_%i' %
i) starts.append(interval.StartExpr().Var()) durations.append(interval.DurationExpr().Var())
intervals.append(interval)
# 2 ADD SHARED RESOURCE CONSTRAINT
solver.Add(solver.Cumulative(intervals, [1 for _ in intervals], 2,
'cumul'))
# 3 MAXIMIZE DURATIONS
obj_var = sum(interval.DurationExpr().Var() for interval in
intervals).Var() obj = solver.Maximize(obj_var, 1)
db1 = solver.Phase(starts, solver.CHOOSE_FIRST_UNBOUND,
solver.ASSIGN_MIN_VALUE)
db2 = solver.Phase(durations, solver.CHOOSE_FIRST_UNBOUND,
solver.ASSIGN_MAX_VALUE)
db3 = solver.Phase([obj_var], solver.CHOOSE_FIRST_UNBOUND,
solver.ASSIGN_MIN_VALUE)
db = solver.Compose([db1, db2, db3])
log = solver.SearchLog(1000000, obj)
count = 0
solver.NewSearch(db, [obj, log])
while solver.NextSolution():
count += 1
print('Solution', count)
for interval in intervals:
print('Wait ([{}..{}] - [{}..{}]; duration: {}), \n'.format(
interval.StartMin(),
interval.StartMax(),
interval.EndMin(),
interval.EndMin(),
interval.DurationExpr().Var().Value()))
solver.EndSearch()
Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le jeu. 26 mars 2020 à 13:51, Stepka notifications@github.com a écrit :
It is just simplified test. In real task I have more complex vrptw problem with scheduling. In my case I need to constraint SlackVars on a group of the nodes with routing.solver().Cumulative().
And both tests shows how I think I can add constraits for SlackVars(). I just make IntrevalVars that shouls match with SlackVars and constrain them using Cumulative() function.
But when I use CP-SAT solver all is work perfectly. But when I try to do same things using Routing solver - it is does not work.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1937#issuecomment-604413121, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUPL3NC7BNGR3DJGKOJAMTRJNFWNANCNFSM4LTW4F2Q .
Yes it works for routing model with this:
routing.solver().NewSearch(db, [time_limit, obj, log])
while routing.solver().NextSolution():
...
routing.solver().EndSearch()
but I still need solution for vrptw.
How can I merge your code with this:
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
solution = routing.SolveWithParameters(search_parameters)
if solution:
print_solution(solution, intervals, durations)
?
Hello!
Do you have any follow up on the latest response from Stepka to your post?
Would appreciate it!
Thanks!
This code works fine on the CP solver def main(): """Solve the VRP with time windows.""" data = create_datamodel() solver = pywrapcp.Solver('') # 1 CREATE INTERVALS intervals = [] starts = [] durations = [] for i in range(len(data['starts'])): interval = solver.IntervalVar( data['starts'][i][0], data['starts'][i][1], data['durations'][i][0], data['durations'][i][1], data['ends'][i][0], data['ends'][i][1], False, 'interval%i' % i) starts.append(interval.StartExpr().Var()) durations.append(interval.DurationExpr().Var()) intervals.append(interval) # 2 ADD SHARED RESOURCE CONSTRAINT solver.Add(solver.Cumulative(intervals, [1 for _ in intervals], 2, 'cumul')) # 3 MAXIMIZE DURATIONS obj_var = sum(interval.DurationExpr().Var() for interval in intervals).Var() obj = solver.Maximize(obj_var, 1) db1 = solver.Phase(starts, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) db2 = solver.Phase(durations, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MAX_VALUE) db3 = solver.Phase([obj_var], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) db = solver.Compose([db1, db2, db3]) log = solver.SearchLog(1000000, obj) count = 0 solver.NewSearch(db, [obj, log]) while solver.NextSolution(): count += 1 print('Solution', count) for interval in intervals: print('Wait ([{}..{}] - [{}..{}]; duration: {}), \n'.format( interval.StartMin(), interval.StartMax(), interval.EndMin(), interval.EndMin(), interval.DurationExpr().Var().Value())) solver.EndSearch() Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00 Le jeu. 26 mars 2020 à 13:51, Stepka notifications@github.com a écrit : … It is just simplified test. In real task I have more complex vrptw problem with scheduling. In my case I need to constraint SlackVars on a group of the nodes with routing.solver().Cumulative(). And both tests shows how I think I can add constraits for SlackVars(). I just make IntrevalVars that shouls match with SlackVars and constrain them using Cumulative() function. But when I use CP-SAT solver all is work perfectly. But when I try to do same things using Routing solver - it is does not work. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#1937 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUPL3NC7BNGR3DJGKOJAMTRJNFWNANCNFSM4LTW4F2Q .
This code works fine on the CP solver def main(): """Solve the VRP with time windows.""" data = create_datamodel() solver = pywrapcp.Solver('') # 1 CREATE INTERVALS intervals = [] starts = [] durations = [] for i in range(len(data['starts'])): interval = solver.IntervalVar( data['starts'][i][0], data['starts'][i][1], data['durations'][i][0], data['durations'][i][1], data['ends'][i][0], data['ends'][i][1], False, 'interval%i' % i) starts.append(interval.StartExpr().Var()) durations.append(interval.DurationExpr().Var()) intervals.append(interval) # 2 ADD SHARED RESOURCE CONSTRAINT solver.Add(solver.Cumulative(intervals, [1 for _ in intervals], 2, 'cumul')) # 3 MAXIMIZE DURATIONS obj_var = sum(interval.DurationExpr().Var() for interval in intervals).Var() obj = solver.Maximize(obj_var, 1) db1 = solver.Phase(starts, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) db2 = solver.Phase(durations, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MAX_VALUE) db3 = solver.Phase([obj_var], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) db = solver.Compose([db1, db2, db3]) log = solver.SearchLog(1000000, obj) count = 0 solver.NewSearch(db, [obj, log]) while solver.NextSolution(): count += 1 print('Solution', count) for interval in intervals: print('Wait ([{}..{}] - [{}..{}]; duration: {}), \n'.format( interval.StartMin(), interval.StartMax(), interval.EndMin(), interval.EndMin(), interval.DurationExpr().Var().Value())) solver.EndSearch() Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00 Le jeu. 26 mars 2020 à 13:51, Stepka notifications@github.com a écrit :
… It is just simplified test. In real task I have more complex vrptw problem with scheduling. In my case I need to constraint SlackVars on a group of the nodes with routing.solver().Cumulative(). And both tests shows how I think I can add constraits for SlackVars(). I just make IntrevalVars that shouls match with SlackVars and constrain them using Cumulative() function. But when I use CP-SAT solver all is work perfectly. But when I try to do same things using Routing solver - it is does not work. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#1937 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUPL3NC7BNGR3DJGKOJAMTRJNFWNANCNFSM4LTW4F2Q .
My code shows the constraint works. The tricky part to make it work was the search part. Can you try adapting it to your example ? Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le mar. 31 mars 2020 à 22:44, duca755 notifications@github.com a écrit :
Hello!
Do you have any follow up on the latest response from Stepka to your post?
Would appreciate it!
Thanks!
This code works fine on the CP solver def main(): """Solve the VRP with time windows.""" data = create_datamodel() solver = pywrapcp.Solver('') # 1 CREATE INTERVALS intervals = [] starts = [] durations = [] for i in range(len(data['starts'])): interval = solver.IntervalVar( data['starts'][i][0], data['starts'][i][1], data['durations'][i][0], data['durations'][i][1], data['ends'][i][0], data['ends'][i][1], False, 'interval%i' % i) starts.append(interval.StartExpr().Var()) durations.append(interval.DurationExpr().Var()) intervals.append(interval)
2 ADD SHARED RESOURCE CONSTRAINT solver.Add(solver.Cumulative(intervals,
[1 for _ in intervals], 2, 'cumul')) # 3 MAXIMIZE DURATIONS obj_var = sum(interval.DurationExpr().Var() for interval in intervals).Var() obj = solver.Maximize(obj_var, 1) db1 = solver.Phase(starts, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) db2 = solver.Phase(durations, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MAX_VALUE) db3 = solver.Phase([obj_var], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) db = solver.Compose([db1, db2, db3]) log = solver.SearchLog(1000000, obj) count = 0 solver.NewSearch(db, [obj, log]) while solver.NextSolution(): count += 1 print('Solution', count) for interval in intervals: print('Wait ([{}..{}]
- [{}..{}]; duration: {}), \n'.format( interval.StartMin(), interval.StartMax(), interval.EndMin(), interval.EndMin(), interval.DurationExpr().Var().Value())) solver.EndSearch() Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00 Le jeu. 26 mars 2020 à 13:51, Stepka notifications@github.com a écrit : … <#m-5810027570700119166> It is just simplified test. In real task I have more complex vrptw problem with scheduling. In my case I need to constraint SlackVars on a group of the nodes with routing.solver().Cumulative(). And both tests shows how I think I can add constraits for SlackVars(). I just make IntrevalVars that shouls match with SlackVars and constrain them using Cumulative() function. But when I use CP-SAT solver all is work perfectly. But when I try to do same things using Routing solver - it is does not work. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#1937 (comment) https://github.com/google/or-tools/issues/1937#issuecomment-604413121>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUPL3NC7BNGR3DJGKOJAMTRJNFWNANCNFSM4LTW4F2Q .
This code works fine on the CP solver def main(): """Solve the VRP with time windows.""" data = create_datamodel() solver = pywrapcp.Solver('') # 1 CREATE INTERVALS intervals = [] starts = [] durations = [] for i in range(len(data['starts'])): interval = solver.IntervalVar( data['starts'][i][0], data['starts'][i][1], data['durations'][i][0], data['durations'][i][1], data['ends'][i][0], data['ends'][i][1], False, 'interval%i' % i) starts.append(interval.StartExpr().Var()) durations.append(interval.DurationExpr().Var()) intervals.append(interval)
2 ADD SHARED RESOURCE CONSTRAINT solver.Add(solver.Cumulative(intervals,
[1 for _ in intervals], 2, 'cumul')) # 3 MAXIMIZE DURATIONS obj_var = sum(interval.DurationExpr().Var() for interval in intervals).Var() obj = solver.Maximize(obj_var, 1) db1 = solver.Phase(starts, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) db2 = solver.Phase(durations, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MAX_VALUE) db3 = solver.Phase([obj_var], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) db = solver.Compose([db1, db2, db3]) log = solver.SearchLog(1000000, obj) count = 0 solver.NewSearch(db, [obj, log]) while solver.NextSolution(): count += 1 print('Solution', count) for interval in intervals: print('Wait ([{}..{}]
- [{}..{}]; duration: {}), \n'.format( interval.StartMin(), interval.StartMax(), interval.EndMin(), interval.EndMin(), interval.DurationExpr().Var().Value())) solver.EndSearch() Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00 Le jeu. 26 mars 2020 à 13:51, Stepka notifications@github.com a écrit :
… <#m-5810027570700119166> It is just simplified test. In real task I have more complex vrptw problem with scheduling. In my case I need to constraint SlackVars on a group of the nodes with routing.solver().Cumulative(). And both tests shows how I think I can add constraits for SlackVars(). I just make IntrevalVars that shouls match with SlackVars and constrain them using Cumulative() function. But when I use CP-SAT solver all is work perfectly. But when I try to do same things using Routing solver - it is does not work. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#1937 (comment) https://github.com/google/or-tools/issues/1937#issuecomment-604413121>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUPL3NC7BNGR3DJGKOJAMTRJNFWNANCNFSM4LTW4F2Q .
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1937#issuecomment-606864784, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUPL3NDPCFWQPZKDVIAXK3RKJI3HANCNFSM4LTW4F2Q .
I'm trying to adapt your code to my task and faced with print routes problem. This code failed:
count = 0
routing.solver().NewSearch(db, [time_limit, obj, log])
while routing.solver().NextSolution():
count += 1
plan_output = 'Solution #{}\n'.format(count)
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):
node_index = manager.IndexToNode(index)
plan_output += '[ #{} -> \n'.format(
node_index
)
index = routing.NextVar(index).Value()
for interval in intervals:
plan_output += 'Wait ([{}..{}] - [{}..{}]; duration: {}), \n'.format(
get_time_string(interval.StartMin()),
get_time_string(interval.StartMax()),
get_time_string(interval.EndMin()),
get_time_string(interval.EndMin()),
get_time_string(interval.DurationExpr().Var().Value()))
print(plan_output)
routing.solver().EndSearch()
Code prints:
WARNING: Logging before InitGoogleLogging() is written to STDERR
I0402 10:55:39.796936 12248 search.cc:253] Start search (memory used = 64.69 MB)
I0402 10:55:39.797935 12248 search.cc:253] Root node processed (time = 0 ms, constraints = 48, memory used = 64.98 MB)
I0402 10:55:39.809952 12248 search.cc:253] Solution #0 (objective value = 40, time = 12 ms, branches = 1262, failures = 627, depth = 635, memory used = 65.29 MB, limit = 0%)
F0402 10:55:39.814927 12248 expressions.cc:1340] Check failed: min_.Value() == max_.Value() (0 vs. 13) variable Nexts0(0..13) is not bound.
*** Check failure stack trace: ***
This line is wrong:index = routing.NextVar(index).Value()
What I doing wrong?
of course, the routing model is only 'solved' if you use the routing.Solve() method. Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le jeu. 2 avr. 2020 à 11:01, Stepka notifications@github.com a écrit :
I'm trying to adapt your code to my task and faced with print routes problem. This code failed:
count = 0 routing.solver().NewSearch(db, [time_limit, obj, log]) while routing.solver().NextSolution(): count += 1 plan_output = 'Solution #{}\n'.format(count) 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): node_index = manager.IndexToNode(index) plan_output += '[ #{} -> \n'.format( node_index ) index = routing.NextVar(index).Value() for interval in intervals: plan_output += 'Wait ([{}..{}] - [{}..{}]; duration: {}), \n'.format( get_time_string(interval.StartMin()), get_time_string(interval.StartMax()), get_time_string(interval.EndMin()), get_time_string(interval.EndMin()), get_time_string(interval.DurationExpr().Var().Value())) print(plan_output) routing.solver().EndSearch()
Code prints:
WARNING: Logging before InitGoogleLogging() is written to STDERR I0402 10:55:39.796936 12248 search.cc:253] Start search (memory used = 64.69 MB) I0402 10:55:39.797935 12248 search.cc:253] Root node processed (time = 0 ms, constraints = 48, memory used = 64.98 MB) I0402 10:55:39.809952 12248 search.cc:253] Solution #0 (objective value = 40, time = 12 ms, branches = 1262, failures = 627, depth = 635, memory used = 65.29 MB, limit = 0%) F0402 10:55:39.814927 12248 expressions.cc:1340] Check failed: min.Value() == max.Value() (0 vs. 13) variable Nexts0(0..13) is not bound. Check failure stack trace:
This line is wrong: index = routing.NextVar(index).Value() What I doing wrong?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1937#issuecomment-607716793, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUPL3OXEE2C7E2Y632VK3DRKRH45ANCNFSM4LTW4F2Q .
I'm sorry, but I frustrated. Am I right that or-tools now cannot solve routing model and constrain IntervalVars via Cumulative() function in one case? Will it be added in the future?
It can:
https://github.com/google/or-tools/blob/stable/ortools/constraint_solver/samples/vrp_resources.py
Laurent Perron | Operations Research | lperron@google.com | (33) 1 42 68 53 00
Le jeu. 2 avr. 2020 à 11:34, Stepka notifications@github.com a écrit :
I'm sorry, but I frustrated. Am I right that or-tools now cannot solve routing model and constrain IntervalVars via Cumulative() function in one case? Will it be added in the future?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/google/or-tools/issues/1937#issuecomment-607733632, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUPL3J7EJNZYHCQUDTYMS3RKRL3ZANCNFSM4LTW4F2Q .
I tryied VRP resources example, updated it with IntervalVar instead FixedDurationIntervalVar. And this code shown the same result as example. So, it can be a signal that problem is not with IntervalVar and Cumulative.
But I found two problems again.
First - from output when I run VRP example with fixed duration vars:
Route for vehicle 0:
0 Time(5,5) -> 8 Time(8,8) -> 14 Time(11,11) -> 16 Time(13,13) -> 0 Time(20,20)
Time of the route: 20min
Route for vehicle 1:
0 Time(0,0) -> 12 Time(4,4) -> 13 Time(6,6) -> 15 Time(11,11) -> 11 Time(14,14) -> 0 Time(20,20)
Time of the route: 20min
Route for vehicle 2:
0 Time(5,5) -> 7 Time(7,7) -> 1 Time(11,11) -> 4 Time(13,13) -> 3 Time(14,14) -> 0 Time(25,25)
Time of the route: 25min
Route for vehicle 3:
0 Time(0,0) -> 9 Time(2,3) -> 5 Time(4,5) -> 6 Time(6,9) -> 2 Time(10,12) -> 10 Time(14,16) -> 0 Time(25,25)
Time of the route: 25min
As you see each vehicle transit to a first location from depot for a 2..4 time units, but there are not adds load_time (5 time units) in the arrival time. Looks like duration is omitted by solver. It is looks like a bug.
And the second problem, when I try to link my interval var duration to slackvars solver has no affect. Look like it linked with bug above.
Hello,
This worked fine for me:
routing.solver().Add(routing.solver().Cumulative(vector< IntervalVar * >, vector< int > &demands, int capacity, string &name).
I will try to re-examine, I hope no hidden issues ...
I made a little test for 6 interval vars using cp_model. And it work as I great!
But the same test, but for routing solver does not work! Can it be a bug or I missed something?
Below tests for both solvers:
and
And here is outputs:
cp_model solver output (not more than 2 intervals simultaneously, as I expected):
routing solver output (all intervals simultaneously, but I expect not more than 2):
So, please help. Am I missed something or it is a bug of the OR Tools?
I use: