In IBM's docplex optimization library, can you set an interval_var
's size parameter as a function of another variable? Meaning, say for this example I wanted to make the task size dependent on the skill level of the worker. If the worker has a skill level of 2 and another worker has a skill level of 1, the task is completed twice as fast with the first worker. So the size parameter of the interval_var
for that task should be the task.duration / skill_level
.
It is typically set as an integer value based on the documentation, so I am wondering if there is a workaround to make this possible.
From the example:
Task = (namedtuple("Task", ["name", "duration"]))
TASKS = {Task("masonry", 35),
Task("carpentry", 15),
Task("plumbing", 40),
Task("ceiling", 15),
Task("roofing", 5),
Task("painting", 10),
Task("windows", 5),
Task("facade", 10),
Task("garden", 5),
Task("moving", 5),
}
tasks = {} # dict of interval variable for each house and task
for house in HOUSES:
for task in TASKS:
tasks[(house, task)] = mdl.interval_var(start=period_domain,
end=period_domain,
size=task.duration,
name="house {} task {}".format(house, task))
There are two possibilities:
1- In general, if you have to handle workers with different skills, you will have also to handle the allocation of tasks to workers in the scheduling problem. In this case, for a given tasks (for instance 'masonry') you will create one optional interval variable per possible worker (or per skill) and you will specify the skill-related duration on this interval variable. See for example the delivered Python example "house_building_optional.py" (though in this example, we assume the duration is worker independent). So you will end up with a pattern like:
tasks = [ interval_var(name='Task{}'.format(i)) for i in ... ]
tasksOnWorkers = [ [ interval_var(optional=True, size=DURATION[i,j], name='Task{}_Worker{}'.format(i,j)) for j in ...] for i in ... ]
model.add(alternative(tasks[i], [tasksOnWorkers[i][j] for j in ...]) for i in ...)
Stated otherwise, in the example you mention you would not specify the size here:
tasks[(house, task)] = mdl.interval_var(start=period_domain,
end=period_domain,
size=task.duration,
name="house {} task {}".format(house, task))
But instead, here:
for house in HOUSES:
for skill in SKILLS:
iv = mdl.interval_var(name='H' + str(house) + '-' + skill.task + '(' + skill.worker + ')')
iv.set_optional()
wtasks[(house, skill)] = iv
2- The above method is the preferred one in case of resource allocation. But you can also use an integer expression length_of(intervalVar)
to constrain the length of the interval:
x = interval_var() # By default length is unconstrained in [0,INTERVAL_MAX)
model.add(length_of(x) == 'Whatever integer expression or variable in the model')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.