No problem, I am glad to help. [Edit: apologies -- in an effort to simplify the presentation I had a version of the code below that was incorrect.] There are several ways to express the rule you propose, but which one will produce the best results depends on context. The rule is non-linear and discontinuous. In theory, that prevents the algorithms from doing clever things to produce results faster. But in practice, the algorithms implement many tricks that often produce great results. So you might have to experiment a little to see which algorithm and formulation will perform best in practice. For example: here is how you might do it if you have only linear expressions: proc optmodel; num jRange = 5; /* suppose J can vary between -5 and 5 */ num delta = .1; /* meaningful deviation from 0 -- Don't make too small.*/ var JPosPart >= 0 <= jRange, JNegPart >= 0 <= jRange ; impvar J = JPosPart - JNegPart; var IsJNeg binary; impvar I = 1 + 4*IsJNeg; /* The bound is >= 1 only if J <= delta */ con ComputeIsJNeg1: IsJNeg <= (1/delta) * jNegPart ; /* The right hand is > 0 only if jNegPart is < delta, but is always <= 1 */ con ComputeIsJNeg2: IsJNeg >= 1 / jRange * ( jNegPart - delta ); /* The right hand is 1 only if jPosPart is 0, but always >= 0 */ con ComputeIsJNeg3: IsJNeg <= 1 - (1/(jRange + delta)) * jPosPart; max s = 10*I + J ; solve ; print I J IsJNeg JNegPart JPosPart; quit; There are simpler ways if you make assumptions about objective sense. You might just have to experiment with some examples.
... View more