3

First question on Stack overflow... love this website...

I am using PuLP on Python. Based on inputting variables, an objective function, and constraints, I am trying to view the dual variables/values that are associated with the optimal solution of initial LP problem (the primal). I am having trouble searching in the documentation and I just wanted to be clear. Is there a way to do this with pulp? There is example code below showing the input of the primal.

NOTE: I edited my question from asking for the dual to asking for the dual results (based on feedback).

NOTE2: Further edited for clarification based on feedback.

import pulp
lpProb = pulp.LpProblem("example", pulp.LpMinimize)
x1 = pulp.LpVariable("x1", 0, None, pulp.LpContinuous)
x2 = pulp.LpVariable("x2", 0, None, pulp.LpContinuous)
x3 = pulp.LpVariable("x3", 0, None, pulp.LpContinuous)
lpProb += 3*x1 + 4*x2 + 2*x3
lpProb += x1 + 2*x2 + x3 >= 42
lpProb += 5*x1 + 7*x2 + 4*x3 >= 68
lpProb.solve()
print(pulp.LpStatus[lpProb.status])
for i in lpProb.variables():
    print("Variable {0} = {1}".format(i.name, i.varValue))
print("Objective function z = {0}".format(pulp.value(lpProb.objective)))
josliber
  • 43,891
  • 12
  • 98
  • 133
  • AFAIK, I do not think such a utility exists. Why do you want to see visually the LP dual? I mean, what is the benefit over writing down the dual formulation by hand? – Ioannis Feb 04 '18 at 13:04
  • Ionnis, thanks for the reply. First, it is all intended to be done by an algorithm (as opposed by h and). Second, the dual can be found from the information given (without me having to define a second problem myself). Third, if I had to type in two problems, I might as well find another method (other than Pulp) that will let me directly translate the formulae and constraint to the matrix variables (C, X, A, B, etc.). That would defeat the purpose of using the library. Post-optimality analysis is a crucial piece of the puzzle. – Loosely Defined Feb 04 '18 at 17:04
  • Clarification, whatever method shows the dual from the first problem, may want to create another problem with it. I don't have a problem with this as long as I don't have to manually type up another problem (not preferred). – Loosely Defined Feb 04 '18 at 17:06
  • Could you elaborate on why you need to formulate the dual problem programmatically? What is the end goal? To the best of my knowledge, modern solvers do not provide this information, but they provide everything ones need to know about the dual solution, post-optimality analysis and methods that work in the dual space. – Ioannis Feb 05 '18 at 09:00
  • 1
    I assume you want the value of the dual variables in the optimal solution. The example https://github.com/coin-or/pulp/blob/master/examples/CG.py shows how to access these. – Stuart Mitchell Feb 05 '18 at 09:04
  • @Ioannis, sorry. I requested something relatively inflexible. I changed my question to be more flexible. Stuart's comment gave me a hint of the built-in method (which wasn't clear to me in the documentation). – Loosely Defined Feb 06 '18 at 03:28
  • @StuartMitchell, I changed my question to something more flexible. Based on your comment, I think I solved my question. Iterating through the constraints and looking at the .pi attribute and .slack attribute is what I am looking for. Is there anything that explicitly says w1, w2? Thanks!! – Loosely Defined Feb 06 '18 at 03:30
  • The dual of a problem is something very different from duals in a solution. – Erwin Kalvelagen Feb 06 '18 at 03:38
  • Your description led to an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). I suggest you remove the part that refers to generating the dual problem programatically and keep the real question, which is how to access the dual optimal solution. – Ioannis Feb 06 '18 at 09:49
  • 1
    Since nobody answered, the solution suggested by @StuartMitchell was to iterate through some items in lpProb.constraints.items() as shown below (code can be added to above example): for name, c in list(lpProb.constraints.items()): print(name, ":", c, "\t", c.pi, "\t\t", c.slack) – Loosely Defined Feb 18 '18 at 04:20

1 Answers1

3

The following was suggested by @StuartMitchell in the comments on the question. It prints the name, dual value, and slack of each constraint.

for name, c in list(lpProb.constraints.items()):
    print(name, ":", c, "\t", c.pi, "\t\t", c.slack)
josliber
  • 43,891
  • 12
  • 98
  • 133
  • Thanks. I didn't want to "answer my own question"...but I did want the solution to be visible. – Loosely Defined May 16 '18 at 04:56
  • @LooselyDefined I went ahead and made this a community wiki (so I don't get any reputation for it), but I wanted to make sure it was in the answer section instead of being edited into the question. Feel free to answer your own questions -- that is allowed on this site! – josliber May 16 '18 at 05:13