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

CPLEX OPL中如何定义含i<j或i≠j下标的决策变量xijk

嘿,作为一个经常和OPL打交道的老玩家,我太懂你这种冗余变量的烦恼了!其实用OPL的集合功能就能完美解决这个问题,下面给你两种常见场景的方案:

方案1:仅保留i < j的变量(最常用,适合顺序建模)

因为你的x[i][j][k]是表示工件i和j在机器k上的加工顺序,其实只需要存i < j的情况就够了——比如x[<i,j>][k] = 1就代表i在j前面加工,0就代表j在i前面,完全不需要重复定义x[<j,i>][k],这样直接砍掉一半冗余变量!

具体代码这么写:

int jobsNum = ...; 
int machinesNum = ...; 
range jobs = 0..jobsNum-1; 
range machines = 0..machinesNum-1; 

// 先定义所有满足i < j的工件对集合
{tuple(int i, int j)} jobPairs = {<i,j> | i,j in jobs : i < j};

// 基于这个集合定义决策变量,只生成需要的xijk
dvar boolean x[jobPairs][machines];

之后写约束的时候,直接遍历jobPairs就行,比如要表示机器k上任意两个工件有且只有一种顺序,就不用再写x[i][j][k] + x[j][i][k] = 1,而是直接用x[<i,j>][k]的0/1值来对应两种情况,简洁又高效。

方案2:保留i ≠ j的变量(特殊场景用)

如果你的业务逻辑确实需要区分所有i≠j的情况(比如某些双向约束场景),那也可以定义排除i=j的集合:

{tuple(int i, int j)} jobPairs = {<i,j> | i,j in jobs : i != j};
dvar boolean x[jobPairs][machines];

这种写法会去掉所有i=j的无用变量,但保留i<j和j<i的对,适合确实需要双向变量的场景。

为什么这么做?

这样定义的核心是用OPL的集合过滤功能,提前把无效的下标排除在外,从根源上减少决策变量的数量——尤其是当工件数很多的时候,变量数的减少会大幅提升求解器的运行速度,避免冗余计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:39:37