如何解决Ortools-Jobshop-根据任务在计算机上的排名修改任务持续时间
我正在处理车间的一个变体,我希望根据机器时间表中的任务分配/等级来修改任务持续时间。
例如一种简单的情况是,在计算机上分配的第一个任务将花费50%的时间才能完成。
更一般的情况是,计算机上的每n个任务都需要更长的X%的时间。
我已经阅读了有关通道约束的信息,但是我不确定如何在这种情况下实现它们,或者是否还有其他更好的选择。任何方向将不胜感激。
from __future__ import print_function
import collections
# Import Python wrapper for or-tools CP-SAT solver.
from ortools.sat.python import cp_model
def MinimalJobshopSat():
"""Minimal jobshop problem."""
# Create the model.
model = cp_model.CpModel()
jobs_data = [ # task = (machine_id,processing_time).
[(2,1),(0,(1,1)],# Job0
[(0,# Job1
[(1,(2,1)] # Job2
]
machines_count = 1 + max(task[0] for job in jobs_data for task in job)
all_machines = range(machines_count)
# Computes horizon dynamically as the sum of all durations.
horizon = sum(task[1] for job in jobs_data for task in job)
# Named tuple to store information about created variables.
task_type = collections.namedtuple('task_type','start end interval')
# Named tuple to manipulate solution information.
assigned_task_type = collections.namedtuple('assigned_task_type','start job index duration')
# Creates job intervals and add to the corresponding machine lists.
all_tasks = {}
machine_to_intervals = collections.defaultdict(list)
for job_id,job in enumerate(jobs_data):
for task_id,task in enumerate(job):
machine = task[0]
duration = task[1]
suffix = '_%i_%i' % (job_id,task_id)
start_var = model.NewIntvar(0,horizon,'start' + suffix)
end_var = model.NewIntvar(0,'end' + suffix)
interval_var = model.NewIntervalVar(start_var,duration,end_var,'interval' + suffix)
all_tasks[job_id,task_id] = task_type(
start=start_var,end=end_var,interval=interval_var)
machine_to_intervals[machine].append(interval_var)
# Create and add disjunctive constraints.
for machine in all_machines:
model.AddNoOverlap(machine_to_intervals[machine])
# # Precedences inside a job.
# Change constraint to only respect the project start date i.e. the first dummy task
for job_id,job in enumerate(jobs_data):
for task_id in range(len(job) - 1):
model.Add(all_tasks[job_id,task_id + 1].start >= all_tasks[job_id,task_id].end)
在这种情况下,我们期望修改后的输出如下,其中每台计算机上的第一个任务的持续时间增加了50%
Optimal Schedule Length: 4
Machine 0: job_1_0 job_0_1
[0,2] [2,3]
Machine 1: job_2_0 job_0_2 job_1_1
[0,3] [3,4]
Machine 2: job_0_0 job_2_1
[0,3]
解决方法
看看这个constraint,它创建了一个电路约束,该约束将优先级递减地转换为一系列任务。
现在,您可以使用每个任务的start literal来暗示正确的持续时间
model.Add(duration[i] == int(nominal_duration * 1.5)).OnlyEnforceIf(start_lit)
model.Add(duration[i] == nominal_duration).OnlyEnforceIf(start_lit.Not())
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。