问题
I have an equation and i don't know how to implement it in AMPL for CPLEX. Here is it: enter image description here
Thank you for your help!
回答1:
With a linear solver (like CPLEX), the usual approach is to turn this into a linear constraint with a binary variable indicating which of the two cases applies.
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.
A couple of considerations:
If you want to be mathematically precise, when z_v
equals eps exactly, z_s_1
could take either value, and hence z_s
could be either 0 or beta
. But given the limitations of computer arithmetic, we normally don't need to lose sleep about strict vs. non-strict inequalities.
This will prevent solutions with z_v > bignum+eps
, so bignum
will need to be large enough to allow reasonable values of z_v
. However, if you make it too large, you can run into problems with machine arithmetic. For instance, consider the following example:
option solver cplex;
param bignum = 1e6;
var x binary;
minimize of: x;
s.t. c1: bignum*x >= 1;
solve;
display x;
Evaluating this by hand, since x
is binary and bignum*x
>= 1, we can see that x
must be 1. However, running this through AMPL/CPLEX, I instead get the solution x=0
, even though this violates c1
.
The reason for this is that these solvers generally allow a small tolerance for "integer" variables. Hence, it accepts a solution of x=1e-10
as "close enough" to integer. This satisfies c1
since x*bignum >= 1
, but then it rounds x
to zero. This can be confusing if you're not expecting it! So figure out what the smallest value is for bignum
that will do the job, based on the largest plausible value for z_v
, and check results carefully. You may need to tinker with the tolerance parameters.
AMPL does also offer some support for logical constraints with CPLEX but I'm less familiar with those, so I'm not sure if they offer an alternate solution to this problem.
来源:https://stackoverflow.com/questions/55779330/how-to-implement-decision-variable-in-ampl