基于python的scip库使用,从基础模型到复杂模型,从一维变量到三维变量

这篇博客介绍了如何利用PySCIPOpt库来创建和解决优化问题。首先,展示了基本的模型创建,包括设置变量类型、目标函数和约束条件。接着,通过两个实例详细解释了模型的构建和求解过程:一个是简单的单变量模型,另一个涉及二维变量的复杂模型。博主还分享了一个未完成的三维变量模型示例。这些例子涵盖了离散变量、目标函数的最小化以及多种约束条件的设定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础知识

创建模型:model=Model(name)#name是模型名字

创建变量:model.addVar(vtype,name,lb=0,ub=1)#vtype是变量类型,有I(Integer)表示离散变量,B(Binary )表示0/1变量

创建目标函数: model.setObjective(coeffs,sense)#前者是目标函数,后者是"minisize"或者"maxsize"

创建约束条件:model.addCons(cons)#cons是约束条件

求解:model.optimize()#求解
model.getBestSol()#得到决策变量数值
model.getObjVal()#得到目标函数值

导入库

from pyscipopt import Model,quicksum

栗子1 单个变量+简单模型

<think>嗯,用户给了一个关于使用ortools处理调度问题的Python代码转换的问题。首先,我需要理解用户提供的代码结构和各个变量的含义。用户定义了一些集合,比如LOT、Operation、Machine_of_operation等,然后提到了两个约束条件:Lot的释放时间必须早于其开始处理的时间,机器的释放时间也必须早于任何Lot在该机器上的开始时间。 首先,我需要确认这些约束如何转化为ortools的线性规划约束。用户已经创建了一个三维字典s_lom来表示每个Lot在每个工序和机器上的开始时间。接下来,约束1和约束2分别涉及Lot的释放时间r_l和机器的释放时间r_m,需要确保这些时间都小于等于对应的s_lom变量。 接下来,我需要检查用户提供的Python代码是否有错误。例如,在Operation字典中,'O2'被错误地写成了'02',这可能会导致问题,因为键名不一致。此外,在遍历每个Lot的Operation时,用户使用了[0] + Operation.get((l, o), []),这似乎不正确,因为Operation的键是Lot的名称,如'L1',而不是元组(l, o)。正确的应该是Operation.get(l, []),然后遍历每个工序o。 然后,创建变量s_lom的部分可能需要调整,因为当前的循环结构可能错误地遍历了Machine_of_operation的所有工序,而不是每个Lot的特定工序。例如,对于每个Lot l,应该遍历其对应的Operation中的o,然后针对该o对应的机器列表添加变量。 在约束部分,用户提到的约束1和约束2需要为每个Lot l、其每个工序o,以及该工序可用的机器m添加约束。例如,对于约束1,每个Lot的每个工序的开始时间必须大于等于该Lot的释放时间。同样,约束2要求每个工序的开始时间必须大于等于该工序所用机器的释放时间。 此外,用户可能在初始化s_lom时存在错误,比如在循环中使用了[0] + Operation.get(...),这里的0可能是一个占位符,但实际应该处理每个Lot的Operation列表中的每个工序。需要修正循环结构,确保正确遍历每个Lot的工序。 最后,将这些约束用ortools的solver.Add()方法实现,确保每个s_lom[l][o][m]变量满足r_l <= s_lom[l][o][m]和r_m <= s_lom[l][o][m]的条件。同时,需要确保Machine_of_operation中的每个工序o对应的机器m被正确引用,例如'O1'对应的机器是'M1'和'M2',所以在添加约束时,应该只针对这些机器,而不是所有机器。 总结来说,需要修正Operation字典中的键错误,调整循环结构以正确遍历每个Lot的工序及其对应的机器,然后为每个变量添加相应的约束。此外,还需要确保在添加约束时,只针对每个工序可用的机器,而不是所有机器,避免不必要的约束和变量创建。</think>让我们逐步分析并构建这个调度问题的约束条件代码。以下是分步骤的中文说明: --- ### 一、问题分析与代码修正 首先发现原始代码存在两个关键错误需要修正: 1. **工序命名不一致**:`Operation`字典中`'02'`应为`'O2'`(字母O而非数字0) 2. **循环逻辑错误**:`for o in [0] + Operation.get((l, o), [])`应改为遍历`Operation[l]`中的工序 修正后的数据结构: ```python Operation = { # 修正后的工序定义 'L1': ['O1', 'O2', 'O3'], # ...其他LOT保持相同模式... } Machine_of_operation = { 'O1': {'M1':20, 'M2':25}, 'O2': {'M3':25, 'M4':25}, 'O3': {'M5':1, 'M6':1} } ``` --- ### 二、决策变量创建 需要为每个Lot的**每个工序**在其可选机器上创建变量: ```python from ortools.linear_solver import pywraplp solver = pywraplp.Solver.CreateSolver('SCIP') s_lom = {} for l in LOT: s_lom[l] = {} # 遍历该Lot的所有工序 for o in Operation[l]: # 修正循环逻辑 s_lom[l][o] = {} # 遍历该工序可用的机器 for m in Machine_of_operation[o]: s_lom[l][o][m] = solver.NumVar(0, solver.infinity(), f's_{l}_{o}_{m}') ``` --- ### 三、约束条件实现 #### 约束1:Lot释放后才能开始加工 $$ r_l \leq s_{l,o,m},\quad \forall l \in LOT, o \in Operation[l], m \in Machine[o] $$ ```python for l in LOT: r_l = Lot_release_time[l] for o in Operation[l]: for m in Machine_of_operation[o]: solver.Add(r_l <= s_lom[l][o][m]) ``` #### 约束2:机器可用后才能加工 $$ r_m \leq s_{l,o,m},\quad \forall l \in LOT, o \in Operation[l], m \in Machine[o] $$ ```python for o in Machine_of_operation: for m in Machine_of_operation[o]: r_m = Machine_release_time[m] for l in LOT: if o in Operation[l]: # 仅处理需要该工序的Lot solver.Add(r_m <= s_lom[l][o][m]) ``` --- ### 四、完整代码结构 ```python # 导入与数据初始化 from ortools.linear_solver import pywraplp # 数据定义(此处使用修正后的数据)... # 创建求解器 solver = pywraplp.Solver.CreateSolver('SCIP') # 创建决策变量 s_lom = {} for l in LOT: s_lom[l] = {} for o in Operation[l]: s_lom[l][o] = {} for m in Machine_of_operation[o]: s_lom[l][o][m] = solver.NumVar(0, solver.infinity(), f's_{l}_{o}_{m}') # 添加约束1 for l in LOT: r_l = Lot_release_time[l] for o in Operation[l]: for m in Machine_of_operation[o]: solver.Add(r_l <= s_lom[l][o][m]) # 添加约束2 for o in Machine_of_operation: for m in Machine_of_operation[o]: r_m = Machine_release_time[m] for l in LOT: if o in Operation[l]: solver.Add(r_m <= s_lom[l][o][m]) ``` --- ### 五、后续步骤建议 1. **添加目标函数**:例如最小化总完工时间 `makespan` 2. **添加工序顺序约束**:同一Lot的工序需按顺序执行 3. **添加资源冲突约束**:同一机器不能同时加工多个Lot 需要根据具体调度需求继续扩展模型
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值