一、工厂合并
(一) 工厂合并——生产二维矩阵
【引入】
sets:
factory /1..6/ : a;
plant /1..8/ : d;
Cooperation(factory,p lant) : c, x;
endsets
以上程序可以得到以下结论:
- Cooperation大工厂是由factory和plant两家小工厂合并而办,可生产6*8的矩阵。
- a是1*6的矩阵,d是1*8的矩阵,c和x都是6*8的矩阵。
- 如果将Cooperation(factory,p lant)中的factory与plant调换位置,则生产8*6的矩阵。
- 工厂合并的名字Cooperation是随便起的,矩阵的名字c和x也是随便起的。
(二)矩阵的赋值
【引入】
data:
c=6,2,6,7,4,2,5,8
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
【例题】
【程序】
model:
sets:
factory /1..6/ : a;
plant /1..8/ : d;
Cooperation(factory,p lant) : c, x;
endsets
data:
a=60,55,5 1,43,41,52;
d=35,37,22,32,41,32,43,38;
c=6,2,6,7,4,2,5,8
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( Cooperation(i,j) : c(i,j)*x(i,j) );
@for( factory(i): @sum(plant(j):x(i,j)) <= a(i) );
@for( plant(j): @sum(factory(i):x(i,j)) = d(j) );
end
二、运算符
(一) 算术运算符
【例】若x=2,求解的数值。
x = 2;
y = 3*x^10 + 6/(15-x^(1/2));
(二)关系运算符
① 关系运算符往往用在约束条件中,用来指定约束条件左右两边必须满足的关系。
② Lingo只有三种关系运算符:“=”、“>=”以及“<=”。
没有单独的“>”和“<”,若出现,Lingo则视为省略了“=”。
若想严格表达A大于B,可以用以下方式:
B = 10; e = 0.0001; A - e > B;
(三)逻辑运算符
【定义】
分类 | 运算符 理解 作用 |
两个数字之间 | # eq # equal 两个运算对象相等为真 |
# ne # not equal 两个运算对象不相等为真 | |
# gt # greater than 左边大于右边为真 | |
# ge # greater equal 左边大于等于右边为真 | |
# lt # less than 左边小于右边为真 | |
# le # less equal 左边小于等于右边为真 | |
两个逻辑表达式之间 | # not # 非门 单目运算符,表示取反 |
# and # 与门 左右两边均正确才为真 | |
# or # 或门 左右两边均错误才为假 |
【唯一出现的位置】
a) for循环与sum求和。
b) if判断中。
【例1】
若矩阵a=[6,5,4,3,2,1],用集合的语言求解a(5)+a(6)。
model:
sets:
factory / 1..6 / : a;
endsets
data:
a = 6,5,4,3,2,1;
enddata
y = @sum( factory(i) | i#ge#5 : a(i) );
end
上式中,i#ge#5对sum求和的范围进行了限制,当然也可以写i#gt#4。
【例2】
若矩阵a由六个元素组成,且a(i)>5,i=1,2,5,6。求矩阵a各元素求和的最小值。
model:
sets:
factory / 1..6 / : a;
endsets
min = @sum(factory : a);
@for( factory(i) | i#lt#3 #or# i#ge#5 : a(i)>5 );
end
三、Lingo内置函数
(一)if判断
【例1】
① Lingo默认所有变量不为负数,故应先进行定义域自由化。
② if函数语法简单,看一眼即可学会。
@free(x);
@free(y);
x = -10; ! 给x一个随机的初值
y = @if( x#ge#0 , x+10 , x-10 );
【例2】
① 0<=x<=500可以x#ge#0 #and# x#le#500,也可以直接x#le#500。
② if函数的嵌套功能:
x = 1500; ! 给x一个随机的初值
y = @if( x#le#500 ,4*x , @if( x#gt#1000 , 1 500+2*x , 500+3*x ));
【提示】
① if函数通常仅仅在分段函数处出现,一般其出现频率、使用次数十分之低。
② Lingo中的if函数,必须自带一个else。
(二) 变量定界函数
函数 | 作用 |
@bin(x) @gin(x) @bnd(a,x,b) @free(x) | 限制x只能取0或1,可用于0−1规划 限制x为整数,在整数规划中特别有用 限制a x b,推荐直接替换两个约束条件 取消对变量x非负的限制,使其定义域自由 |
【@free】
求函数 z=(x+2)^2 +(y−2)^2的最小值。
@free(x);
@free(y);
min = (x+2)^2 + (y-2)^2;
【@bnd】
求函数y=2x在(1,3)之间的最大值。
@bnd(1,x,3);
max = 2*x;
【@bin】
已知a=[2,9,3,8,10,6,4,10以及b=1,3,4,3,3,1,5,10,求以下线性规划:
model:
sets:
factory / 1..8 / : a,b,x;
endsets
data:
a = 2,9,3,8,10,6,4,10;
b = 1,3,4,3,3,1,5,10;
enddata
max = @sum(factory : a*x );
@sum(factory : b*x ) < 15;
@for( factory : @bin(x) );
end
【@gin】
已知a=[2.1 1.0 1.8 1.2 2.0 1.2]以及b=[6 125 12500 345 5],求整数规划:
model:
sets:
factory / 1..6 / : a,x;
plant / 1..5 / :b;
coo(factory,p lant) : c;
endsets
data:
a=2.1 1.0 1.8 1.2 2.0 1.2;
b=6 125 12500 345 5;
c=0.45 20 41 5 22 0.3
0.45 28 4065 5 0.35
0.65 40 850 43 0.6
0.4 25 75 27 0.2
0.5 26 76 48 0.4
0.5 75 235 8 0.6;
enddata
max = @sum( factory : a*x );
@for( p lant(j) : @sum(factory(i):c(i,j)*x(i)) <= b(j) );
@sum( factory : x )=14;
x(2)<=3;
x(4)<=2;
@for( factory(i) | i#ne#2 #and# i#ne#4 : @bnd(1,x(i),4) );
@for( factory : @gin(x) );
end
(三) 数学函数
类别 | 函数名 返回值 |
三角函数 | @sin(x) 返回x的正弦值 @cos(x) 返回x的余弦值 @tan(x) 返回x的正切值 |
指数对数 | @log(x) 返回x的自然对数值,其他底数用换底公式 @exp(x) 返回xe的值,因e的数值无法敲入而诞生 |
其它 | @abs(x) 返回x的绝对值 @sigh(x) 返回x的符号值,x³0为1,x<0为−1 @floor(x) 返回x的整数部分,向靠近0的方向取整 |
比较大小 | @smax(x1, x2,……, xn) 返回其中的最大值 @smin(x1, x2,……, xn) 返回其中的最小值 |
【例1】
求解sin( 3.14159) +log^1024_2 +|−10| +e^0。
y = @sin(3.14159) + @log(1024) / @log(2) + @abs(-10) + @exp(0);
(四)集合操作函数
设factoty工厂生产6个元素的矩阵:
类别 | 函数名 作用 |
熟人 | @for( factory : a>0 ) 循环 @sum( factory : a ) 求和 |
有用 | @prod( factory : a ) 求积 @max( factory : a ) 求最大值 @min( factory : a ) 求最小值 |
鸡肋 | @in( factory , c ) 判断常数c是否在集合中 @size( factory ) 返回工厂可生产矩阵的长度 |
【例1】
model:
sets:
factory / 1..6 / : a;
endsets
data:
a = 6,5,4,3,2,1;
enddata
prod = @prod(factory : a);
greater = @max(factory : a);
less = @min(factory : a);
in = @in(factory,5);
size = @size(factory);
end