AMPL(A Mathematical Programming Language):一个代数建模语言简介

      最近学习了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的国外论文的翻译.

你可能感兴趣的:(c,优化,windows,脚本,Google,语言)