Convert String Representation Of A Comparison Formula Back To Formula
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"