amplpy:如何将数据定义为与集合关联的参数

问题描述 投票:0回答:1

我正在尝试使用 amplpy 将 python 脚本链接到 ampl 模型,真正的愿望是使用脚本生成一些参数,并使用 ampl 找到某些变量的最佳值。

值得一提的是,该模型单独运行良好,没有错误,并找到了最优解。

由于我需要在 python 脚本中加载模型和参数,因此我尝试使用 amplpy.read() 和 amplpy.read_data() 导入 .dat 文件,但它不起作用。 python解释器返回的错误消息:

ampl.read('fpo-dt.dat')

Error:
    po-dt.dat
    line 2 offset 55
        no data for set L
Traceback (most recent call last):

  File "C:\Users\LaPSEE\AppData\Local\Temp\ipykernel_6064\4255500489.py", line 1, in <cell line: 1>
    ampl.read('fpo-dt.dat')

  File "C:\ProgramData\Miniconda3\lib\site-packages\amplpy\ampl.py", line 554, in read
    self._error_handler_wrapper.check()

  File "C:\ProgramData\Miniconda3\lib\site-packages\amplpy\ampl.py", line 704, in check
    raise exp

  File "C:\ProgramData\Miniconda3\lib\site-packages\amplpy\ampl.py", line 688, in error
    self.error_handler.error(exception)

  File "C:\ProgramData\Miniconda3\lib\site-packages\amplpy\errorhandler.py", line 25, in error
    raise exception

AMPLException: po-dt.dat
line 2 offset 55
    no data for set L

为了克服这个问题,我直接在脚本中定义参数。这就是我正在做的方式,对于与两个集合相关联的参数 GD。

from amplpy import AMPL, DataFrame
ampl = AMPL()
ampl.reset()
ampl.read('modelfpo.mod')

gd = ([[0,      0,      0],
    [20.00,  20.00,  20.00],
    [21.00,  24.00,  38.40],
    [21.60,  27.00,  59.40],
    [26.40,  33.00,  72.60],
    [22.80,  28.50,  62.70],
    [18.00,  18.00,  18.00],
    [21.60,  27.00,  59.40],
    [18.00,  22.50,  49.50],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [5.25,  6.00,  9.60],
    [26.25,  33.60,  80.64],
    [23.10,  27.30,  49.14],
    [27.50,  35.20,  84.48],
    [21.00,  24.00,  38.40],
    [26.40,  33.00,  72.60],
    [20.00,  22.00,  30.80],
    [24.15,  29.40,  58.80],
    [18.00,  19.80,  27.72],
    [21.00,  22.05,  26.46],
    [25.00,  32.00,  76.80],
    [22.00,  26.00,  46.80],
    [18.00,  19.80,  27.72],
    [10.35,  12.60,  25.20],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [6.60,  7.80,  14.04]])

df_gd = DataFrame('GD', data=gd)
ampl.set_data(df_gd,'GD')

翻译员由此返回:

ampl.set_data(df_gd,'GD')
Traceback (most recent call last):

  File "C:\Users\xxxx\AppData\Local\Temp\ipykernel_6064\2016685981.py", line 1, in <cell line: 1>
    ampl.set_data(df_gd,'GD')

  File "C:\ProgramData\Miniconda3\lib\site-packages\amplpy\ampl.py", line 608, in set_data
    self._impl.setData(data._impl, set_name)

    RuntimeError: file -
    line 1 offset 10    
    GD is not a set
python ampl amplpy
1个回答
0
投票

当您尝试加载索引参数的数据而不为索引集提供数据时,通常会出现错误消息

no data for set L
。以下:

set L;
param p{L};
data;
param p := 
   1 23
   2 32
   4 12;
model;
display p;

会产生错误:

    Error executing "display" command:
    error processing param p[...]:
        no data for set L

在数据声明中,如果您想与参数同时加载索引集,您可以提供索引集的名称:

set L;
param p{L};
data;
param : L : p  := 
   1 23
   2 32
   4 12;
model;

关于错误消息

GD is not a set
ampl.set_data
的第二个参数用于索引集(例如,参见amplpy.AMPL.set_data),这就是您收到该错误的原因。由于它是一个参数,您可以加载其数据(使用 pandas DataFrame),如下所示:

from amplpy import AMPL
import pandas as pd
ampl = AMPL()
ampl.reset()
ampl.eval("""
set I;
set J;
param GD{I,J};
""")
gd = [[0,      0,      0],
    [20.00,  20.00,  20.00],
    [21.00,  24.00,  38.40],
    [21.60,  27.00,  59.40],
    [26.40,  33.00,  72.60],
    [22.80,  28.50,  62.70],
    [18.00,  18.00,  18.00],
    [21.60,  27.00,  59.40],
    [18.00,  22.50,  49.50],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [5.25,  6.00,  9.60],
    [26.25,  33.60,  80.64],
    [23.10,  27.30,  49.14],
    [27.50,  35.20,  84.48],
    [21.00,  24.00,  38.40],
    [26.40,  33.00,  72.60],
    [20.00,  22.00,  30.80],
    [24.15,  29.40,  58.80],
    [18.00,  19.80,  27.72],
    [21.00,  22.05,  26.46],
    [25.00,  32.00,  76.80],
    [22.00,  26.00,  46.80],
    [18.00,  19.80,  27.72],
    [10.35,  12.60,  25.20],
    [0.00,  0.00,  0.00],
    [0.00,  0.00,  0.00],
    [6.60,  7.80,  14.04]]
df_gd = pd.DataFrame(columns=["I", "J", "GD"], data=gd)
ampl.set["I"] = set(df_gd["I"].tolist()) # load data for set I
ampl.set["J"] = set(df_gd["J"].tolist()) # load data for set J
ampl.param["GD"] = df_gd.set_index(["I", "J"]) # load data for paramater GD
ampl.eval("display GD;")
© www.soinside.com 2019 - 2024. All rights reserved.