You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OR-Tools实现任务优先级调度并最小化完工时间?

问题描述

车间未来两天需安排两项任务,仅配备1名操作员,每日只能完成1项任务。两项任务优先级不同,一项更紧急,另一项次之。需要确保在可行情况下优先安排更紧急的任务,同时实现该目标并最小化完工时间(Make Span)?

解决方案(OR-Tools SAT求解器实现)

以下是基于Google OR-Tools CP-SAT求解器的实现,已修正原代码的逻辑缺陷并将注释翻译为中文:

from ortools.sat.python import cp_model

model = cp_model.CpModel()

# 1. 数据定义
tasks = {0, 1}
# 任务紧急程度映射:100代表更紧急,10次之
task_to_urgency_level = {0: 10, 1: 100}
days = {0, 1}
# 每日可用操作员数量:每天1名
day_to_operator_resource = {0: 1, 1: 1}

# 2. 决策变量
max_date_index = max(days)
# 存储每个任务分配到的日期索引
variables_task_day_index = {
    task: model.NewIntVar(0, max_date_index, f"task_{task}_day") for task in tasks
}
# 任务-日期分配矩阵(布尔变量:1表示任务分配到对应日期)
variables_task_to_day_matrix = {
    (task, day): model.NewBoolVar(f"task_{task}_assigned_to_day_{day}")
    for task in tasks
    for day in days
}

# 3. 约束条件
# 每日任务数量不超过当日可用操作员数量
for day in days:
    model.Add(
        sum(variables_task_to_day_matrix[task, day] for task in tasks) <= day_to_operator_resource[day]
    )

# 每个任务只能分配到一个日期
for task in tasks:
    model.Add(
        sum(variables_task_to_day_matrix[task, day] for day in days) == 1
    )

# 关联分配矩阵与任务日期索引变量
for task in tasks:
    for day in days:
        model.Add(
            variables_task_day_index[task] == day
        ).OnlyEnforceIf(
            variables_task_to_day_matrix[task, day]
        )

# 核心约束:确保更紧急任务的分配日期不晚于次紧急任务
urgent_task = [t for t in tasks if task_to_urgency_level[t] == 100][0]
less_urgent_task = [t for t in tasks if task_to_urgency_level[t] == 10][0]
model.Add(variables_task_day_index[urgent_task] <= variables_task_day_index[less_urgent_task])

# 4. 目标函数:最小化完工时间(所有任务完成日期的最大值)
make_span = model.NewIntVar(0, 99999, "make_span")
model.AddMaxEquality(
    make_span,
    [variables_task_day_index[task] for task in tasks]
)
model.Minimize(make_span)

# 5. 求解并输出结果
solver = cp_model.CpSolver()
status = solver.Solve(model)

if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
    print("任务分配结果:")
    for day in days:
        for task in tasks:
            if solver.Value(variables_task_to_day_matrix[task, day]):
                urgency_desc = "更紧急" if task_to_urgency_level[task] == 100 else "次之"
                print(f"任务{task}({urgency_desc})→ 第{day+1}天")
    print(f"最小完工时间:{solver.Value(make_span)+1}天")
else:
    print("无可行解")
关键说明
  1. 修正原代码中task_to_urgency_level的结构:原集合无法对应任务与紧急度的映射,改为字典后才能区分任务优先级。
  2. 添加紧急任务优先约束:通过强制更紧急任务的分配日期不晚于次紧急任务,确保优先安排逻辑生效。
  3. 最优解逻辑:在满足紧急优先的前提下,最小化完工时间的结果为:更紧急任务安排在第1天,次紧急任务安排在第2天,完工时间为2天,这是唯一可行且最优的方案。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 12:57:11