0

I'm trying to use mystic to create a simplified expression of my constraints. I have an array of 200 elements. I'm first testing for 1 constraint, which is limiting the sum of all the variables between min and max limits like this:

0 <= x0 + x1 + x2 + ....... x198 + x199 <= 20000

The issue is this process is taking too long to simplify just for this 1 constraint alone - approx 1hr (haven't even added others yet). How can I resolve this?

min_lim = 0
max_lim = 20000

def constraint_func():
    variable_num = ['x'+str(i) for i in range(200)]
    constrain_eq = f'{min_lim} <=' + ' + '.join(variable_num) + f' <= {max_lim}'
    return constrain_eq

eqn = ms.simplify(constraint_func(), all=True)
constrain = ms.generate_constraint(ms.generate_solvers(eqn), join=my.constraints.and_)
star_it8293
  • 399
  • 3
  • 12
  • I don't think `mystic` can handle multiple equations/inequalities in a single expression -- you'll need to add each of the bounds in a separate line. – Mike McKerns Feb 22 '23 at 13:10

1 Answers1

1

Mystic can't handle both <= in the same equation. Essentially, it hangs on the call. If you modify the code as below, the simplify operation takes just a second or so (on my ancient MacOS).

import mystic.symbolic as ms
min_lim = 0
max_lim = 20000

def constraint_func():
    variable_num = ['x'+str(i) for i in range(200)]
    constraint_1 = f'{min_lim} <= ' + ' + '.join(variable_num)
    constraint_2 = f'{max_lim} >= ' + ' + '.join(variable_num)
    return '\n'.join([constraint_1, constraint_2])

eqn = ms.simplify(constraint_func(), all=True)

As an aside, there's still a subtle potential issue. Both of the constraints will be simplified with x0 isolated on the left-hand side. You can alternately isolate two different target variables (x0 and x1, respectively), and then combine the simplified equations, like this:

>>> import mystic.symbolic as ms
>>> min_lim = 0
>>> max_lim = 20000
>>> variable_num = ['x'+str(i) for i in range(200)]
>>> constraint_1 = f'{min_lim} <= ' + ' + '.join(variable_num)
>>> constraint_2 = f'{max_lim} >= ' + ' + '.join(variable_num)
>>> eqn1 = ms.simplify(constraint_1, all=True, target='x0')
>>> eqn2 = ms.simplify(constraint_2, all=True, target='x1')
>>> eqn = '\n'.join([eqn1,eqn2])

I can't say which of the above two simplifications should work better for you, it's often problem-dependent.

Mike McKerns
  • 33,715
  • 8
  • 119
  • 139