线性规划 linear programming(LP)
前面部分代码全部运行再Lingo当中
问题假设
解决多元函数条件极值的问题,问题需要近似的满足:
- 比例性(决策变量对其余两种因素的贡献与自身成正比)
- 可加性 (两两决策变量的取值之间没有任何的关系)
- 连续性 决策变量取值是连续的,不是离散的
上面所说的东西都是假设的条件
三个因素
- 决策变量
- 目标函数
- 约束条件(必要时转换为整数规划)书本p109
模型求解
图解法:
对于二维的决策变量而言,最优解一定在凸多边形的顶点位置
推广到n维而言的话,一定在凸多面体的某个顶点处(可行域内)
程序演示
卖牛奶问题
model:
max=72*x1+64*x2;
[milk] x1+x2<50;
[time] 12*x1+8*x2<480;
[cpct] 3*x1<100;
end
结果演示效益的增量我们叫做资源的潜在价值,在经济学领域叫做影子价格。
目标函数的敏感系数(书本p100)
决策变量在最优解不变情况下的变化范围
执行设置完option后执行lingo range
资源约束右端项的分析(影子价格作用的条件范围)
上图下面的部分
但上面的两个问题仅仅是一个充分条件,并不意味着超出范围无利可图,需要重新构建模型讨论
补充见书本p103
约束条件转换为整数规划
书本p109 @gin
1.分解子问题
max=2*x1+3*x2+4*x3;
1.5*x1+3*x2+5*x3<600;
280*x1+250*x2+400*x3<60000;
@gin(x1);@gin(x2);@gin(x3);
END
2.引入01变量
max=2*x1+3*x2+4*x3;
1.5*x1+3*x2+5*x3<600;
280*x1+250*x2+400*x3<60000;
M=1000;
x1<M*y1;x1>80*y1;
x2<M*y2;x2>80*y2;
x3<M*y3;x3>80*y3;
@gin(x1);@gin(x2);@gin(x3);
@bin(y1);@bin(y2);@bin(y3);
END
3.非线性规划,万不得已都不用
分段函数线性规划
书本p111
1.非线性求解全部最优解(在lingo当中设置全局最优)
! 4.3节例2 (方法1);
Model:
Max= 4.8*x11 + 4.8*x21 + 5.6*x12 + 5.6*x22 - 10*x1 - 8*x2 - 6*x3;
x11+x12 < x + 500;
x21+x22 < 1000;
0.5*x11 - 0.5*x21 > 0;
0.4*x12 - 0.6*x22 > 0;
x=x1+x2+x3;
(x1 - 500) * x2=0;
(x2 - 500) * x3=0;
x1 < 500;
x2 < 500;
x3 < 500;
2.01变量转换为线性约束(整数规划)(全局最优)
01规划解决双变量的约束(等价)
! 4.3节例2(方法2);
Model:
Max= 4.8*x11 + 4.8*x21 + 5.6*x12 + 5.6*x22 - 10*x1 - 8*x2 - 6*x3;
x11+x12 < x + 500;
x21+x22 < 1000;
0.5*x11 - 0.5*x21 > 0;
0.4*x12 - 0.6*x22 > 0;
x=x1+x2+x3;
x1 < 500*y1;
x2 < 500*y2;
x3 < 500*y3;
x1>500*y2;
x2>500*y3;
@bin(y1);@bin(y2);@bin(y3);
end
3.直接处理分段函数(最具有一般性) 书本p112
! 4.3节例2(方法3);
Model:
sets:
points/1..4/: b, c, y, z;
endsets
data:
n=3;
b=0 500 1000 1500;
c=0 5000 9000 12000;
enddata
Max=4.8*x11 + 4.8*x21 + 5.6*x12 + 5.6*x22 - @sum(points: c*z);
x11+x12 < x + 500;
x21+x22 < 1000;
0.5*x11 - 0.5*x21 > 0;
0.4*x12 - 0.6*x22 > 0;
@for(points(k)|(k#NE#1)#AND#(k#NE#(n+1)):
z(k) < y(k-1) + y(k);
);
z(1)<y(1);
z(n+1)<y(n);
x= @sum(points: b*z);
@sum(points: z) = 1;
@sum(points: y) = 1;
@for(points: @bin(y););
end
指派问题(收益最大)01规划
指派运动员问题(分派)p114
! 4.4节例1;
MODEL:
sets:
person/1..5/;
position/1..4/;
link(person,position): c, x;
endsets
data:
c= 66.8, 75.6, 87, 58.6,
57.2, 66, 66.4, 53,
78, 67.8, 84.6, 59.4,
70, 74.2, 69.6, 57.2,
67.4, 71, 83.8, 62.4;
enddata
min=@sum(link: c*x);
@for(person(i): @sum(position(j):x(i,j))<=1;);
@for(position(i):@sum(person(j):x(j,i))=1;);
@for(link: @bin(x));
END
选课策略与多目标规划
试探其他最优解(p116)
! 4.4节例2;
MODEL:
sets:
course/1..9/: c,x;
endsets
MIN = number;
number = @sum(course: x) ;
! number = 6;
x(1)+x(2)+x(3)+x(4)+x(5) > 2;
x(3)+x(5)+x(6)+x(8)+x(9) > 3;
x(4)+x(6)+x(7)+x(9) > 2;
2*x(3) - x(1) - x(2) < 0;
x(4) - x(7) < 0;
2*x(5) - x(1) - x(2) < 0;
x(6) - x(7) < 0;
x(8) - x(5) < 0;
2*x(9) - x(1) - x(2) < 0;
@for(course: @bin(x));
END
投资风险与二次规划
p132
均值方差模型,非线性规划
! 4.8节例1(投资组合);
MODEL:
Title 简单的投资组合模型;
SETS:
YEAR/1..12/;
STOCKS/ A, B, C/: Mean,X;
link(YEAR, STOCKS): R;
STST(Stocks,stocks): COV;
ENDSETS
DATA:
TARGET = 1.15;
! R是原始数据;
R =
1.300 1.225 1.149
1.103 1.290 1.260
1.216 1.216 1.419
0.954 0.728 0.922
0.929 1.144 1.169
1.056 1.107 0.965
1.038 1.321 1.133
1.089 1.305 1.732
1.090 1.195 1.021
1.083 1.390 1.131
1.035 0.928 1.006
1.176 1.715 1.908;
ENDDATA
CALC: !计算均值向量Mean与协方差矩阵COV;
@for(stocks(i): Mean(i) =
@sum(year(j): R(j,i)) / @size(year) );
@for(stst(i,j): COV(i,j) = @sum(year(k):
(R(k,i)-mean(i))*(R(k,j)-mean(j))) / (@size(year)-1) );
ENDCALC
[OBJ] MIN = @sum(STST(i,j): COV(i,j)*x(i)*x(j));
[ONE] @SUM(STOCKS: X) = 1;
[TWO] @SUM(stocks: mean*x) >= TARGET;
END
98年A题
! 4.8节例2(投资收益与风险);
MODEL:
SETS:
stock/S0..S4/: r, q, p, u, x, c, f;
points/1..11/: Lamda, Risk, Revenue; ! 选择11个不同的权值分别计算;
ENDSETS
DATA:
r = 0.05,0.28,0.21,0.23,0.25; !收益率;
q = 0,0.025,0.015,0.055,0.026; !风险率;
p = 0,0.01,0.02,0.045,0.065; !手续费率;
u = 0,103,198,52,40; ! 手续费阈值;
M = 10000; !总资金;
EPS = 0.000001; !判定投资量是否为0的阈值;
Lamda_start = 0; !权值起始值;
Lamda_add = 0.1; !权值增量;
ENDDATA
SUBMODEL OBJ:
MIN = Weight * MaxQ - (1-Weight) * Reve;
ENDSUBMODEL
SUBMODEL CONS:
MaxQ = @max(stock: q * x);
Reve = @sum(stock: r * x - c);
@for(stock:
f = x + c;
c = @if(x#LT#EPS, 0, p * @smax(u,x));
);
M = @sum(stock: f);
ENDSUBMODEL
CALC:
! 系统参数设置;
! 输出详细结果;
@SET( 'TERSEO', 0);
! 关闭求解状态窗口;
@SET( 'STAWIN', 0);
! 分别求解不同广告费上限的优化问题;
@FOR( POINTS( K):
Weight = Lamda_start + (K-1) * Lamda_add;
@SOLVE( OBJ, CONS);
Lamda( K) = Weight;
Risk ( K) = MaxQ;
Revenue(K)= Reve;
);
! 显示结果;
@WRITE( ' 权值 风险(元) 收益(元)', @NEWLINE( 1));
@FOR( POINTS: @WRITE( @FORMAT( Lamda, '#16.6G'),
@FORMAT( Risk, '#16.6G'),
@FORMAT( Revenue, '#16.6G'), @NEWLINE( 1))
);
ENDCALC
END
下面使用matlab绘图
% 4.8节 例2 (投资风险问题):绘图
clc, clear all,
data=[ 0.700000 247.525 2673.27
0.766000 247.525 2673.27
0.767000 92.2858 2164.63
0.810000 92.2509 2164.82
0.811000 78.4930 2105.99
0.824000 78.4933 2105.99
0.825000 59.3960 2016.24
0.962000 59.3960 2016.24
0.963000 2.97000 575.817
0.964000 2.97000 575.817
0.965000 2.85795 572.798
0.966000 0.000000 500.000
1.00000 0.000000 500.000];
Risk=data(:,2);
Revenue=data(:,3);
plot(Risk,Revenue,'-')
grid
xlabel('风险(元)')
ylabel('收益(元)')
完结