一、线性规划基础
(一)方法
① 一个线性规划中只含一个目标函数。(两个以上是多目标线性规划,Lingo无法直接解)
② 求目标函数的最大值或最小值分别用max = …或min = …来表示。
③ 以!开头,以;结束的语句是注释语句;
④ 线性规划和非线性规划的本质区别是目标函数是否线性,其余一致,故不需要区分。
但值得注意的是,非线性规划的求解十分困难,基本得不到全局最优解。
(二)例题
某工厂有两条生产线,分别用来生产M和P两种型号的产品,利润分别为200元/个和300元/个,生产线的最大生产能力分别为每日100和120,生产线每生产一个M产品需要1个劳动日(1个工人工作8小时称为1个劳动日)进行调试、检测等工作,而每个P产品需要2个劳动日,该厂工人每天共计能提供160劳动日,假如原材料等其他条件不受限制,问应如何安排生产计划,才能使获得的利润最大?
(三)解
设两种产品的生产量分别为x1和x2,则该问题的数学模型为:
目标函数:max z=200x1+300x2
约束条件为:
x1<=100
x2<=200
x1+2*x2<=160
xi>=0, i=1,2
(四)程序
max = 200*x1 + 300*x2;
x1 <= 100;
x2 <= 120;
x1 + 2*x2 <= 160;
由Lingo信息可知,运行时间依旧0秒,目标值为29000,此时x1是100,x2是30。
二、矩阵工厂
(一)矩阵工厂:生产一维矩阵
先来看看例子,不必在意其中的空格(Lingo不读取空格):
sets:
factory /1..6/ : a,b;
plant /1..3/ : x,y;
endsets
以上程序对应知识点:
① factory和plant都是制造矩阵的工厂,但它们是两家不同的工厂。
② factory工厂后面的 /1..6/ 说明它专门生产1*6的矩阵。
factory工厂最后面出现的a和b,都是1*6的矩阵。
③ plant工厂后面的 /1..3/ 说明它专门生产1*3的矩阵。
plant工厂最后面出现的x和y,都是1*3的矩阵。
④ 矩阵工厂的名字factory是随便起的,工厂所生产行矩阵的名字a和b也是随便起的。
⑤ 以上这四句话,本质是定义了四个行矩阵的大小,矩阵工厂只是中介。
⑥ 生产完矩阵后,工厂和矩阵之间将脱开联系。
⑦ Lingo不是一行一行读代码的,所以用sets:和endsets表示矩阵工厂生产流程的起止。
(二) 矩阵的赋值
矩阵工厂不能只生产矩阵,还要给矩阵赋初值才行,例子如下:
sets:
factory /1..6/ : a,b;
plant /1..3/ : c,x;
endsets
data:
a = 1, 2, 3, 4, 5, 6;
b = 6.0, 5.0, 4.0, 3.0, 2.0, 1.0;
c = 10, 20, 30;
enddata
以上程序对应以下知识点:
① 不是每个矩阵都要赋值,有些矩阵正是我们要求解的变量。
② 需要赋值的矩阵必须赋满,不能给6个元素的矩阵只赋3个数值。
③ Lingo中可以给矩阵赋整数,也可以赋小数。
④ Lingo不是一行一行读代码的,所以用data:和enddata表示矩阵赋值的起止。
(三) 循环与求和
【例】已知模型如下,请编程求解:
【for循环】
题中约束条件:i=1,2,…,5可以利用for循环一步到位。
@for( gc(i) : a(i)*x(i) = S );
① for循环,括起整行语句,因为S=ai*xi,i=1,2,…,5,相当于5个约束条件;
② for循环内部,先写工厂,以告诉for循环几次,之后再上接约束条件。
③ 此处的i可带可不带,甚至可以换成j、k或m等等。
④ 二维矩阵工厂出现后,同时会出现i和j,那时必须带i和j。
【sum求和】
题中约束条件,可以利用sum求和一步到位。
@sum( gc(i) : x(i) ) = 5000;
① sum求和,不可以括起完整的约束条件,因为一般的求和的结构是这样的: x1+x2+x3+x4+x5=5000
② sum求和内部,先写工厂,以告诉sum求和几次,之后再上接约束条件。
③ 此处的i可带可不带。
④ 二维矩阵工厂出现后,同时会出现i和j,那时必须带。
【for与sum出现的标志】
① 约束条件后面有i=1,2,…,5一定在最外层套上for。
② 约束条件前面是出现求和符号å,一定在中间加上sum。
-
【例题】
【程序】
model:
sets:
gc /1..5/ : a,x;
endsets
data:
a = 1,2,3,4,5;
enddata
max = S;
@for( gc(i) : a(i)*x(i) = S );
@sum( gc(i) : x(i) ) = 5000;
end
PS:使用了矩阵工厂创建矩阵后,整个程序需用model:和end包起来。