1

I want to schedule n jobs on m machines with transition times and alternatives and modified the example in github/or-tools/scheduling_with_transitions_sat.py because I also want some kind of lateness penalty.

My test input data is with n = 9 and m = 3:

jobs_data = [[[(304776, 0, 'r2500', True, 2130458),
   (-1, 1, 'r2500', False, 2130458),
   (-1, 2, 'r2500', False, 2130458)]],
 [[(-1, 0, 'r1200', False, 1295928),
   (193491, 1, 'r1200', True, 1295928),
   (-1, 2, 'r1200', False, 1295928)]],
 [[(215173, 0, 'v3750', False, 1428522),
   (-1, 1, 'v3750', False, 1428522),
   (-1, 2, 'v3750', False, 1428522)]],
 [[(20226, 0, 'v3000', False, 369014),
   (20226, 1, 'v3000', False, 369014),
   (-1, 2, 'v3000', False, 369014)]],
 [[(222962, 0, 'r2500', False, 6517387),
   (222962, 1, 'r2500', False, 6517387),
   (-1, 2, 'r2500', False, 6517387)]],
 [[(-1, 0, 'r1700', False, 1266091),
   (-1, 1, 'r1700', False, 1266091),
   (80988, 2, 'r1700', False, 1266091)]],
 [[(-1, 0, 'r1350', False, 5138051),
   (-1, 1, 'r1350', False, 5138051),
   (89880, 2, 'r1350', False, 5138051)]],
 [[(-1, 0, 'r1200', False, 5699494),
   (131899, 1, 'r1200', False, 5699494),
   (-1, 2, 'r1200', False, 5699494)]],
 [[(-1, 0, 'r1200', False, 505015),
   (-1, 1, 'r1200', False, 505015),
   (126922, 2, 'r1200', True, 505015)]]]

with a list of n jobs containing m alternative tasks with [processing time, machine_id, resource/material, job already active on machine?, deadline/due date].

Now I created the variable l_lateness. lateness_seconds at the moment is the difference between the scheduled end_time and the deadline.

l_lateness = model.NewIntVar(-horizon_due_date, horizon_due_date, 'l_lateness')
lateness_seconds = (l_end - job[0][0][4])

model.Add(l_lateness ==  lateness_seconds)

termin.append(l_lateness)

I then use the variable in the objective as follows:

# Objective.
  makespan = model.NewIntVar(0, horizon, 'makespan')
  model.AddMaxEquality(makespan, job_ends)
  makespan_weight = 1
  transition_weight = 3
  deadline_weight = 5
  print(type(sum(termin)))
  print(type(sum(switch_literals)))
  model.Minimize(makespan * makespan_weight +
                 sum(switch_literals) * transition_weight +
                 sum(termin) * deadline_weight)

This works fine. But I want

lateness_seconds = max(0,(l_end - job[0][0][4]))

so that only the jobs where the deadline wasn't met count.

If I do this, then I get the following error message and I don't understand why or how to avoid it:

NotImplementedError: Evaluating a BoundedLinearExpr as a Boolean value is not supported.

I tried to rewrite it as

if l_end >= job[0][0][4]:
  model.Add(ueberzogen ==  (l_end - job[0][0][4]))
else:
  model.Add(ueberzogen ==  0)

But that gives me the same error for the expression l_end >= job[0][0][4].

I am using ortools Version: 9.0.9048.

Svenja K
  • 11
  • 2
  • Maybe a duplicate of https://stackoverflow.com/questions/67535624/google-or-tools-notimplementederror-evaluating-a-boundedlinearexpr-as-a-boolean – Max Ostrowski May 27 '21 at 08:24
  • I know you can encounter this error when you use something like model.Add(lower_bound <= variable <=upper_bound). And you can avoid it with model.Add(variable >= lower_bound) model.Add(variable <=upper_bound). But I don't understand why model.Add(variable1 == max(0, variable2-c) ) triggers the error, but model.Add(variable1 == (variable2-c) ) don't. – Svenja K May 27 '21 at 08:34
  • 2
    Isn't "max" the Python function, not one from OR Tools? To use a quantity in the objective you have to construct it as a solver variable, for example using AddMaxEquality. – cph May 27 '21 at 10:02

1 Answers1

3

We have added pedantic tests in version 9.0 because using min(), max() and other python constructs will not produce a valid model.

Please use AddMinEquality() or AddMaxEquality().

Laurent Perron
  • 4,884
  • 1
  • 4
  • 21