【问题标题】:How do I define AMPL like sets and parameters in Julia+JuMP?如何在 Julia+JuMP 中定义类似 AMPL 的集合和参数?
【发布时间】:2014-08-30 22:53:05
【问题描述】:

我需要在 Julia+JuMP 中定义一些常量参数,类似于你在 AMPL 中定义时所做的事情

set A := a0 a1 a2;

param p :=
a0 1
a1 5
a2 10 ;

如何在 Julia 中定义 Ap 之类的内容?

【问题讨论】:

    标签: julia julia-jump


    【解决方案1】:

    JuMP 本身并没有为 Julia 中可用的索引集定义特殊语法。因此,例如,您可以定义

    A = [:a0, :a1, :a2]
    

    :a0 定义了一个符号。

    如果你想在这个集合上索引一个变量,那么语法是:

    m = Model()
    @variable(m, x[A])
    

    JuMP 也不像 AMPL 那样区分数据和模型,因此没有参数的真正概念。相反,您只需在使用数据时提供数据。如果我正确理解你的问题,你可以做类似的事情

    p = Dict(:a0 => 1, :a1 => 5, :a2 => 10)
    @constraint(m, sum(p[i]*x[i] for i in A) <= 20)
    

    这将添加约束

    x[a0] + 5 x[a1] + 10 x[a2] <= 20
    

    我们将p 定义为 Julia 字典。这里没有特定于 JuMP 的内容,实际上任何 julia 表达式都可以作为系数提供。可以很容易地说

    @constraint(m, sum(foo(i)*x[i] for i in A) <= 20)
    

    foo 是一个任意 Julia 函数,可以执行数据库查找、计算 pi 的位数等。

    【讨论】:

    • 这个答案非常有用。无论如何,我认为数据不应该在代码中。我看到两个解决方案:1)如果可能,从文件中读取常量。 2)通过脚本生成代码,该脚本填充从例如xml读取的数据。
    • 从文件中读取数据当然是合理的。 JuMP 的理念是让用户决定如何构建输入而不是强加某些文件格式。例如,在上面,您可以使用 Julia 的本机 I/O 函数或 LightXML.jl 包从文件中填充 p
    • 非常感谢,我试着搜索一下。
    • @mlubin 您将如何继续定义目标?我确实尝试过@objective(m, Max, sum(x[i]+p[i] for i in A)),但它不起作用。实际上,Julia 0.5 在你写的约束语句上给了我一个错误:LoadError: indexing Array{Pair{Symbol,Int64},1} with types Tuple{Symbol} is not supported
    • 我已更正了p 定义中的错误。代码现在应该可以工作了。
    【解决方案2】:

    我无法得到@mlubin 工作的原始答案。此外,网络上的许多示例使用基于位置的索引,我觉得不太自然,所以我改用字典重写了 GAMS 教程的trnsport.gms 示例......感觉更接近 gams/ampl "sets “..

    #=
    Transposition in JuMP of the basic transport model used in the GAMS tutorial
    
    This problem finds a least cost shipping schedule that meets requirements at markets and supplies at factories.
    
    - Original formulation: Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions.
    Princeton University Press, Princeton, New Jersey, 1963.
    - Gams implementation: This formulation is described in        detail in:
    Rosenthal, R E, Chapter 2: A GAMS Tutorial. In GAMS: A User's Guide.
    The Scientific Press, Redwood City, California, 1988.
    - JuMP implementation: Antonello Lobianco
    =#
    
    using JuMP, DataFrames
    
    # Sets
    plants  = ["seattle","san_diego"]          # canning plants
    markets = ["new_york","chicago","topeka"]  # markets
    
    # Parameters
    a = Dict(              # capacity of plant i in cases
      "seattle"   => 350,
      "san_diego" => 600,
    )
    b = Dict(              # demand at market j in cases
      "new_york"  => 325,
      "chicago"   => 300,
      "topeka"    => 275,
    )
    
    #  distance in thousands of miles
    d_table = wsv"""
    plants     new_york  chicago  topeka
    seattle    2.5       1.7      1.8
    san_diego  2.5       1.8      1.4
    """
    d = Dict( (r[:plants],m) => r[Symbol(m)] for r in       eachrow(d_table), m in markets)
    
    f = 90 # freight in dollars per case per thousand miles
    
    c = Dict() # transport cost in thousands of dollars per case ;
    [ c[p,m] = f * d[p,m] / 1000 for p in plants, m in markets]
    
    # Model declaration
    trmodel = Model() # transport model
    
    # Variables
    @variables trmodel begin
        x[p in plants, m in markets] >= 0 # shipment quantities in cases
    end
    
    # Constraints
    @constraints trmodel begin
        supply[p in plants],   # observe supply limit at plant p
            sum(x[p,m] for m in markets)  <=  a[p]
        demand[m in markets],  # satisfy demand at market m
            sum(x[p,m] for p in plants)  >=  b[m]
     end
    
    # Objective
    @objective trmodel Min begin
        sum(c[p,m]*x[p,m] for p in plants, m in markets)
    end
    
    print(trmodel)
    
    status = solve(trmodel)
    
    if status == :Optimal
        println("Objective value: ", getobjectivevalue(trmodel))
        println("Shipped quantities: ")
        println(getvalue(x))
        println("Shadow prices of supply:")
        [println("$p = $(getdual(supply[p]))") for p in plants]
        println("Shadow prices of demand:")
        [println("$m = $(getdual(demand[m]))") for m in markets]
    
    else
        println("Model didn't solved")
        println(status)
    end
    
    # Expected result:
    # obj= 153.675
    #['seattle','new-york']   = 50
    #['seattle','chicago']    = 300
    #['seattle','topeka']     = 0
    #['san-diego','new-york'] = 275
    #['san-diego','chicago']  = 0
    #['san-diego','topeka']   = 275
    

    我的related blog post 上提供了更多评论版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      相关资源
      最近更新 更多