Как реализовать переменную решения в AMPL

#math #modeling #ampl

#математика #моделирование #ampl

Вопрос:

У меня есть уравнение, и я не знаю, как реализовать его в AMPL для CPLEX. Вот оно: введите описание изображения здесь

Спасибо за вашу помощь!

Комментарии:

1. Какой решатель вы используете с AMPL? Некоторые решатели делают это намного проще, чем другие.

2. я использую cplex solver

Ответ №1:

С линейным решателем (например, CPLEX) обычный подход заключается в том, чтобы превратить это в линейное ограничение с двоичной переменной, указывающей, какой из двух случаев применим.

 param eps;
param beta;
param bignum = 1e5;
var z_s_1 binary;
# will have value 0 when z_v <= eps, else 1
var z_s = z_s_1*beta;
var z_v >= 0;

s.t. Define_z_s_1_a: z_s_1 * eps <= z_v;
# so if z_v < eps then z_s_1 must be 0 and hence z_s = 0
s.t. Define_z_s_1_b: z_s_1 * bignum >= z_v - eps;
# so if z_v > eps, then z_s_1 must be > 0 so must be 1, 
# and hence z_s = beta.
  

Несколько соображений:

Если вы хотите быть математически точным, когда z_v точно равно eps, z_s_1 может принимать любое значение и, следовательно z_s , может быть либо 0, либо beta . Но, учитывая ограничения компьютерной арифметики, нам обычно не нужно терять сон о строгих и нестрогих неравенствах.

Это предотвратит решения с z_v > bignum eps , поэтому bignum должно быть достаточно большим, чтобы обеспечить разумные значения z_v . Однако, если вы сделаете ее слишком большой, вы можете столкнуться с проблемами с машинной арифметикой. Например, рассмотрим следующий пример:

 option solver cplex;
param bignum = 1e6;
var x binary;

minimize of: x;

s.t. c1: bignum*x >= 1;
solve;
display x;
  

Оценивая это вручную, поскольку x является двоичным и bignum*x > = 1, мы видим, что x это должно быть 1. Однако, запустив это через AMPL / CPLEX, я вместо этого получаю решение x=0 , хотя это нарушает c1 .

Причина этого в том, что эти решатели обычно допускают небольшой допуск для «целых» переменных. Следовательно, он принимает решение x=1e-10 как «достаточно близкое» к целому числу. Это удовлетворяет c1 since x*bignum >= 1 , но затем округляется x до нуля. Это может сбить с толку, если вы этого не ожидаете! Итак, выясните, какое наименьшее значение для bignum этого будет выполнять работу, основываясь на наибольшем правдоподобном значении для z_v , и тщательно проверьте результаты. Возможно, вам придется повозиться с параметрами допуска.

AMPL также предлагает некоторую поддержку логических ограничений с помощью CPLEX, но я менее знаком с ними, поэтому я не уверен, предлагают ли они альтернативное решение этой проблемы.