最近学习了AMPL,感觉和LINGO建模语言比较相似。不过感觉使用起来更方便,并且有许多商业和开源的求解器支持AMPL,尤其开源的,这为我们的开发带来了便利。AMPL官方站点http://www.ampl.com/不可不看,当前提供了一个全功能测试版,可以下载试用。这是一个网上的免费优化服务器:http://www-neos.mcs.anl.gov/,网站中介绍了一些支持AMPL的求解器。这里有更多关于优化求解器的信息:http://plato.asu.edu/guide.html。
AMPL是一种广泛应用的、有效的、灵活的代数建模语言,可以把它看作一种脚本(script)语言,它主要解决夹杂优化处理的线形、非线性或整型编程问题。为了在实际问题中使用AMPL,还需要一个AMPL的解释器和规划问题的求解器。AMPL解释器解释执行AMPL脚本,遇到涉及到优化求解的代码再调用求解器求解,求解器所得结果返回至解释器用于显示或做为中间结果使用,这过程理论上可以往复任意多次。实际上就把脚本语言和优化求解完美的融合到一块了。一个优化求解器可以很方便的和AMPL解释器对接,因此有众多的求解器支持AMPL语言。
我认为AMPL应该成为数学建模、科技金融经济建模中的一个有力工具。下面是两个例子。为了执行AMPL脚本,可按下述步骤进行配置(Windows下):
(1)到链接http://www.ampl.com/DOWNLOADS/index.html中下载amplcml.zip(该版本是免费的,有限制,可用Google搜一下或有收获,也可到这里http://rapidshare8.com/看看);
(2)把amplcml.zip解压至一个目录下,然后找到ampl.exe文件所在的目录,称为ampl根目录,比如C:/amplcml;
(3)把ampl根目录设置到Windows路径上;
(4)把例1的AMPL脚本内容存成文本文件,比如C:/exam1.mod;
(4)进入Windows命令窗口:开始-->运行,输入cmd回车;
(5)运行脚本:ampl c:/exam1.mod。
例1 简单的脚本演示。
AMPL脚本:
set vec:=1..4;
param x{vec};
data;
param x:=1 1
2 5
3 6
4 8;
display x;
display sum {i in vec} x[i];
输出:
x [*] :=
1 1
2 5
3 6
4 8
;
sum{i in vec} x[i] = 20
例2 最小费用最大流问题。
param N >0,integer;
param s >0,<=N,integer;
param t >0,<=N,integer;
set nodes:=1..N;
set arcs within nodes cross nodes;
param c{arcs}>=0;
param cap{arcs}>0;
var x{arcs}>=0;
subject to banlance{i in nodes: i<>s and i<>t}:
sum{(i,j) in arcs} x[i,j] =sum{(j,i) in arcs} x[j,i];
subject to capcon{(i,j) in arcs}:
x[i,j]<=cap[i,j];
minimize totalcost: sum{(i,j) in arcs} c[i,j]*x[i,j]-
(max {(i,j) in arcs} c[i,j] *N+1)*(sum{(s,j) in arcs} x[s,j]-sum{(j,s) in arcs} x[j,s]);
data;
param N:=10;
param s:=1;
param t:=10;
param: arcs: c cap :=
1 1 4 8
2 1 7 5
4 1 4 7
10 1 8 5
5 2 8 8
2 3 3 2
5 3 6 2
8 3 6 7
9 3 5 2
10 3 9 5
2 4 3 7
6 4 3 5
10 4 1 7
4 5 9 2
5 5 6 3
6 5 5 4
7 5 6 7
9 5 5 1
1 6 6 3
3 6 5 3
5 6 7 1
2 7 5 5
4 7 10 9
5 7 2 6
6 7 1 6
7 7 1 6
9 7 1 6
10 7 4 8
1 8 4 8
2 8 4 2
7 8 8 9
3 9 6 6
6 9 8 6
7 9 9 2
3 10 10 2
4 10 2 3
5 10 1 7
;
option solver cplex;
solve;
option display_precision 20;
display sum{(i,j) in arcs} c[i,j]*x[i,j],
(sum{(s,j) in arcs} x[s,j])-(sum{(j,s) in arcs} x[j,s]);
输出:
CPLEX 11.2.0: optimal solution; objective -828
9 dual simplex iterations (0 in phase I)
sum{(i,j) in arcs} c[i,j]*x[i,j] = 182
sum{(s,j) in arcs} x[s,j] - sum{(j,s) in arcs} x[j,s] = 10
例3 运输问题,供应量、需求量和单位运输费用代码中数据。下面给出了AMPL代码和LINGO代码,大家可以比较异同。
AMPL代码:
set ORIG; # origins
set DEST; # destinations
param supply {ORIG} >= 0; # amounts available at origins
param demand {DEST} >= 0; # amounts required at destinations
check: sum {i in ORIG} supply[i] = sum {j in DEST} demand[j];
param cost {ORIG,DEST} >= 0; # shipment costs per unit
var Trans {ORIG,DEST} >= 0; # units to be shipped
minimize Total_Cost:
sum {i in ORIG, j in DEST} cost[i,j] * Trans[i,j];
subject to Supply {i in ORIG}:
sum {j in DEST} Trans[i,j] = supply[i];
subject to Demand {j in DEST}:
sum {i in ORIG} Trans[i,j] = demand[j];
data;
param: ORIG: supply := # defines set "ORIG" and param "supply"
GARY 1400
CLEV 2600
PITT 2900 ;
param: DEST: demand := # defines "DEST" and "demand"
FRA 900
DET 1200
LAN 600
WIN 400
STL 1700
FRE 1100
LAF 1000 ;
param cost:
FRA DET LAN WIN STL FRE LAF :=
GARY 39 14 11 14 16 82 8
CLEV 27 9 12 9 26 95 17
PITT 24 14 17 13 28 99 20 ;
option solver cplex;
solve;
printf "结果:/n";
display {i in ORIG, j in DEST: Trans[i,j]<>0} Trans[i,j];
输出结果:
CPLEX 11.2.0: optimal solution; objective 196200
12 dual simplex iterations (0 in phase I)
结果:
Trans[i,j] :=
CLEV DET 1200
CLEV LAF 400
CLEV LAN 600
CLEV WIN 400
GARY FRE 1100
GARY LAF 300
PITT FRA 900
PITT LAF 300
PITT STL 1700
;
LINGO代码:
model:
!6发点8收点运输问题;
sets:
warehouses: capacity;
vendors: demand;
links(warehouses,vendors): cost, volume;
endsets
!目标函数;
min=@sum(links: cost*volume);
!需求约束;
@for(vendors(J):
@sum(warehouses(I): volume(I,J))=demand(J));
!产量约束;
@for(warehouses(I):
@sum(vendors(J): volume(I,J))<=capacity(I));
!这里是数据;
data:
warehouses, capacity=
GARY 1400
CLEV 2600
PITT 2900 ;
vendors, demand=FRA 900
DET 1200
LAN 600
WIN 400
STL 1700
FRE 1100
LAF 1000 ;
cost=
39 14 11 14 16 82 8
27 9 12 9 26 95 17
24 14 17 13 28 99 20 ;
enddata
end
输出结果:
Global optimal solution found.
Objective value: 196200.0
Infeasibilities: 0.000000
Total solver iterations: 11
Variable Value Reduced Cost
CAPACITY( GARY) 1400.000 0.000000
CAPACITY( CLEV) 2600.000 0.000000
CAPACITY( PITT) 2900.000 0.000000
DEMAND( FRA) 900.0000 0.000000
DEMAND( DET) 1200.000 0.000000
DEMAND( LAN) 600.0000 0.000000
DEMAND( WIN) 400.0000 0.000000
DEMAND( STL) 1700.000 0.000000
DEMAND( FRE) 1100.000 0.000000
DEMAND( LAF) 1000.000 0.000000
COST( GARY, FRA) 39.00000 0.000000
COST( GARY, DET) 14.00000 0.000000
COST( GARY, LAN) 11.00000 0.000000
COST( GARY, WIN) 14.00000 0.000000
COST( GARY, STL) 16.00000 0.000000
COST( GARY, FRE) 82.00000 0.000000
COST( GARY, LAF) 8.000000 0.000000
COST( CLEV, FRA) 27.00000 0.000000
COST( CLEV, DET) 9.000000 0.000000
COST( CLEV, LAN) 12.00000 0.000000
COST( CLEV, WIN) 9.000000 0.000000
COST( CLEV, STL) 26.00000 0.000000
COST( CLEV, FRE) 95.00000 0.000000
COST( CLEV, LAF) 17.00000 0.000000
COST( PITT, FRA) 24.00000 0.000000
COST( PITT, DET) 14.00000 0.000000
COST( PITT, LAN) 17.00000 0.000000
COST( PITT, WIN) 13.00000 0.000000
COST( PITT, STL) 28.00000 0.000000
COST( PITT, FRE) 99.00000 0.000000
COST( PITT, LAF) 20.00000 0.000000
VOLUME( GARY, FRA) 0.000000 27.00000
VOLUME( GARY, DET) 0.000000 14.00000
VOLUME( GARY, LAN) 0.000000 8.000000
VOLUME( GARY, WIN) 0.000000 14.00000
VOLUME( GARY, STL) 0.000000 0.000000
VOLUME( GARY, FRE) 1100.000 0.000000
VOLUME( GARY, LAF) 300.0000 0.000000
VOLUME( CLEV, FRA) 0.000000 6.000000
VOLUME( CLEV, DET) 1200.000 0.000000
VOLUME( CLEV, LAN) 600.0000 0.000000
VOLUME( CLEV, WIN) 400.0000 0.000000
VOLUME( CLEV, STL) 0.000000 1.000000
VOLUME( CLEV, FRE) 0.000000 4.000000
VOLUME( CLEV, LAF) 400.0000 0.000000
VOLUME( PITT, FRA) 900.0000 0.000000
VOLUME( PITT, DET) 0.000000 2.000000
VOLUME( PITT, LAN) 0.000000 2.000000
VOLUME( PITT, WIN) 0.000000 1.000000
VOLUME( PITT, STL) 1700.000 0.000000
VOLUME( PITT, FRE) 0.000000 5.000000
VOLUME( PITT, LAF) 300.0000 0.000000
有兴趣的朋友可以留个言哟,交流交流!这里是一篇有关AMPL的国外论文的翻译.