属性 capacity的第2个和第3个值分别为34和20,其余的未知 3.2模型的初始部分 初始部分是 LINGO提供的另 选部分。在初始部分中,可以输入初始声明 ( initialization statement),和数据部分中的数据声明相同。对实际问题的建模时,初 始部分并不起到描述模型的作用,在初始部分输入的值仅被 LINGO求解器当作初始点来用, 并且仅仅对非线性模型有用。和数据部分指定变量的值不同, LINGO求解器可以自由改变初 始部分初始化的变量的值。 个初始部分以“init:”开始,以“ endinit”结束。初始部分的初始声明规则和数据 部分的数据声明规则相同。也就是说,我们可以在声明的左边同时初始化多个集属性,可以 把集属性初始化为一个值,可以用问号实现实时数据处理,还可以用逗号指定未知数值。 例3.9 init X,Y=0,:1; endinit X^2+¥^2<=1; 好的初始点会减少模型的求解时间 在这一节中,我们仅带大家接触了一些基本的数据输入和初始化概念,不过现在你应该 可以轻松的为自己的模型加入原始数据和初始部分啦。 11
11 属性 capacity 的第 2 个和第 3 个值分别为 34 和 20,其余的未知。 3.2 模型的初始部分 初始部分是 LINGO 提供的另一个可选部分。在初始部分中,可以输入初始声明 (initialization statement),和数据部分中的数据声明相同。对实际问题的建模时,初 始部分并不起到描述模型的作用,在初始部分输入的值仅被 LINGO 求解器当作初始点来用, 并且仅仅对非线性模型有用。和数据部分指定变量的值不同,LINGO 求解器可以自由改变初 始部分初始化的变量的值。 一个初始部分以“init:”开始,以“endinit”结束。初始部分的初始声明规则和数据 部分的数据声明规则相同。也就是说,我们可以在声明的左边同时初始化多个集属性,可以 把集属性初始化为一个值,可以用问号实现实时数据处理,还可以用逗号指定未知数值。 例 3.9 init: X, Y = 0, .1; endinit Y=@log(X); X^2+Y^2<=1; 好的初始点会减少模型的求解时间。 在这一节中,我们仅带大家接触了一些基本的数据输入和初始化概念,不过现在你应该 可以轻松的为自己的模型加入原始数据和初始部分啦
§4 LINGO函数 有了前几节的基础知识,再加上本节的内容,你就能够借助于 LINGO建立并求解复杂的 优化模型了 LINGO有9种类型的函数 1.1.基本运算符:包括算术运算符、逻辑运算符和关系运算符 2.2.数学函数:三角函数和常规的数学函数 3.3.金融函数: LINGO提供的两种金融函数 4.4.概率函数: LINGO提供了大量概率相关的函数 5.5.变量界定函数:这类函数用来定义变量的取值范围 6.6.集操作函数:这类函数为对集的操作提供帮助 7.7.集循环函数:遍历集的元素,执行一定的操作的函数 8.8.数据输入输出函数:这类函数允许模型和外部数据源相联系,进行数据的输入 输出 9.9.辅助函数:各种杂类函数 4.1基本运算符 这些运算符是非常基本的,甚至可以不认为它们是一类函数。事实上,在 LINGO中它们 是非常重要的 4.1.1算术运算符 算术运算符是针对数值进行操作的。LING0提供了5种二元运算符 乘方 乘除加减 LINGO唯一的一元算术运算符是取反函数“-”。 这些运算符的优先级由高到底为: 高-(取反) 低 运算符的运算次序为从左到右按优先级高低来执行。运算的次序可以用圆括号“()”来 改变。 例4.1算术运算符示例。 2-5/3,(2+4)/5等等 4.1.2逻辑运算符 在 LINGO中,逻辑运算符主要用于集循环函数的条件表达式中,来控制在函数中哪些集 成员被包含,哪些被排斥。在创建稀疏集时用在成员资格过滤器中, LINGO具有9种逻辑运算符: #not#否定该操作数的逻辑值,#not#是一个一元运算符 #eq#若两个运算数相等,则为true;否则为 flase #ne#若两个运算符不相等,则为true;否则为 flase #gt#若左边的运算符严格大于右边的运算符,则为true;否则为 flase #ge#若左边的运算符大于或等于右边的运算符,则为true;否则为flas #1t#若左边的运算符严格小于右边的运算符,则为true;否则为 flase #1e#若左边的运算符小于或等于右边的运算符,则为true:否则为 flase #and#仅当两个参数都为true时,结果为true;否则为 flase #or#仅当两个参数都为 false时,结果为 false;否则为true 这些运算符的优先级由高到低为: 高#not
12 §4 LINGO 函数 有了前几节的基础知识,再加上本节的内容,你就能够借助于 LINGO 建立并求解复杂的 优化模型了。 LINGO 有 9 种类型的函数: 1. 1. 基本运算符:包括算术运算符、逻辑运算符和关系运算符 2. 2. 数学函数:三角函数和常规的数学函数 3. 3. 金融函数:LINGO 提供的两种金融函数 4. 4. 概率函数:LINGO 提供了大量概率相关的函数 5. 5. 变量界定函数:这类函数用来定义变量的取值范围 6. 6. 集操作函数:这类函数为对集的操作提供帮助 7. 7. 集循环函数:遍历集的元素,执行一定的操作的函数 8. 8. 数据输入输出函数:这类函数允许模型和外部数据源相联系,进行数据的输入 输出 9. 9. 辅助函数:各种杂类函数 4.1 基本运算符 这些运算符是非常基本的,甚至可以不认为它们是一类函数。事实上,在 LINGO 中它们 是非常重要的。 4.1.1 算术运算符 算术运算符是针对数值进行操作的。LINGO 提供了 5 种二元运算符: ^ 乘方 ﹡ 乘 / 除 ﹢ 加 ﹣ 减 LINGO 唯一的一元算术运算符是取反函数“﹣”。 这些运算符的优先级由高到底为: 高 ﹣(取反) ^ ﹡/ 低 ﹢﹣ 运算符的运算次序为从左到右按优先级高低来执行。运算的次序可以用圆括号“()”来 改变。 例 4.1 算术运算符示例。 2﹣5/3,(2﹢4)/5 等等。 4.1.2 逻辑运算符 在 LINGO 中,逻辑运算符主要用于集循环函数的条件表达式中,来控制在函数中哪些集 成员被包含,哪些被排斥。在创建稀疏集时用在成员资格过滤器中。 LINGO 具有9种逻辑运算符: #not# 否定该操作数的逻辑值,#not#是一个一元运算符 #eq# 若两个运算数相等,则为 true;否则为 flase #ne# 若两个运算符不相等,则为 true;否则为 flase #gt# 若左边的运算符严格大于右边的运算符,则为 true;否则为 flase #ge# 若左边的运算符大于或等于右边的运算符,则为 true;否则为 flase #lt# 若左边的运算符严格小于右边的运算符,则为 true;否则为 flase #le# 若左边的运算符小于或等于右边的运算符,则为 true;否则为 flase #and# 仅当两个参数都为 true 时,结果为 true;否则为 flase #or# 仅当两个参数都为 false 时,结果为 false;否则为 true 这些运算符的优先级由高到低为: 高 #not#
#eq# #ne##gt##ge##lt##le# 低#and##or# 例4.2逻辑运算符示例 2#gt#3#and#4#gt#2,其结果为假(0)。 4.1.3关系运算符 在 LINGO中,关系运算符主要是被用在模型中,来指定一个表达式的左边是否等于、小 于等于、或者大于等于右边,形成模型的一个约束条件。关系运算符与逻辑运算符#eq#、#1e#、 #ge#截然不同,前者是模型中该关系运算符所指定关系的为真描述,而后者仅仅判断一个该 关系是否被满足:满足为真,不满足为假。 LINGO有三种关系运算符:“=”、“<=”和“>=”。 LINGO中还能用“<”表示小于等 于关系,“〉”表示大于等于关系。LING0并不支持严格小于和严格大于关系运算符。然而, 如果需要严格小于和严格大于关系,比如让A严格小于B A<B 那么可以把它变成如下的小于等于表达式: A+E<=B 这里ε是一个小的正数,它的值依赖于模型中A小于B多少才算不等, 下面给出以上三类操作符的优先级: 局#nOt# (取反) #eq##ne##gt##ge##It##le# #and# for# 低 4.2数学函数 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函数的自然对数 如果x<0返回-1:否则,返回1 @floor(x) 返回x的整数部分。当x>=0时,返回不超过x的最大整数:当x<0 时,返回不低于x的最大整数 @smax(x1,x2,…,xn)返回x1,x2,…,xn中的最大值 smin(x1,x2,…,xn)返回x1,x2,…,xn中的最小值 例4.3给定一个直角三角形,求包含该三角形的最小正方形 解:如图所示。 CE=asin x. AD=bcos x. DE acosx+bsin x 求最小的正方形就相当于求如下的最优化问题 min max CE, AD, DE E LINGO代码如下 model object/1.3/: fi endsets B dat
13 #eq# #ne# #gt# #ge# #lt# #le# 低 #and# #or# 例 4.2 逻辑运算符示例 2 #gt# 3 #and# 4 #gt# 2,其结果为假(0)。 4.1.3 关系运算符 在 LINGO 中,关系运算符主要是被用在模型中,来指定一个表达式的左边是否等于、小 于等于、或者大于等于右边,形成模型的一个约束条件。关系运算符与逻辑运算符#eq#、#le#、 #ge#截然不同,前者是模型中该关系运算符所指定关系的为真描述,而后者仅仅判断一个该 关系是否被满足:满足为真,不满足为假。 LINGO 有三种关系运算符:“=”、“<=”和“>=”。LINGO 中还能用“<”表示小于等 于关系,“>”表示大于等于关系。LINGO 并不支持严格小于和严格大于关系运算符。然而, 如果需要严格小于和严格大于关系,比如让 A 严格小于 B: A<B, 那么可以把它变成如下的小于等于表达式: A+ε<=B, 这里ε是一个小的正数,它的值依赖于模型中 A 小于 B 多少才算不等。 下面给出以上三类操作符的优先级: 高 #not# ﹣(取反) ^ ﹡ / ﹢﹣ #eq# #ne# #gt# #ge# #lt# #le# #and# #or# 低 <= = >= 4.2 数学函数 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 返回-1;否则,返回 1 @floor(x) 返回 x 的整数部分。当 x>=0 时,返回不超过 x 的最大整数;当 x<0 时,返回不低于 x 的最大整数。 @smax(x1,x2,…,xn) 返回 x1,x2,…,xn 中的最大值 @smin(x1,x2,…,xn) 返回 x1,x2,…,xn 中的最小值 例 4.3 给定一个直角三角形,求包含该三角形的最小正方形。 解:如图所示。 CE = asin x, AD = bcos x, DE = a cos x + bsin x, 求最小的正方形就相当于求如下的最优化问题: CE AD DE x min max , , 2 0 LINGO 代码如下: model: sets: object/1..3/: f; endsets data: A B C D DA E a b x
a,b=3,4;!两个直角边长,修改很方便 enddata f(1)=a* @sin(x) f()=b* @cos(x) min=8smax(f(1),(2),f(3)1() f(3)=a*@cos(x)+b*@ @bnd(0 7) 在上面的代码中用到了函数ebnd,详情请见4.5节 4.3金融函数 目前 LINGO提供了两个金融函数。 1. @fpa( I, n) 返回如下情形的净现值:单位时段利率为I,连续n个时段支付,每个时段支付单位费 用。若每个时段支付x单位的费用,则净现值可用x乘以efpa(I,n)算得。efpa的计算公式 为 1-(1+D)” (1+D) 净现值就是在一定时期内为了获得一定收益在该时期初所支付的实际费用 例4.4贷款买房问题贷款金额50000元,贷款年利率5.31%,采取分期付款方式(每 年年末还固定金额,直至还清)。问拟贷款10年,每年需偿还多少元? LINGO代码如下 50000=x*@fpa(.0531,10); 答案是x=6573.069元。 2.會fp1(I,n) 返回如下情形的净现值:单位时段利率为I,第n个时段支付单位费用。efpl(I,n)的 计算公式为 细心的读者可以发现这两个函数间的关系: @m(1,n)=∑@p(,k) 4.4概率函数 1. epon(p, n, x) 项分布的累积分布函数。当n和(或)x不是整数时,用线性插值法进行计算 2. @pcx (n, x) 自由度为n的x2分布的累积分布函数 3. Opeb (a, x) 当到达负荷为a,服务系统有x个服务器且允许无穷排队时的 Erlang繁忙概率 4. epel(a, x) 当到达负荷为a,服务系统有x个服务器且不允许排队时的 Erlang繁忙概率。 5. Pfd (n, d, x) 自由度为n和d的F分布的累积分布函数 6. epfs(a, x, c) 当负荷上限为a,顾客数为c,平行服务器数量为x时,有限源的 Poisson服务系统的 等待或返修顾客数的期望值。a是顾客数乘以平均服务时间,再除以平均返修时间。当c和 (或)x不是整数时,采用线性插值进行计算 7. phg(pop, g, n, x) 超几何( Hypergeometric)分布的累积分布函数。pop表示产品总数,g是正品数。从 所有产品中任意取出n(n≤pop)件。pop,g,n和x都可以是非整数,这时采用线性插值
14 a, b = 3, 4; !两个直角边长,修改很方便; enddata f(1) = a * @sin(x); f(2) = b * @cos(x); f(3) = a * @cos(x) + b * @sin(x); min = @smax(f(1),f(2),f(3)); @bnd(0,x,1.57); end 在上面的代码中用到了函数@bnd,详情请见 4.5 节。 4.3 金融函数 目前 LINGO 提供了两个金融函数。 1.@fpa(I,n) 返回如下情形的净现值:单位时段利率为 I,连续 n 个时段支付,每个时段支付单位费 用。若每个时段支付 x 单位的费用,则净现值可用 x 乘以@fpa(I,n)算得。@fpa 的计算公式 为 I I I n n k k − = − + = + 1 (1 ) (1 ) 1 1 。 净现值就是在一定时期内为了获得一定收益在该时期初所支付的实际费用。 例 4.4 贷款买房问题 贷款金额 50000 元,贷款年利率 5.31%,采取分期付款方式(每 年年末还固定金额,直至还清)。问拟贷款 10 年,每年需偿还多少元? LINGO 代码如下: 50000 = x * @fpa(.0531,10); 答案是 x=6573.069 元。 2.@fpl(I,n) 返回如下情形的净现值:单位时段利率为 I,第 n 个时段支付单位费用。@fpl(I,n)的 计算公式为 n I − (1+ ) 。 细心的读者可以发现这两个函数间的关系: = = n k fpa I n fpl I k 1 @ ( , ) @ ( , ) 。 4.4 概率函数 1.@pbn(p,n,x) 二项分布的累积分布函数。当 n 和(或)x 不是整数时,用线性插值法进行计算。 2.@pcx(n,x) 自由度为 n 的 χ 2 分布的累积分布函数。 3.@peb(a,x) 当到达负荷为 a,服务系统有 x 个服务器且允许无穷排队时的 Erlang 繁忙概率。 4.@pel(a,x) 当到达负荷为 a,服务系统有 x 个服务器且不允许排队时的 Erlang 繁忙概率。 5.@pfd(n,d,x) 自由度为 n 和 d 的 F 分布的累积分布函数。 6.@pfs(a,x,c) 当负荷上限为 a,顾客数为 c,平行服务器数量为 x 时,有限源的 Poisson 服务系统的 等待或返修顾客数的期望值。a 是顾客数乘以平均服务时间,再除以平均返修时间。当 c 和 (或)x 不是整数时,采用线性插值进行计算。 7.@phg(pop,g,n,x) 超几何(Hypergeometric)分布的累积分布函数。pop 表示产品总数,g 是正品数。从 所有产品中任意取出 n(n≤pop)件。pop,g,n 和 x 都可以是非整数,这时采用线性插值
进行计算 8. eppl (a, x) Poisson分布的线性损失函数,即返回max(0,z-x)的期望值,其中随机变量z服从均值 为a的 Poisson分布。 9. epps(a 均值为a的 Poissonη分布的累积分布函数。当ⅹ不是整数时,采用线性插值进行计算 10.@ps1(x) 单位正态线性损失函数,即返回max(0,z-x)的期望值,其中随机变量z服从标准正态 分布 11.@psn(x) 标准正态分布的累积分布函数 2. eptd(n, x) 自由度为n的t分布的累积分布函数。 13. @grand (seed) 产生服从(0,1)区间的拟随机数。@ grand只允许在模型的数据部分使用,它将用拟随机 数填满集属性。通常,声明一个m×n的二维表,m表示运行实验的次数,n表示每次实验所 需的随机数的个数。在行内,随机数是独立分布的:在行间,随机数是非常均匀的。这些随 机数是用“分层取样”的方法产生的 例4.5 M=4;N=2;seed=1234567 enddat sets rows/1.M/ cols/1.N/ table(rows, cols):i X=@qrand(seed) enddata 如果没有为函数指定种子,那么 LINGO将用系统时间构造种子。 14. @rand (seed) 返回0和1间的伪随机数,依赖于指定的种子。典型用法是U(I+1)=rand(U(I))。注 意如果seed不变,那么产生的随机数也不变。 例4.6利用 grand产生15个标准正态分布的随机数和自由度为2的t分布的随机数 model !产生一列正态分布和t分布的随机数; seLs series/1.15/: u, norm endsets !第一个均匀分布随机数是任意的; grand(.1234); 产生其余的均匀分布的随机数 for( serles(工)|工#GT#1: I)=grand( u( I -1) efor( serles(工) 正态分布随机数 epsn( norm(工))=u(工) !和自由度为2的t分布随机数;
15 进行计算。 8.@ppl(a,x) Poisson 分布的线性损失函数,即返回 max(0,z-x)的期望值,其中随机变量 z 服从均值 为 a 的 Poisson 分布。 9.@pps(a,x) 均值为 a 的 Poisson 分布的累积分布函数。当 x 不是整数时,采用线性插值进行计算。 10.@psl(x) 单位正态线性损失函数,即返回 max(0,z-x)的期望值,其中随机变量 z 服从标准正态 分布。 11.@psn(x) 标准正态分布的累积分布函数。 12.@ptd(n,x) 自由度为 n 的 t 分布的累积分布函数。 13.@qrand(seed) 产生服从(0,1)区间的拟随机数。@qrand 只允许在模型的数据部分使用,它将用拟随机 数填满集属性。通常,声明一个 m×n 的二维表,m 表示运行实验的次数,n 表示每次实验所 需的随机数的个数。在行内,随机数是独立分布的;在行间,随机数是非常均匀的。这些随 机数是用“分层取样”的方法产生的。 例 4.5 model: data: M=4; N=2; seed=1234567; enddata sets: rows/1..M/; cols/1..N/; table(rows,cols): x; endsets data: X=@qrand(seed); enddata end 如果没有为函数指定种子,那么 LINGO 将用系统时间构造种子。 14.@rand(seed) 返回 0 和 1 间的伪随机数,依赖于指定的种子。典型用法是 U(I+1)=@rand(U(I))。注 意如果 seed 不变,那么产生的随机数也不变。 例 4.6 利用@rand 产生 15 个标准正态分布的随机数和自由度为 2 的 t 分布的随机数。 model: !产生一列正态分布和 t 分布的随机数; sets: series/1..15/: u, znorm, zt; 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); !和自由度为 2 的 t 分布随机数;