GAMS & Python: как переписать выходной файл gdx при запуске GamsJob в цикле - PullRequest
0 голосов
/ 16 ноября 2018

В моей задаче мне нужно запустить ту же модель GAMS с разными значениями параметров в Python. Для этого я создал рабочую область GAMS, модель, задание и базу данных GDX:

model = '''Variables 
        objective, {vars};
    Parameters
        {up_bounds}; {low_bounds};
    $gdxin db
    $load {load_values}
    $gdxin
    Equations  
        obj, {eqs_list};
        obj ..    objective =e= {obj_equation};
        {nodes_eq};
        {up_bounds_eq};
    Model myLP /all/;
    Solve myLP using lp minimizing objective;'''.format(load_values=' '.join(load_values), kwargs**)
ws = GamsWorkspace(working_directory='some_path')

db = ws.add_database('db')
load_values_p = [self.db.add_parameter(value, 0).add_record() for value in load_values]

job = ws.add_job_from_string(model)

for i in range(any_count):
    update_parameters_values()
    job.run(databases=self.db)
    result.append([job.out_db[key][()].level for key in res_values_names])

где:
load_values - список имен переменных, которые будут загружены из 'db.gdx'. Они также инициализируются в Parameter разделе model;
update_parameters_values() - функция, которая изменяет значения load_values_p (она также автоматически изменяется в db объекте и файле db.gdx);
res_values_names - список имен переменных результатов.

Проблема в том, что job генерирует новый файл GDX out_db на каждой итерации, но я хочу переписать существующий и просто прочитать обновленные значения результатов. Как это сделать? Спасибо)

1 Ответ

0 голосов
/ 03 декабря 2018

Я нашел решение в документации GAMS - GamsModifier может решить мою проблему.Применяя его к моей задаче и коду выше:

model = '''Variables 
        objective, {vars};
    Scalars
        {up_bounds}; {low_bounds};
    Equations  
        obj, {eqs_list};
        obj ..    objective =e= {obj_equation};
        {nodes_eq};
        {up_bounds_eq};
    Model myLP /all/;'''.format(kwargs**)
ws = GamsWorkspace(working_directory='some_path')

cp = ws.add_checkpoint()
master_init_job = ws.add_job_from_string(model)
master_init_job.run(checkpoint=cp)
mi = cp.add_modelinstance()

load_values = [mi.sync_db.add_parameter(load_value, 0)
               for load_value in load_values]

modifiers = [GamsModifier(load_value) for load_value in load_values]
mi.instantiate('myLP using lp minimizing objective', modifiers=modifiers)

for load_value in self.load_values:
    load_value.add_record()

for i in range(any_count):
    update_parameters_values()
    mi.solve()
    result.append([mi.sync_db.get_variable(key)[()].level 
                   for key in res_values_names])

На момент запуска значения всех переменных аналогичны перечисленным в вопросе.Эта реализация позволяет избежать создания дополнительных файлов и работает быстрее.

...