#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, но я менее знаком с ними, поэтому я не уверен, предлагают ли они альтернативное решение этой проблемы.