ampl / amplpy

Python API for AMPL

Home Page:https://amplpy.ampl.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Extract and reuse variables

xrixhon opened this issue · comments

Hello,

I’m currently working with the API amplpy on python in order to run iteratively a model. Although, I would like to know if it is possible to fix the values of a set of multi-dimensional variables of a run based on the values resulting from a previous run. All I’ve been able to find so far are the functions getVariable(), getValues() and fix() from the API documentation (https://ampl.com/api/nightly/python/index.html). What I would like to do is something like that (if in run#2 I’d like to fix variable "b" (a multi-dimensional variable) to the values of variable "a" from run #1):

a = ampl.getVariable(‘a’)
a = a.getValues()
b.fix(a)

Unfortunately, such a thing does not work as, seemingly, the function fix() is only applicable when it is passed a scalar as an argument (it does not seem to accept dataframes). I would like to avoid for loops to go through element of the prior variable (‘a’ in this case) to fix values of the second variable (‘b’ in this case).

What could be awesome would be to automatically generate a .mod file with all the "fix variable := ....;" that could simply be read for the next run.

Could you help me on this topic, please?

Thank you in advance for your answer,

Best regards,

Xavier

Hi Xavier,

You can achieve that as follows:

from amplpy import AMPL
ampl = AMPL()
ampl.read('diet.mod')
ampl.readData('diet.dat')
ampl.solve()
ampl.eval('var Buy2 {j in FOOD} >= f_min[j], <= f_max[j];')

buy = ampl.getVariable('Buy')
buy2 = ampl.getVariable('Buy2')
buy2.setValues(buy.getValues()) # assign to Buy2 the values from Buy
buy2.fix() # fix variable Buy2

ampl.display('Buy2.astatus')
ampl.display('Buy2.val')

Output:

Buy2.astatus [*] :=
BEEF  fix
 CHK  fix
FISH  fix
 HAM  fix
 MCH  fix
 MTL  fix
 SPG  fix
 TUR  fix
;

Buy2.val [*] :=
 MCH  46.6667
 MTL   1.57618e-15
 SPG   8.42982e-15
;

Regarding your question about producing a mod file with the fix instructions for the variables, you can achieve that as follows:

with open('fix.mod', 'w') as f:
    for index, variable in ampl.getVariable('Buy'):
        print('let {} := {};'.format(variable.name(), variable.value()), file=f)

Hello Filipe,

Thank you very much for your help. It did the job perfectly.
For my information, is there a reason you wrote "let" instead of "fix"? In a broader view, what is the difference between these two instructions?

Thank you in advance for your answer,

Best regards,

Xavier

Hi Xavier,

Sorry, instead of 'let {} := {};' it should have been 'fix {} := {};'. "let" assigns the value to the variable but the variable value can still be changed by the solver unless if fix the variable with "fix variable_name;". "fix" assigns the value and fixes the variable to that value.

Hi Filipe,

Thanks again for your precise and fast answers.

Cheers,