如何在CPLEX中生成包含多个元素的集合Y?
问题原因分析
你的原有代码存在3个核心逻辑问题,导致Y只能生成单元素:
- 集合
Y的推导规则错误:你定义的{sum(i in I)Ea[i]*w[i]|x in 0..W-q , i in I: ok[i]==1 }中,sum(i in I)Ea[i]*w[i]是固定值,和迭代变量x、i完全无关,自然只会输出一个结果 rand仅执行1次:原有代码的集合E只会在模型初始化时生成1次随机值,对应的Ea和加权和也唯一,没有多次生成不同随机取值的逻辑ok数组逻辑冗余:ok[i in I]的判断条件sum(i in I)Ea[i]*w[i]<=W-q和下标i没有关联,所有ok[i]取值完全一致,该条件没有实际筛选作用
修改方案
调整为在execute执行块中循环多次生成随机集合E,每次计算合法的加权和后添加到集合Y中即可,示例修改代码如下:
int m=3 ; range I= 1..m; int w[i in I]=i; int q= min(i in I)w[i] ; int W=1000; {int} B={381,198,291}; // 预先定义可写的空集合Y {int} Y = {}; execute { // 可自定义需要生成的Y元素数量,此处示例生成10个不重复的合法值 var targetCount = 10; while(Y.size < targetCount) { // 每次循环重新生成随机集合E var E = new Set(); for(var f in B) { if(f>0) E.add(rand(f)); } // 计算当前E对应的加权和 var sumVal = 0; var j=1; for(var k in E) { sumVal += k * w[j]; j = j+1; } // 符合条件的取值加入Y,OPL集合会自动去重 if(sumVal <= W - q) { Y.add(sumVal); } } writeln("最终生成的Y集合:", Y); }
关键修改说明
- 将随机生成
E、计算加权和的逻辑放到循环中,每次生成不同的随机取值,得到多个不同的加权和 - 直接在
execute块中对可写集合Y做动态添加,利用OPL集合自动去重的特性保证元素唯一性 - 去掉了冗余的
Ea数组、ok数组和错误的Y集合推导逻辑,简化执行流程
内容的提问来源于stack exchange,提问作者Prarup
相关产品推荐
相关产品推荐

