1

I'm trying to use amplpy to link a python script to a ampl model, and the real desire is use a script to generate some parameters, and use the ampl to find the optimal values to some variables.

Worth mentioning that the model works fine alone, no errors and finds the optimal solution.

Since i need to load the model and the parameters in the python script, i tried to import the .dat file with amplpy.read() and amplpy.read_data() and it doest work. the error message that the python interpreter returs:

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

Trying to overcome this problem, I'm defining the parameters directly in the script. This is the way I'm doing, for the parameter GD, associated with two sets.

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')

From this the interpreter returs:

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

1 Answers1

0

The error message no data for set L usually happens when you try to load data for an indexed parameter without providing data for the indexing set. The following:

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

will produce the error:

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

In the data declaration you can provide the name of the indexing set if you want to load it at the same time as the parameter:

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

Regarding the error message GD is not a set, the second argument of ampl.set_data is for the indexing set (see, e.g., amplpy.AMPL.set_data) and that is why you got that error. Since it is a parameter you can load its data (using a pandas DataFrame) as follows:

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;")
fdabrandao
  • 81
  • 4