求解流程
1)定义常量:可以通过float、int、boolean定义常量。定义范围是为了便于对数组进行操作。
//定义常量
int F = ...;//定义整型
float R=...;//定义浮点型
int m=...;
int B = ...;
//定义范围
range nF=1..F;
range Machs = 1..m;
- 定义常量数组
//定义数组常量
float dta[nF,Machs]=...;
- 如果需要由两个变量初始化一个变量,可以进行如下操作
-这与(float wj[j in Jobs][m in Machs][r in rv]=ptime[j in Jobs][m in Machs][r in rv]*wv[r];)结果不同。
float wj[j in Jobs][m in Machs][r in rv]=ptime[j][m][r]*wv[r];
2)定义变量:dvar关键字定义变量
dvar boolean x[Jobs0][nF][Machs][Jobs0];
dvar float+ Cr[worker,Jobs];
dvar float+ Cmax;
3)目标函数:minimize
4)约束
forall、sum,minl、maxl、min、max
- maxl和minl是求括号内的最小值,既可以用于定义int minl(int,…);也可以用于约束中。
forall(r in worker) TWC[r]==maxl(y[r],z[r]);
- min和max的用法与sum类似,就是求组内最大值
forall (m in machs) Time[m]==max(l in Jobs) Cr[l]-S[l]*uw[m];
CPLEX中range实现取并集运算
- 目的:在CPLEX的OPL语言中,不支持range定义的范围的取并集运算,但是想要获得不连续的range 范围。
- 使用not in将连续范围进行打断,迂回实现取并集的操作。
range T1 = 1..4;
range T2 = 7..9;
range T3 = 5..6;
range T4 = 1..9;
dvar int x[T4][T4];
subject to
{
forall(j in T1)sum(i in T4:i not in T3)x[i][j] == 1;
}
//可以实现range范围T1和T2的并集,通过i in T4:i not in T3将全集中的某个range集合去除之后得到其他range范围的并集。
设置cplex求解时间
- 在模型文件中,目标函数前添加代码:execute PARAMS {cplex.tilim = 100;}
- 如果求解的例子过小,cplex的优化时间太小,最后显示的时间可能会大于设置的求解时间限制
数据初始化
- 在execute脚本的初始化数据(预处理模块)
range r =1..2;
int values1[r][r];
execute ct1{
for (i in r)
{
for (j in r)
{
if (i == 2*j)
values[i][j] = i+j;
}
writeln(values1);
}
}
- 声明数组时初始化
int values2[i in r][j in r] = (i == 2*j)?i+j:0;
int a[i in 1..10] = i+1;
int m[i in 0..10][j in 0..10] = 10 *i +j;
execute ct2{
writeln(values2);
writeln(a);
writeln(m);
}
模型常用线性化方法
1.Max/Min
2.绝对值
Maxmin/Minmax目标函数
fixed cost目标函数
分布式目标函数
6.逻辑或
乘积式