目 录
- 项目式 实践教学
^_^
- 朴实无华的Lingo
o_o
- 先写框架少出bug
>_<
Level-1 界面
不区分大小写,语句可以直接跨行。
Level-2 集合
指派问题
例:6个仓库,8个客户,原始集合相当于一维数组。派生集合可为二维数组
要求的变量设为x。目标函数运费最小。
sets:
cangku/1..6/:a;
kehu/1..8/:d;
erwei(cangku,kehu):c,x;
endsets
data:
a=60,55,51,43,41,52;
d=35,37,22,32,41,32,43,38;
c=6,2,6,7,4,2,5,9,
4,9,5,3,8,5,8,2,
5,2,1,9,7,4,3,3,
7,6,7,3,9,2,7,1,
2,3,9,5,7,2,6,5,
5,5,2,2,8,1,4,3;
enddata
min=@sum(erwei(i,j):c(i,j)*x(i,j));
@for(cangku(i):@sum(kehu(j):x(i,j))<=a(i));
@for(kehu(j):@sum(cangku(i):x(i,j))=d(j));
现在输出的结果界面不直观,期望输出如下表。
防止输入错误,可复制粘贴。
Level-3 设置&函数
多起点全局求解
一般不勾选Use Global Solver,但需要多起点初始值(下图)。
min=x * @cos(3*x);
@bnd(0,x,6.25);
")
逻辑运算符
关系运算符
Lingo没有严格的>、<,可以加减很小的数来代替计算。
x+0.0000001 <= b;
函数
集合操作函数
值班问题
值班问题,注意星期七
@for(zhiban(i):z-x(@wrap(i+1,7)) - x(@wrap(i+2,7)) >= r(i));
- 注:@wrap(i+1,7),可以把8变成1,9变成2。
变量定界函数
@bin(x) | 0-1 |
---|---|
@bnd(L,x,U) | @bnd( -1, x, 1); -1<=x<=1 |
@gin(x) | 整数 |
@free(x) | 实数 |
值班问题还要加整数约束
@for(zhiban(i):@gin(x(i)));
如果针对所有的成员,可以省略数组的标号,但不建议省略。
背包问题:0-1规划
sets:
wupin/1..8/:a,c,x;
endsets
data:
a=1,3,4,3,3,1,5,10;
c=2,9,3,8,10,6,4,10;
b=15;
enddata
max=z;
z=@sum(wupin(i):c(i)*x(i));
@sum(wupin(i):a(i)*x(i))<=b;
@for(wupin(i):@bin(x(i)));
其他函数:@if
@if 用于写分段函数,多次调用
fx=@if(x #le# 500,4*x, @if(x #le# 1000,500+3*x,1500+2*x));
Level-4 数据库
txt数据操作
!仓库点;
WH1 WH2 WH3 WH4 WH5 WH6 ~
!客户成员;
V1 V2 V3 V4 V5 V6 V7 V8 ~
~是txt文件数据库中一条结束语标志,按行顺序读取。
Excel数据操作
sets:
cangku/1..6/:a;
kehu/1..8/:d;
erwei(cangku,kehu):wv,x;
endsets
data:
a,d,wv=@ole('运输模型 3.3.xlsx');
enddata
min=@sum(erwei(i,j):wv(i,j)*x(i,j));
@for(cangku(i):@sum(kehu(j):x(i,j))<=a(i));
@for(kehu(j):@sum(cangku(i):x(i,j))=d(j));
data:
@ole('result.xlsx')=x;
enddata
- Excel表中定义名称不能为c
- 文件与代码同路径更方便
- 名称管理器可修改定义名称
稀疏集合
直接列举法
有序问题
满足i<j下的i、j,
只用下标,不是数组变量
sets:
renwu/A,B,C,D,E,F,G,H,I,J,K/:t;
station/1..4/;
paixu(renwu,renwu)/A,B, B,C, C,F, C,G, F,J,
J,K, G,J, D,E, E,H, E,I, H,J, I,J/;
fenpei(renwu,station):x;
endsets
data:
t=45,11,9,50,15,12,12,12,12,8,9;
enddata
min=z;
@for(station(k):@sum(renwu(i):t(i)*x(i,k))<=z);
@for(renwu(i):@sum(station(k):x(i,k))=1);
@for(paixu(i,j)|(i #lt# j): @sum(station(k):k*x(j,k)-k*x(i,k))>=0);
@for(fenpei(i,j):@bin(x(i,j)));
data:
@ole('result 3.5.xlsx')=x;
enddata
data:
!两次编写忘了写冒号(:);
enddata
元素过滤法
如何定义上三角二维数组?
加逻辑运算条件,占位符&
sets:
zhiyuan/1..8/;
hezuo(zhiyuan,zhiyuan)|(&1 #lt# &2):c,x;
endsets
data:
c=9,3,4,2,1,5,6,
1,7,3,5,2,1,
4,4,2,9,2,
1,5,5,2,
8,7,6,
2,3,
4;
enddata
min=z;
z=@sum(hezuo(i,j)|(i #lt# j):c(i,j)*x(i,j));
@for(zhiyuan(i): @sum(hezuo(j,k)|( (j#eq#i)#or#(k#eq#i) ):x(j,k))=1);
@for(hezuo(i,j)|(i #lt# j):@bin(x(i,j)));
Level-5 算法
最短路径
动态规划,没有目标函数。
Lingo中嵌入了群体智能算法。
sets:
cities / A, B, C, D, E, F G /: f;
roads( cities, cities ) / A,B A,C B,D B,E B,F C,D C,E C,F D,G E,G F,G /: W, P;
endsets
data:
w = 2, 4, 3, 3, 2, 2, 3, 1, 1, 3, 4;
enddata
N = @size( cities );
f( N ) = 0;
@for( cities( i ) | i #lt# N :
f( i ) = @min( roads( i, j ) : w( i, j ) + f( j ) ) );
@for( roads( i, j ) : p( i, j ) =
@if( f( i ) #eq# w( i, j ) + f( j ), 1, 0 ) );
w是对应路段的权重,
最后额外加一句选择路径表示出来。
看结果从A到G。
旅行商
sets:
city/1..6/:u;
erwei(city,city):c,x;
endsets
data:
c=0,702,454,842,2396,1196,
702,0,324,1093,2136,764,
454,324,0,1137,2180,798,
842,1093,1137,0,1616,1857,
2396,2136,2180,1616,0,2900,
1196,764,798,1857,2900,0;
enddata
min=z;
z=@sum(erwei(i,j):c(i,j)*x(i,j));
@for(city(i):@sum(city(j)|(i#ne#j):x(i,j))=1);
@for(city(j):@sum(city(i)|(i#ne#j):x(i,j))=1);
@for(erwei(i,j):@bin(x(i,j)));
n=@size(city);
@for(erwei(i,j)|((j#ne#1)#and#(i#ne#j)):
u(i)-u(j)+n*x(i,j) <= n-1);
data:
@ole('旅行商路径.xlsx')=x;
enddata