Skip to content Skip to sidebar Skip to footer

Convert String Representation Of A Comparison Formula Back To Formula

Python newbie here. I have a library function that is expecting a formula object; solver.Add(x + y < 5) However my formula is dynamic and being provided from another system as a

Solution 1:

The idea is that x and y are variables, e.g.,

x = solver.IntVar(0, xmax, 'x')
y = solver.IntVar(0, ymax, 'y')

so that when you call solver.Add(x + y < 5), python will look up the names x and y and substitute them for the objects they are. That is, IntVar + IntVar < 5, which will be a constraint object.

When you do eval('x + y < 5'), it's as if you're doing x + y < 5, so you just need to ensure that the names x and y exist in the current scope. There are two ways of achieving that, namely

var = req_json['Variables'][0]

exec('{0} = IntVar(0, {1}, "{0}")'.format(var['Name'], var['Max']))   # first
locals()[var['Name']] = IntVar(0, var['Max'], var['Name'])            # second

The first one creates the string 'x = IntVar(0, 10, "x")', which it executes as a literal python statement. While the second one creates the IntVar programmatically and then stores it in the name x. locals()['x'] = 1 is the equivalent of x = 1.

All in all, the solution could be

# You don't need to manually store the variables, as they're added in `solver.variables()`forvar in req_json['Variables']:
    name = var['Name']
    locals()[name] = solver.IntVar(0, var['Max'], name)
for constraint in req_json['Constraints']:
    solver.Add(eval(constraint['Formula']), constraint['Name'])

# However you decide what the expression is to maximise. Whether it's another key# in your `req_json` dict, or the LHS of the constraint formula. I'll just hardcode this.
solver.Maximize(x + y)

status = solver.Solve()

if status == pywraplp.Solver.OPTIMAL:
    print('Answer :')
    print('Objective value =', solver.Objective().Value())
    for v in solver.variables():
        print('{} = {}'.format(v.name(), v.solution_value()))

THIS ASSUMES THAT eval(constraint['Formula']) WILL NEVER DO ANYTHING MALICIOUS, which you say is your case. If you can't guarantee that, your other option is to parse the string manually for the variable names, operations and relations and build a safe string which can then be evaluated.

Finally, if you run this as is, you'll get an error saying

ValueError: Operators "<"and">"not supported with the linear solver

But if you change the constraint formula to 'x + y <= 5', it'll work just fine.

Post a Comment for "Convert String Representation Of A Comparison Formula Back To Formula"