03-第三章-Lingo基本函数-优化软件与应用-教学课件.ppt
主讲人:雒兴刚Email:Tel:83682292优化软件与应用Lingo有9种类型的函数:1基本运算符:包括算术运算符、逻辑运算符和关系运算符2数学函数:三角函数和常规的数学函数3金融函数:Lingo提供的两种金融函数4概率函数:Lingo提供了大量概率相关的函数5变量界定函数:这类函数用来定义变量的取值范围6集操作函数:这类函数为对集的操作提供帮助7集循环函数:遍历集的元素,执行一定的操作的函数8数据输入输出函数:这类函数允许模型和外部数据源相联系,进行数据的输入输出9辅助函数:各种杂类函数第三章 Lingo 基本函数基本运算符-算数运算符算术运算符是针对数值进行操作的。LINGO提供了5种二元运算符:乘方乘除加减Lingo唯一的一元算术运算符是取反函数“”。优先级:-,*and/,+and-算术运算符示例:253,(2 4)5等等。第三章 Lingo 基本函数基本运算符-逻辑运算符逻辑运算符主要用于集循环函数的条件表达式中,来控制在函数中哪些集成员被包含,哪些被排斥。在创建稀疏集时用在成员资格过滤器中。(#not#否定该操作数的逻辑值,not是一个一元运算符)运算符为TRUE时条件运算符为TRUE时条件#eq#若两个运算数相等#ne#若两个运算符不相等#gt#若左边的运算符严格大于右边的运算符#ge#若左边的运算符大于或等于右边的运算符#lt#若左边的运算符严格小于右边的运算符#le#若左边的运算符小于或等于右边的运算符#and#仅当两个参数都为true时#or#仅当两个参数都为true时第三章 Lingo 基本函数基本运算符-关系运算符(1)Lingo有三种关系运算符:“=”、“=”。(2)Lingo并不支持严格小于和严格大于关系运算符。(3)Lingo中还能用“”表示大于等于关系。(4)如让A严格小于B,那么:A+=B这里 是一个小的正数,它的值依赖于模型中A 小于B 多少才算不等。第三章 Lingo 基本函数数学函数abs(x)返回x的绝对值sin(x)返回x的正弦值,x采用弧度制cos(x)返回x的余弦值tan(x)返回x的正切值exp(x)返回常数e的x次方log(x)返回x的自然对数lgm(x)返回x的gamma函数(积分形式)的自然对数sign(x)如果x=0时,返回不超过x的最大整数;当x0时,返回不低于x的最大整数。smax(x1,x2,xn)返回x1,x2,xn中的最大值smin(x1,x2,xn)返回x1,x2,xn中的最小值Lingo提供了大量的标准数学函数:第三章 Lingo 基本函数数学函数A B C DE a b x例:给定一个直角三角形,求包含该三角形的最小正方形。其中:求最小的正方形就相当于求如下的最优化问题:第三章 Lingo 基本函数金融函数 1fpa(I,n)返回如下情形的净现值(净现值就是在一定时期内为了获得一定收益在该时期初所支付的实际费用):单位时段利率为I,连续n个时段支付,每个时段支付单位费用。若每个时段支付x单位的费用,则净现值可用x乘以fpa(I,n)算得。fpa的计算公式为:例:贷款买房问题贷款金额50000元,贷款年利率5.31%,采取分期付款方式(每年年末还固定金额,直至还清)。问拟贷款10年,每年需偿还多少元?LINGO代码如下:50000=x*fpa(.0531,10);答案是x=6573.069元。I=0.0531,n=10第三章 Lingo 基本函数金融函数 2fpl(I,n)返回如下情形的净现值:单位时段利率为I,第n个时段支付单位费用。fpl(I,n)的计算公式为:实际上:第三章 Lingo 基本函数概率函数7phg(pop,g,n,x)超几何(Hypergeometric)分布的累积分布函数。pop表示产品总数,g是正品数。从所有产品中任意取出n(npop)件。pop,g,n和x都可以是非整数,这时采用线性插值进行计算。8ppl(a,x)Poisson分布的线性损失函数,即返回max(0,z-x)的期望值,其中随机变量z服从均值为a的Poisson分布。9pps(a,x)均值为a的Poisson分布的累积分布函数。当x不是整数时,采用线性插值进行计算。10psl(x)单位正态线性损失函数,即返回max(0,z-x)的期望值,其中随机变量z服从标准正态分布。11psn(x)标准正态分布的累积分布函数。12ptd(n,x)自由度为n的t分布的累积分布函数。第三章 Lingo 基本函数概率函数14rand(seed)返回0和1间的伪随机数,依赖于指定的种子。典型用法是U(I+1)=rand(U(I)。注意如果seed不变,那么产生的随机数也不变。MODEL:SETS:series/1.15/:u,znorm;ENDSETS!第一个均匀分布随机数是任意的;u(1)=rand(.1234);!产生其余的均匀分布的随机数;for(series(I)|I#GT#1:u(I)=rand(u(I-1);for(series(I):!正态分布随机数;psn(znorm(I)=u(I);!ZNORM 和ZT 可以是负数;free(znorm(I););END例:利用rand 产生15个标准正态分布的随机数。SolveX:thevaluereturnedbyPSN(X)istheareaunderthecurvetotheleftofthepointontheordinateindicatedbyX取消对变量x的默认下界为0的限制第三章 Lingo 基本函数集操作函数LINGO提供了几个函数帮助处理集。1in(set_name,primitive_index_1,primitive_index_2,)如果元素在指定集中,返回1;否则返回0;常用来产生补集。例:全集为I,B是I的一个子集,C是B的补集。SETS:I/x1.x4/:x;B(I)/x2/:y;C(I)|#not#in(B,&1):z;ENDSETS2index(set_name,primitive_set_element)该函数返回在集set_name中原始集成员primitive_set_element的索引。如果set_name被忽略,那么LINGO将返回与primitive_set_element匹配的第一个原始集成员的索引。如果找不到,则产生一个错误。C 的第一个原始集,即I。翻译过来就是:I 里的成员,同时又不属于集合B第三章 Lingo 基本函数集操作函数3wrap(index,limit)该函数返回j=index-k*limit,其中k是一个整数,取适当值保证j落在区间1,limit内。该函数相当于index“模limit再加1”。该函数在循环、多阶段计划编制中特别有用。参见后面的例子4size(set_name)该函数返回集set_name的成员个数。在模型中明确给出集大小时最好使用该函数。它的使用使模型更加数据中立,集大小改变时也更易维护。第三章 Lingo 基本函数集循环函数集循环函数遍历整个集进行操作。其语法为function(setname(set_index_list)|conditional_qualifier:expression_list);function相应于后面罗列的四个集循环函数之一(for,sum,min,max);setname是要遍历的集;set_index_list是集索引列表;conditional_qualifier是用来限制集循环函数的范围,当集循环函数遍历集的每个成员时,LINGO都要对conditional_qualifier进行评价,若结果为真,则对该成员执行function操作,否则跳过,继续执行下一次循环。expression_list是被应用到每个集成员的表达式列表,当用的是for函数时,expression_list可以包含多个表达式,其间用逗号隔开。这些表达式将被作为约束加到模型中。当使用除for外的三个集循环函数时,expression_list只能有一个表达式。第三章 Lingo 基本函数集循环函数1for该函数用来产生对集成员的约束。基于建模语言的标量需要显式输入每个约束,不过for函数允许只输入一个约束,然后LINGO自动产生每个集成员的约束。例:产生序列1,4,9,16,25MODEL:SETS:number/1.5/:x;ENDSETSfor(number(I):x(I)=I2);END第三章 Lingo 基本函数集循环函数2sum该函数返回遍历指定的集成员的一个表达式的和。例:求向量5,1,3,4,6,10前5个数的和。MODEL:DATA:N=6;ENDDATASETS:number/1.N/:x;ENDSETSDATA:x=5134610;ENDDATAs=sum(number(I)|I#le#5:x);END第三章 Lingo 基本函数集循环函数3min和max返回指定的集成员的一个表达式的最小值或最大值。例:求向量5,1,3,4,6,10前5个数的最小值,后3个数的最大值。MODEL:DATA:N=6;ENDDATASETS:number/1.N/:x;ENDSETSDATA:x=5134610;ENDDATAminv=min(number(I)|I#le#5:x);maxv=max(number(I)|I#ge#N-2:x);ENDIterateallI第三章 Lingo 基本函数首先,我们需要解决的是,“有哪些集合,对应的属性是什么”,容易看到,我们需要表达一周7天,所以我们建立一个集合:SETS:DAYS;ENDSETS并进行初始化:SETS:DAYS;ENDSETSDATA:DAYS=MONTUEWEDTHUFRISATSUN;ENDDATA第三章 Lingo 基本函数综合实例:A Staff Scheduling Problem为了方便表达,我们也可以用Lingo 的隐性方法进行初始化:SETS:DAYS;ENDSETSDATA:DAYS=MON.SUN;ENDDATA下面我们考虑DAYS 集合的2个属性。一个是每天需要的员工数量,另一个是每天开始工作的员工个数(一旦开始工作就连续工作5天,然后休息2天),分别表示为REQUIRED和START:SETS:DAYS:REQUIRED,START;ENDSETS第三章 Lingo 模型初始化和基本函数综合实例:A Staff Scheduling Problem显然,REQUIRED是给定的参数,START是决策变量。根据题意,可以初始化如下:DATA:DAYS=MONTUEWEDTHUFRISATSUN;REQUIRED=20161316191412;ENDDATA下面我们考虑优化问题的目标,即一个星期内容雇佣的人员总数最小,这个目标可以表示为:Minimize:i STARTi第三章 Lingo 基本函数综合实例:A Staff Scheduling Problem我们知道一个员工是“五天工作+2 天休息”,那么今天工作的员工数量实际上是:Number working today=Number starting today+Number starting 1 day ago+Number starting 2 days ago+Number starting 3 days ago+Number starting 4 days ago.换句话说,为了计算今天工作的员工数量,我们需要把今天开始工作的员工数量,加上前面4天开始工作的员工的数量。前5天、6天开始工作的员工今天正好轮到休息。这可以表示为:i=j-4,j-3,j-2,j-1,j第三章 Lingo 基本函数综合实例:A Staff Scheduling Problem把上述数学表达式转换成lingo 语法:FOR(DAYS(J):SUM(DAYS(I)|I#LE#5:START(J-I+1)=REQUIRED(J);上面的表达仍然有一点问题,如果这样求解,lingo 会报错:I=1,2,3,4,5Start():J,J-1,J-2,J-3,J-4第三章 Lingo 基本函数综合实例:A Staff Scheduling ProblemLess&equal共5项因子相加SETS:DAYS:REQUIRED,START;ENDSETSDATA:DAYS=MONTUEWEDTHUFRISATSUN;REQUIRED=20161316191412;ENDDATAMIN=SUM(DAYS(I):START(I);FOR(DAYS(J):SUM(DAYS(I)|I#LE#5:START(J-I+1)=REQUIRED(J);START(0)出现了问题。START定义7个元素,索引是1-7。START(0)不存在,导致“下标出界”的错误。所以,我们需要把=0 的索引换算到上一个星期的对应日子,例如,0应该是星期日(7),-1是星期6(6),以此类推。LINGO 有一个函数可以实现此功能:WRAP:WRAP函数有2个参数:INDEXandLIMIT。WRAP函数返回J=INDEX-K*LIMIT,这里K 是一个整数,可以使J正好位于1,LIMIT。形象的说,WRAP 对INDEX 减掉或者加上LIMIT,直到它落在1 LIMIT 的范围内.本例中,我们正好需要这个函数把负的索引折算到一个星期的正确索引范围内。第三章 Lingo 基本函数综合实例:A Staff Scheduling Problem加入WRAP函数后,约束可以表达成:FOR(DAYS(J):SUM(DAYS(I)|I#LE#5:START(WRAP(J-I+1,7)=REQUIRED(J);因此,完整的lingo 模型可以表达为:第三章 Lingo 基本函数综合实例:A Staff Scheduling ProblemMODEL:SETS:DAYS:REQUIRED,START;ENDSETSDATA:DAYS=MONTUEWEDTHUFRISATSUN;REQUIRED=20161316191412;ENDDATAMIN=SUM(DAYS(I):START(I);FOR(DAYS(J):SUM(DAYS(I)|I#LE#5:START(WRAP(J-I+1,7)=REQUIRED(J);END第三章 Lingo 基本函数综合实例:A Staff Scheduling Problem第三章 Lingo 基本函数综合实例:A Staff Scheduling Problem目标值22代表,我们最少需要雇佣22个员工.我们需要安排这些员工的工作日期如下:尽管这个问题规模不是很大,大家可以试试,如果用手工去排出这个结果恐怕不会太容易。安排不当,每天的实际工作人数会超过需要的人数,造成浪费。第三章 Lingo 基本函数综合实例:A Staff Scheduling Problem