Closed keyfri closed 6 years ago
Hi I may have found an issue by looking into your code. When you build the "optimality" array, you add constraints that have not been added to the model. In this case, Docplex actually returns 0 without raising an exception (I think it should). The workaround is to store exactly those constraints that are added to the model, that is:
ct = m.add(expr >= uf) # returns the added constraint m.optimality.append(ct) # store the added constraints.
In the code you sent, the constraints were duplicated; the call to dual values was receiving the copies unkwn to the model, hence the 0 value. Future versions of Docplex will make sure an exception is raised in this case.
However, as I could not run your code (extra functions, no data), this might not be the only issue. Let us know if the workaround works.
Regards.
Philippe Couronne (philippe.couronne@fr.ibm.com)
Dear Philippe, Thank you for your reply. I have modified the code following your opinion. However, The dual_value still 0 value. So I share my program on GitHub https://github.com/keyfri/patrol_code/blob/master/src/game_solution.py . Looking forward to hearing from you!
sincerely, Jinpeng Han
Dear Jinpeng
Thanks for sharing your code, this was very helpful as I could try to run it. I encountered a runtime error at this line:
#sub_set_of_attacker_strategies[2] = duals
where index 2 is out of bounds, so I commente dout this line. However, the computation of dual values is performed just above this line, so I was able to track this call to Cplex, and Cplex did return a list of zero values. As I recall, the dual value is the marginal impact on the cost of violating the constraint, but I could not relate the optimality constraints to the objective. You might need help from a mathematical expert in Linear Programming (I'm not) to investigate this further, sorry about that.
I had simplified your code to compute duals in:
duals = m.dual_values(m.optimality)
As Model.dual_values accepts sequences of constraints. I also wondered why you used factory functions (e.g. ge_constraint, le_constraint) rather than the overloaded Python operators such as >= , <=, ==
For example, instead of
ct = m.add(m.ge_constraint(expr, uf))
You can write
ct = m.ad(expr >= uf)
To summarize, with the modification, you code does call the Cplex dual values of the optimality constraint, and they are all zero.
Dear Jinpeng,
To investigate further your issue, I have modified your program to give names to optimality constraints, and exported the LP file. I then loaded this LP file into "cplex.exe", the interactive cplex optimizer, solved it and asked for the dualprices of all "optimality" constraints. Your issue is definitely a matehmatical one.
To add an optimality constraint with a name: ct = m.add(expr >= uf, "ct_optimality%d" % index) To export the model as a LP file: m.export_as_lp(basename="patrol") # relies on Python's tempfile module
Then uder cplex.exe, run the following commands
I get: Display dual values for which constraint(s): ct_optimality All dual prices matching 'ct_optimality' are 0.
Regards Philippe.
When i tell Model.dual_values(cts), the output just print '0'.
` class Solution: def init(self, args):
general method parameter
`