【问题标题】:AMPL: Syntax for sets?AMPL:集合的语法?
【发布时间】:2019-06-10 19:20:13
【问题描述】:

我正在研究混合整数线性程序 (MILP) 的高级语言。该语言是一种数学编程语言的建模语言(AMPL)

第 4 章,第 65 页,图 4-7 显示了以下语法:

set PROD := bands coils plate ;

但是,第 5 章第 74 页显示了以下语法:

set PROD = {"bands", "coils", "plate"};

谁能解释一下语法上的差异?

我将后者放入 *.dat 文件中,AMPL 抱怨 expected ; ( : or symbol{ 所在的位置。想知道这是否只是手册中的错误。

谢谢。

【问题讨论】:

    标签: set ampl


    【解决方案1】:

    第四章的语法——

    set PROD := bands coils plate;
    

    --用于数据文件,而第5章的语法--

    set PROD = {"bands", "coils", "plate"};
    

    -- 用于模型文件。模型和数据文件中集合的语法不同,这有点奇怪(IMO),但确实如此。有关此差异的另一个示例,请参阅this question and answer

    根据 AMPL 手册修改的完整工作示例代码

    由问题的原始发布者添加。

    dietu.mod:

    # dietu.mod
    #----------
    # set MINREQ;   # nutrients with minimum requirements
    # set MAXREQ;   # nutrients with maximum requirements
    set MINREQ = {"A", "B1", "B2", "C", "CAL"};
    set MAXREQ = {"A", "NA", "CAL"};
    
    set NUTR = MINREQ union MAXREQ;    # nutrients
    set FOOD;                          # foods
    
    param cost {FOOD} > 0;
    param f_min {FOOD} >= 0;
    param f_max {j in FOOD} >= f_min[j];
    
    param n_min {MINREQ} >= 0;
    param n_max {MAXREQ} >= 0;
    
    param amt {NUTR,FOOD} >= 0;
    
    var Buy {j in FOOD} >= f_min[j], <= f_max[j];
    
    minimize Total_Cost:  sum {j in FOOD} cost[j] * Buy[j];
    
    subject to Diet_Min {i in MINREQ}:
       sum {j in FOOD} amt[i,j] * Buy[j] >= n_min[i];
    
    subject to Diet_Max {i in MAXREQ}:
       sum {j in FOOD} amt[i,j] * Buy[j] <= n_max[i];
    

    setes MINREQMAXREQ 及其成员的显式定义取自下面的 *.dat 文件(其中它们的定义已被注释掉)。 Matlab 用户,请注意以上内容并注意您需要在集合中的成员之间使用逗号。

    dietu.dat:

    # dietu.dat
    #----------
    data;
    
    # set MINREQ := A B1 B2 C CAL ;
    # set MAXREQ := A NA CAL ;
    set FOOD := BEEF CHK FISH HAM MCH MTL SPG TUR ;
    
    param:   cost  f_min  f_max :=
      BEEF   3.19    2     10 
      CHK    2.59    2     10 
      FISH   2.29    2     10 
      HAM    2.89    2     10 
      MCH    1.89    2     10 
      MTL    1.99    2     10 
      SPG    1.99    2     10 
      TUR    2.49    2     10  ;
    
    param:   n_min  n_max :=
       A      700   20000
       C      700       .
       B1       0       .
       B2       0       .
       NA       .   50000
       CAL  16000   24000 ;
    
    param amt (tr):   A    C   B1   B2    NA   CAL :=
              BEEF   60   20   10   15   938   295
              CHK     8    0   20   20  2180   770
              FISH    8   10   15   10   945   440
              HAM    40   40   35   10   278   430
              MCH    15   35   15   15  1182   315
              MTL    70   30   15   15   896   400
              SPG    25   50   25   15  1329   370
              TUR    60   20   15   10  1397   450 ;
    

    在 AMPL 提示符下使用以下命令求解模型:

    reset data;
    reset;
    model dietu.mod;
    data dietu.dat;
    solve;
    

    【讨论】:

    • 感谢您的解释。而且很酷!一个 OR SE !!我不确定是否将我所有的同事都派到这里,因为它是测试版??我主要使用工具语言 SE、Stats、Math 和计算机式 SE。还有一个grouples论坛...太多的选择。坦率地说,基于计算语言 SE,我发现在 Grouples 与 SE 上可以回答不同的问题,而且我还没有识别出一种模式来区分每个问题中可能回答的问题类型。附言是的,奇怪的是使用多种语法取决于它是在 *.dat 还是 *.mod 文件中。
    • 定义set PROD 的两种方法令人困惑。第一,成员就像枚举类型。名称仅用于区分成员。只要我们始终如一地使用它们,它们就可以是任何东西。它们就像源代码标识符(变量名)。在第二种语法中,它们是真正的字符串,可以在其上应用正则表达式等字符串函数。只有在像 Matlab 这样的弱类型语言中,我才看到这两种类型模糊在一起,例如,使用字符串来搜索对象属性名称。我认为使用多种语法会使语言变得更加复杂。
    • @user36800 我同意语法的变化令人困惑。但我认为这两种方法都将PROD 的元素视为字符串。例如,我在dat 文件中使用set PROD := bands coils plate;,然后在命令行中使用display {p in PROD} substr(p, 2, 4);,结果正确。
    • @user36800 至于 OR.SE——是的,请随时将同事发送到 or.stackexchange.com,即使它处于测试阶段。 Beta 是一个有趣的名称,网站可以在 beta 中停留很多年,但仍然完全处于变化之中。 OR.SE 处于“私人测试版”中,这更像是一个“热身期”,但它应该在几周后进入公开测试版。我同意,太多的选择,这也是我们创建 OR.SE 的原因之一。
    • 注意集合成员可以是带有空格的字符串; .dat 中的引号对于单字集成员是可选的,但对于包含空格的成员是必需的。烦人的是,display 命令会显示后者而不是前者的引号,从而使输出看起来不一致。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    相关资源
    最近更新 更多