CPLEX供需匹配运输场景约束编写错误修正及原因咨询
CPLEX约束错误修正说明
原约束核心错误原因
- 需求约束逻辑完全错误:原约束对「每艘船+每个营地+每个月」单独校验,要求单艘船的运输量直接满足单个营地的全月需求,不符合多船共同补给的业务逻辑,也完全没有关联港口到营地的配送变量
y - 成本计算重复计数:总成本三个求和项均引入了无关索引,导致单成本项被重复计算多倍(例如预备成本求和额外遍历了营地、港口维度,单船成本被重复计算12次)
- 缺少必要的变量关联约束:没有绑定0-1变量
binx和运输量x的关系,也没有港口流量守恒约束、单船每月仅停靠一个港口的约束,变量之间逻辑完全割裂
修正后完整代码
/// Indices int nrofships = 8; range ships = 1..nrofships; int nrofports = 2; range ports = 1..nrofports; int nrofmonths = 5; range months = 1..nrofmonths; int nrofcamps = 6; range camps = 1..nrofcamps; // Parameters float capacity[ships] = [1.250, 2.740, 1.890, 4.980, 2.630, 16.000, 9.610, 3.540]; int demand[camps][months]= [[11, 5, 1, 1, 1],[3, 0, 3, 0, 2],[6, 3, 4, 3, 7],[5, 5, 5, 2, 6],[7, 1, 7, 1, 4],[0, 3, 5, 0, 0]]; int preparation[ships] = [250000, 655000, 412300, 876900, 470025, 3655000, 1914500, 700000]; int transportationcosts[ports][ships] = [[129, 132, 129, 132, 178, 160, 161, 144],[134, 155, 130, 139, 142, 139, 154, 122]]; int distributioncosts[ports][camps] = [[130, 81, 77, 83, 89, 116],[71, 125, 114, 85, 86, 86]]; // decision variable dvar float+ x[ships][ports][months]; // 船s在m月经港口p运输的货量占运力的比例 dvar float+ y[ports][camps][months]; // 港口p在m月向营地c配送的货量 dvar boolean binx[ships][ports][months]; // 船s在m月是否停靠港口p // 总成本表达式 修正:移除无关索引,避免重复计数 dexpr float TotalCost = sum(s in ships, p in ports, m in months) preparation[s]*binx[s][p][m] + sum(s in ships, p in ports, m in months) transportationcosts[p][s]*x[s][p][m]*capacity[s] + sum(p in ports, c in camps, m in months) distributioncosts[p][c]*y[p][c][m]; // 目标函数 minimize TotalCost; subject to { // 1. 需求约束:每个营地每月收到的所有港口配送总量≥需求 forall(c in camps, m in months) ctdemand[c][m]: sum(p in ports) y[p][c][m] >= demand[c][m]; // 2. 港口流量守恒:所有船运到港口p的总货量 = 港口p配送到所有营地的总货量 forall(p in ports, m in months) ctflow[p][m]: sum(s in ships) x[s][p][m] * capacity[s] == sum(c in camps) y[p][c][m]; // 3. 单船运输上限约束:船当月停靠港口时,运量不超过运力 forall(s in ships, p in ports, m in months) ctxcap[s][p][m]: x[s][p][m] <= binx[s][p][m]; // 4. 单船每月仅可停靠一个港口约束 forall(s in ships, m in months) ctoneport[s][m]: sum(p in ports) binx[s][p][m] <= 1; }
补充说明
如果x变量定义的是实际运输吨位数,可调整上限约束为x[s][p][m] <= capacity[s] * binx[s][p][m],同时去掉运输成本核算中的*capacity[s]即可。
内容的提问来源于stack exchange,提问作者BST
相关产品推荐
相关产品推荐

