I have the Constraint: $$ | \sum x_{i} - n/2 | \leq 0 $$
where each $x_{i}$ is a binary variable, and $n$ is the total number of variables.
in docplex, I encode this as:
mod.add_constraint(mod.abs(sum([i for i in var]) - n//2) <= 0)
When I do so, docplex creates an SOS (special ordered set). These sets are are not handled by the secondary method I am using, which causes an error.
As I cannot alter the secondary function, I have been trying to find a way to compute absolute value without calling mod.abs(), mod.max() (which causes a similar problem) or squaring terms. One simple way to do so (logically) is:
P = sum([i for i in var] - n//2)
if -P >= P:
P = -P
Doing this directly causes docplex to throw "no linear constraint in logical test" error, and Report "Cannot convert linear constraint to a boolean value: (-x0-x1-x2... + n) >= (x0 + x1 + x2...-n)".
All I really want here, is for the value of P to always be positive. Is there a more simple way (perhaps through an indicator, an if-else constraint, or big M) that I can encode this?
I do not think that in general, there is a better way to write $\left|\sum_i x_i - \frac n2\right| \le 0$ than $\sum_i x_i = \frac n2$: if there were, wouldn't we use it on all equality constraints all the time?
But to answer the question more generally, if we want to encode a constraint of the form $|A| \le B$ without using absolute value, one natural option is the pair of constraints $$\begin{cases}\phantom{-}A \le B, \\ -A \le B. \end{cases}$$ This will not work with a lower bound on the absolute value, because $|A| \ge B$ is not a convex constraint.