目录索引
- ==直接求解:==
- ==基本约束条件书写:==
思考:
- ==多段式编程:==
模板:
问题引入:
解法:
- 第一句:
- 第二、三句:
- 第四句:
直接求解:
首先我们进行最简单的Lingo求解,在这一类问题中我们不需要使用集合语言,直接按照题目所给的内容翻译即可。
例如这个问题,我们直接照猫画虎在Lingo中输入即可
min = 3*x1 + x2 - x3;
x1 + x2 - 2*x3 >= 2;
x1 - 2*x2 + x3 >= 2;
3*x1 + 2*x2 -x3 = 14;
x3 <= 1;
值得注意的是,在Lingo中所有的变量都是默认大于0的,所以可以省略大于0的约束条件。并且大于等于小于等于均可直接写为大于或者小于,在Lingo中这二者等同
基本约束条件书写:
@表示是一个函数:
- @gin(x):表示x是一个整数
- @bin(x):表示变量为0或1
- @bnd(l,x,u):表示变量x位于[l,u]之间的实数
- @free(x):表示x是任意实数,可以取消默认大于0的约束
思考:
如果我们要约束x为[-5,5]之间的整数该如何做?
@free(x);
@bnd(-5,x,5);
@gin(x);
首先先变为实数,再确定实数所在的范围,最后再约束为整数即可
多段式编程:
模板:
sets:
集合段,所有集合数据都写在这里
endsets
data:
数据段,可以把所有已知的数据都以矩阵的形式写在这里
enddata
约束段写在下方一栏
问题引入:
解法:
1.先确定指标个数,比如Ai表示第几个人,那么总共有四个人也就是说i会从1到4,Bj也同理,j会从1到4。那么我们就需要创建一个集合,在这个集合中所有元素都表示有4个数值
2.确定指标联系,我们设立变量为Cij。例如派A的1号选手去做B3件事,就是C13。
sets:
S/1..4/: a;
T/1..4/: b;
U(S,T): f,c;
endset
U(S,T): f,c;
其实就是创立了一个矩阵,S行T列的矩阵,从C(1,1),C(1,2)依次建立到C(4,4)
至于f的变量则是一个0-1变量,如果是0则代表不指派i人做j事,如果为1则反之。
data:
c = 3 14 10 5
10 4 12 10
9 14 15 13
7 8 11 9;
enddata
我们对于c数据是已知的,而对于f数据是我们要求的结果。c输入的顺序就是(1,1),(1,2)到(4,4)。到这里我们不难发现,a和b是不需要写的,但为了更加清晰易懂故写了上去
min = @sum(S(i):@sum(T(j):f(i,j)*c(i,j)));
@for(S(i):@sum(T(j):f(i,j))=1);
@for(T(j):@sum(S(i):f(i,j))=1);
@for(U(i,j):@bin(f(i,j)));
最后就是求解段了,我们来逐句分析。
第一句:
注意最小值是不需要写变量的,直接写min即可。@sum表示的就是一个求和函数,第一项S(i)表示对谁求和,用谁去迭代。你直接关注i,j属于哪个集合就可以了。 比方说i是从1到4的,属于集合S,那么S(i)则表示依次输入S(1),S(2),S(3),S(4)
第一句话实现了一个sum函数的嵌套,S(1)也就是i=1的大前提下,对每一个j进行迭代。
我这里使用伪Python代码来方便你理解:
min = 0
for i in range(1,4):
for j in range(1,4):
min = min + f(i,j)
第二、三句:
这两句的代码与第一句则是大同小异,仅有一点值得注意那就是最后这个等于号是落在sum函数的外头的,千万要记住!
第四句:
这是一个约束段,我们已经知道f(i,j)是一个0-1变量,但是这个约束是对所有f(i,j)都生效的,所以我们要进行一个循环约束。@for就是一个循环,对U(i,j)均进行循环约束。