1、数学建模简明教程,国家精品课程,第十章 LINGO软件使用 简介及技巧,一、LINGO使用介绍,二、利用LINGO求解优化模型实例,三、LINGO调用VC编写的函数动态库技巧,LINGO是一种专门用于求解数学规划问题的,广泛应用LINGO主要用于求解线性规划、非,线性规划、二次规划和整数规划等问题,也可以,于求解一些线性和非线性方程组及代数方程求根等.,本章介绍的LINGO可在LINGO5.0,Ling8.0,,Ling9.0等版本中使用.,软件包.,一、LINGO使用介绍,1. LINGO编写格式,LINGO模型以MODEL开始,以END结束.中间,为语句,分为四大部分(SECTION):,
2、(1) 集合部分(SETS):这部分以“SETS:”,开始,以“ENDSETS”结束.,在LINGO中称为集合(SET)及其元素,(MEMBER或ELEMENT,类似于数组的下标)和,属性(ATTRIBUTE,类似于数组).,LINGO中的集合有两类:一类是原始集合,(PRIMITIVE SETS),其定义的格式为:,SETNAME/member list(or 1n)/:,attribute,attribute,etc.,另一类是导出集合(DERIVED SETS),即,引用其它集合定义的集合,其定义的格式为:,SETNAME(set1,set2,etc.):,attribute,attri
3、bute,etc.,(2) 目标与约束:这部分定义了目标函数、约束,条件等.一般要用到LINGO的内部函数.,(3) 数据部分(DATA):这部分以“DATA:”,开始,以“END DATA”结束.,其作用在于对集合的属性(数组)输入必要的数,值.格式为:attribute=value_list.该部分主要是方便数,据的输入.,(4) 初始化部分(INIT):这部分以“INIT:”开,始,以“END INIT”结束.作用在于对集合的属性,(数组)定义初值.格式为:attribute=value_list.,编写LINGO程序要注意:,(1) 所有的语句除SETS、ENDSETS、DATA、,E
4、NDDATA、 INIT、ENDINIT 和 MODEL,END,之外必须以一个分号“;”结尾.,(2) LINGO求解非线性规划时已约定各变量非负.,2. LINGO内部函数使用详解.,LINGO建立优化模型时可以引用大量的内部函数,,这些函数以“”符号打头.,2.1 常用数学函数,ABS(X) 返回变量X的绝对数值.,COS( X) 返回X的余弦值,X的单位为弧度.,EXP( X) 返回ex的值,其中e为自然对数的底,,即,FLOOR( X)向0靠近返回X的整数部分.,如FLOOR(3.7),则返回3;FLOOR(-3.7),则,返回-3.,LOG( X) 返回变量X的自然对数值.,SIG
5、N( X) 返回变量X的符号值,当X0时,为-1;当X0时为1.,SIN(X) 返回X的正弦值,X的单位为弧度.,SMAX(X1,X2,.,XN) 返回一列值X1,X2,.,XN的最大值.,SMIN(X1,X2,.,XN) 返回一列值X1,X2,.,XN的最小值.,TAN(X) 返回X的正切值,X的单位为弧度.,2.2 集合函数,用法:,set_operator (set_name|condition:expression),其中set_operator部分是集合函数名, set_name是数,据集合名, expression部分是表达式, condition部,分是条件,用逻辑表达式描述(无
6、条件时可省略).,逻辑表达式中可以三种逻辑算符(#AND#(与),#OR#(或),#NOT#(非)和六种关系算符 (#EQ#,(等于),#NE#(不等于),#GT#(大于),#GE#,(大于等于),#LT#(小于), #LE#(小于等于),常见的集合函数如下:,FOR (set_name:constraint_expressions)对集,合(set_name)的每个元素独立地生成约束,约束由,约束表达式(constraint_expressions)描述.,MAX(set_name:expression)返回集合上的,表达式(expression)的最大值.,MIN(set_name:exp
7、ression)返回集合上的,表达式(expression)的最小值.,SUM(set_name:expression)返回集合上的,表达式(expression)的和.,SIZE(set_name)返回数据集set_name中包,含元素的个数.,IN(set_name,set_element)如果数据集,set_name中包含元素set_element则返回1,否则返回0.,2.3 变量界定函数,变量函数对变量的取值范围附加限制,共有四种.,BND(L,X,U)限制LXU.,BIN(X)限制X为0或1.,FREE(X)取消对X的符号限制(即可取任意,实数值).,GIN(X)限制X为整数值.,
8、二、利用LINGO求解优化模型实例,1某昼夜服务的公交路线每天各时间区段内需,司机和乘务人员如下:,设司机和乘务人员分别在各时间区段一开始上班,,并连续工作八小时,问该公交线路至少配备多少名司,机和乘务人员?从第一班开始排,试建立线性模型.,解,人员总数为:,按所需人数最少的要求,可得到线性模型如下:,LINGO程序如下:,MODEL: min=x1+x2+x3+x4+x5+x6;x1+x6=60;x1+x2=70;x2+x3=60;x3+x4=50;x4+x5=20;x5+x6=30; END,得到的解为:,配备的司机和乘务人员最少为150人.,2. 某地区有三个农场共用一条灌渠,每个农,场
9、的可灌溉地及分配到的最大用水量如下表:,x1=60,x2=10,x3=50,x4=0,x5=30,x6=0;,各农场均可种植甜菜、棉花和高粱三种作物,,各种作物的用水量、净收益及国家规定的该地区各,种作物种植总面积最高限额如下表:,三个农场达成协议,他们的播种面积与其可灌,溉面积相等,而各农场种何种作物并无限制.问如何,制定各农场种植计划才能在上述限制条件下,使本,地区的三个农场的总净收益最大.,解,设农场1种植的甜菜、棉花和高粱分别为,亩,农场2种植的甜菜、棉花和高粱分,设三个农场可耕地分别为,其最大用水量分别为,其甜菜、棉花和高粱的种植限额分别为,根据题目条件,可建立如下线性模型:,其净收
10、益分别为,其耗水量分别为,LINGO编程如下:,MODEL: SETS: place/13/:a,b; kind/13/:c,d,e; plan(place,kind):x; ENDSETS DATA: a=400,600,300; b=600,800,375; c=600,500,325; d=3,2,1; e=400,300,100; ENDDATA max=sum(kind(j):e(j)*sum(place(i):x(i,j); for(kind(j):sum(place(i):x(i,j)=c(j); for(place(i):sum(kind(j):x(i,j)=a(i); for
11、(place(i):sum(kind(j):d(j)*x(i,j)=b(i); END,得到结果如下:,X(1,1)=0,X(1,2)=300,X(1,3)=0 X(2,1)=258.3333,X(2,2)=12.5,X(2,3)=0 X(3,1)=0,X(3,2)=187.5,X(3,3)=0,最大总净收益为253333.3元.,对本题来说,由于数据少,可以不采用数组形式,,而直接采用变量表示,建立模型如下:,亩.,设农场1种植的甜菜、棉花和高粱分别为,亩,农场2种植的甜菜、棉花和高粱分别为,亩,农场3种植的甜菜、棉花和高粱分别为,根据题目条件,可建立如下线性模型:,LINGO程序如下:,M
12、ODEL: max=400*(x1+x2+x3)+300*(y1+y2+y3)+100*(z1+z2+z3); x1+x2+x3=600; y1+y2+y3=500; z1+z2+z3=325; x1+y1+z1=400; x2+y2+z2=600; x3+y3+z3=300; 3*x1+2*y1+z1=600; 3*x2+2*y2+z2=800; 3*x3+2*y3+z3=375; END,得到的解如下:,X1=200,Y1=0,Z1=0;X2=58.33333,Y2=312.5,Z2=0; X3=0,Y3=187.5,Z3=0;,最大总净收益为253333.3元.,3公司在各地有4项业务,
13、选定了4位业务员去处,理.由于业务能力、经验和其它情况不同,4业务员去,处理4项业务的费用(单位:元)各不相同,见下表:,应当怎样分派任务,才能使总的费用最小?,则可以建立如下模型:,LINGO程序如下:,MODEL: SETS: person/14/; task/14/; assign(person,task):a,x; ENDSETS DATA: a=1100,800,1000,700,600,500,300,800,400,800,1000,900,1100,1000,500,700; ENDDATA min=sum(assign:a*x);for(person(i):sum(task(
14、j):x(i,j)=1);for(task(j):sum(person(i):x(i,j)=1);for(assign(i,j):bin(x(i,j); END,得到的结果如下:,最小费用为2100元.,即第1个业余员做第4项业务,第2个业余员做第2,第3项业务.总费用达到最小,为2100元.,LINGO程序中输入的数据也可以从文本文件中读,入,特别是数据比较多时,将程序与数据分开,显得,更方便.如上面程序也可以这样写:,MODEL: SETS: person/14/; task/14/; assign(person,task):a,x; ENDSETS DATA: a=file(data.t
15、xt); ENDDATA min=sum(assign:a*x); for(person(i):sum(task(j):x(i,j)=1); for(task(j):sum(person(i):x(i,j)=1); for(assign(i,j):bin(x(i,j); END,同时在LINGO目录下建立文本文件data.txt,数,据如下:,1100,800,1000,700 600,500,300,800 400,800,1000,900 1100,1000,500,700,其计算结果同上面相同.,4. 篮球队选队员问题篮球队要选择5名队员上场,组成出场阵容参加比赛.8名篮球队员的身高及擅
16、长位,置如下表:,出场阵容满足如下条件:,(1)只能有一名中锋上场;,(2)至少有一名后卫上场;,(4)2号和8号至少有1个不出场;,(3)如1号和4号均上场,则6号不出场;,问应当选择哪5名队员上场,才能使出场队员平均,身高最高?,解,这是一个0-1整数规划问题.,则目标函数很容易给出:,约束条件:,所选队员为5人,则,只能有一名中锋上场,则,至少有一名后卫,则,如1号和4号均上场,则6号不出场.则可用如下一,2号和8号至少有1个不出场,即2号和8号至多,数学模型:,个约束来表达:,出场1个.约束表达:,用LINGO编程如下:,MODEL: SETS: team/18/:a,x; ENDSE
17、TS DATA: a=1.92,1.90,1.88,1.86,1.85,1.83,1.80,1.78;!给出身高数据; ENDDATA max=sum(team(i):a(i)*x(i)/5.0; SUM(team(i):x(i)=5; !所选队员为5人; x(1)+x(2)=1; !只能有一名中锋上场; x(6)+x(7)+x(8)=1; !至少有一名后卫上场; x(1)+x(4)+x(6)=2; !如果1号和4号上场,则6号不上场; x(2)+x(8)=1; !2号和8号至少有一个不出场.即出场人数至多为1个; FOR(team(i):bin(x(i); !所有变量为0-1变量; END,
18、所得到的解为:,x(1)=0,x(2)=1,x(3)=1,x(4)=1,x(5)=1,x(6)=1,x(7)=0, x(8)=0,即第2,3,4,5,6名队员被选上.,最大平均身高为Z=1.864米,5. 有五项设计任务可供选择.各项设计任务的,分别为7,17,11,9,21(万元).设计任务只能一项,一项地进行,总的期限为20周.,选择任务时必须满足下面要求:,(1) 至少完成3项设计任务.,(2) 若选择任务1,必须同时选择任务2.,(3) 任务3和任务4不能同时选择.,应当选择哪些任务,才能使总的设计报酬最大?,解,这是一个0-1整数规划问题.,则容易得到目标函数:,根据题目要求分别列出
19、约束条件如下:,数学模型:,总期限为20周,则约束条件为,至少完成3项设计任务,则,若选择任务1,必须同时选择任务2,则,任务3和任务4不能同时选择,则,LINGO程序如下:,MODEL: SETS: mat/15/:m,t,x; ENDSETS DATA: m=7,17,11,9,21; !定义报酬数组; t=3,8,5,4,10; !定义完成时间; ENDDATA max=SUM(mat(i):m(i)*x(i); !定义目标函数; SUM(mat(i):t(i)*x(i)=3; !至少完成3项任务; x(2)=x(1); !若选择任务1,必须同时选择任务2; x(3)+x(4)=1; !
20、任务3和任务4不能同时选择; FOR(mat(i):BIN(x(i); !使各变量为0-1变量; END,得到的解为,x(1)=1,x(2)=1,x(3)=1,x(4)=0,x(5)=0.,最大报酬为35万元.,即在满足各种约束条件下,选择设计任务1,2,3,,可使总报酬达到最大为35万元.,6. 固定费用,有四种资源A,B,C,D被用于生产三种产品I, II,单耗量及组织三种商品生产的固定费用见下表.现要,求制定一个生产计划,使总收益最大.,解,可引入用0-1变量来解决是否需要固定费用问题.,第I种产品销售一件可收入7-4=3元,第II种产品,销售一件可收入10-6=4元,第III种产品销售
21、一件可,收入20-12=8元.,则问题的整数规划模型为:,.,LINGO程序.,MODEL: DATA: M=150; ENDDATA max=3*x1+4*x2+8*x3-100*y1-150*y2-200*y3;!目标函数; 2*x1+4*x2+8*x3=500; 2*x1+3*x2+4*x3=300; x1+2*x2+3*x3=100; 3*x1+5*x2+7*x3=700; x1=M*y1; x2=M*y2; x3=M*y3; GIN(x1);GIN(x2);GIN(x3); !指定产品件数为整数; BIN(y1);BIN(y2);BIN(y3); !指定0-1变量; end,最大值为
22、Z=200元.,7. 某企业和用户签定了设备交货合同,已知该,企业各季度的生产能力、每台设备的生产成本和每,季度末的交货量见下表,若生产出的设备当季度不,交货,每台设备每季度需要支付保管费0.1万元,试,问在遵守合同的条件下,企业应如何安排生产计划,,才能使年消耗费用最低?,解法1,LINGO程序如下:,MODEL: SETS: QUART/14/:x,y,p,d,c; ENDSETS DATA: !指定数据; p=25,35,30,20; d=15,20,25,20; c=12.0,11.0,11.5,12.5; ENDDATA min=sum(QUART(i):c(i)*x(i)+0.1*
23、y(i); !目标函数; FOR(QUART(i):x(i)=p(i); !生产能力限制; FOR(QUART(i)|i#GT#1:y(i)=y(i-1)+x(i)-d(i); y(1)=x(1)-d(1); end,得到的结果如下:,x1=15,x2=35,x3=30,x4=0;y1=0,y2=15, y3=20,y4=0.,年消耗最小费用为913.5万元.,解法2,下面条件:,根据交货量的规定,应满足如下条件:,其值如下表:,则该模型表示如下:,LINGO程序如下:,MODEL: SETS: QUART/14/:p,d; LINK(QUART,QUART)| End,得到的结果如下:,年消
24、耗最小费用为913.5万元.,为0台,与前面方法得到的结果一样.其最小费用也,可以看出,第1季度生产量为15台,第2季度生产,量为35台,第3季度生产量为30台,第4季度生产量,一样.,9. 旅行售货商问题(TSP问题),设有一个售货员从10个城市中的某一个城市出发,,去其它9个城市推销产品. 10个城市相互距离如下表.,要求每个城市到达一次仅一次后,回到原出发城市.,回到原出发城市.问他应如何选择旅行路线,使总路,程最短.,用来表示经过的各城市之间的路线.设,则该TSP问题转化为如下线性模型:,LINGO程序如下:,!TSP quesion; MODEL: SETS: city/110/;
25、link(city,city)| ENDDATA,MIN=SUM(link:d*s);SUM(city(j)|j#GT#1:S(j,1)=2; !与第1个城市相连的有两个城市;!与第i个城市相连有两个城市;FOR(city(i)|i#GT#1:SUM(city(j)|j#GT#i:s(j,i)+SUM(city(k)|k#LT#i:s(i,k)=2);FOR(link:BIN(s);,其最短路线为143375681091,,最短距离为77公里.,得到的结果如下:,优缺点分析:,该方法将TSP问题求解化为线性规划,采用,LINGO软件求解.优点是求解速度极快;缺点是可,能会形成一些子圈。无法真正
26、得到最优解.,解法二,各城市之间的路线.设,考虑每个城市后只有一个城市,则:,考虑每个城市前只有一个城市,则:,但仅以上约束条件不能避免在一次遍历中产生多于,一个互不连通回路.,充分约束条件:,于是我们可以得到如下的模型:,LINGO程序,!TSP quesion; MODEL: SETS: city/110/:u; link(city,city):d,s; ENDSETS DATA: d= 0 7 4 5 8 6 12 13 11 187 0 3 10 9 14 5 14 17 174 3 0 5 9 10 21 8 27 125 10 5 0 14 9 10 9 23 168 9 9 14
27、 0 7 8 7 20 196 14 10 9 7 0 13 5 25 1312 5 21 10 8 13 0 23 21 1813 14 8 9 7 5 23 0 18 1211 17 27 23 20 25 21 18 0 1618 17 12 16 19 13 18 12 16 0; ENDDATA,MIN=SUM(link:d*s);for(city(j):sum(city(i)|j#ne#i:s(i,j)=1); !城市j前有一个城市相连;for(city(i):sum(city(j)|j#ne#i:s(i,j)=1); !城市i后前有一个城市相连;for(link(i,j)|i#N
28、E#j#and#i#gt#1:u(i)-u(j)+10*s(i,j)=9);for(city(i)|i#gt#1:u(i)=8);FOR(link:BIN(s); end,三、LINGO调用VC编写的函数动态库技巧,下面通过一个实际的例子讲述Visual C+编写该,函数,然后用动态库的形式输出该函数供LINGO调用.,例,某公司生产A,B和C三种产品,售价分别是12元、,7元和6元.生产每件A产品需要1小时技术服务、10小,时直接劳动、3千克材料;生产每件B产品需要2小时,技术服务、4小时直接劳动、2千克材料;生产每件C,产品需要1小时技术服务、5小时直接劳动、1千克材,表.要求建立一个总利
29、润最大的数学模型.,料.现在最多能提供100小时技术服务、700小时直接,劳动、 400千克材料.生产成本是非线性函数,如下,分析与求解,件.问题的难点是产品的成本是一个分段函数,难,以用线性函数表达,因此可采用动态库编写一个专门,的函数来计算成本.,而改变.,目标函数为:,其中,由于目标函数是非线性的,采用自己编写用户函数,的方式来实现.,这里先介绍USER函数,该函数允许用户自己编写函数,该函数应当用C或,FORTRAN语言编写,返回值为用户计算的结果.,USER函数包含两个参数:第一个用于指定参数,的个数,第二个用于指定参数向量(类似于C语言中,的main(argc,argv)的编写格式
30、).在LINGO中调用,USER时则直接指定对应的参数(类似C语言中的,main(argc,argv)的执行格式).,该函数采用动态库编写.这里的例子采用VC编写动,态库.注意动态库中该函数名固定为MYUSER,在,LINGO中调用时则固定外部函数名为USER.,下面是VC中该动态库的编写过程:,1启动VC6.0,选择File-New.启动New属性单,,选择Projects页面.再选择WIN32 Dynamic-Link,Library.在右边Project name标签下的编辑框中任意,输入一个工程名.如CALC.点击OK命令按钮后就建,立了一个新的空的工程.,文件名.如CB.,2选择Pr
31、oject-Add to Project-New.在New,属性单中选择File页面.在下面空白框中选择C+,Source File.在右边File标签下的编辑框中输入一个,3编辑C+程序CB.CPP如下:,#include #include #include #include #include #define N 3 #define DllExport extern “C“ _declspec(dllexport) /该函数计算成本,DllExport void MYUSER(int* NumArgs, double *x, double *dResult) double sum;if(*N
32、umArgs=0 /返回成本总值 ,总数.第二个输入为向量x,就是外部输入的变量.第,注意在程序中MYUSER函数的第一个整型变量,NumArgs代表输入的变量个数.根据LINGO调用时输,入的变量个数,可以在C+程序内部得到输入变量的,程序计算的结果dResult.,三个变量dResult用于返回最后的计算结果.用LINGO,调用时只需要输入各变量就行了,函数自动返回C+,编好程序后,按F7运行后生成动态库CALC.DLL.,将其拷贝到LINGO目录下,并将文件名改名为,MYUSER.DLL.启动LINGO,就可以通过外部函数,USER调用动态库中自己编写的函数.,LINGO程序:,!采用动态库编写自己的函数; MODEL: max=12*x1+7*x2+6*x3-USER(x1,x2,x3); !目标函数; x1+2*x2+x3=100; !技术服务的约束; 10*x1+4*x2+5*x3=700; !直接劳动的约束; 3*x1+2*x2+x3=400; !材料的约束; GIN(x1); GIN(x2); GIN(x3); end,全局最优解.,迭代6步得到局部最优解为x1=70,x2=0,x3=0.,总利润最大为210元.容易验证,该局部最优解也是,再见,