0

I am building a routing optimization model using pyomo on python.

I have solved my model but I am trying to extract the decision variable information for my model. My model is binary, and the values I am looking for are values of my model.z decision variable that equal to 1.

When I write instance.pprint() I get the following sample of output. I therefore want to code something that gives me only the decision variables that are equal to 1 such as z(1,4).

enter image description here

Sample of my code is shown below:

model.I = RangeSet(5)
model.J = RangeSet(5)


model.z = Var(model.I, model.J, domain = Binary) 


def constraint (model,i):
    return sum(model.z[i,j] - model.z[j,i] for j in model.J if i != j) == 0
model.constraint = Constraint(model.I, rule=constraint)


print()
z_values = pd.Series(model.z[i,j].extract_values(), name = model.z.name)
print(z_values)

I have tried the above code but as some of my values are 0 (because they have not being visited), I have been getting the following error message.

ValueError: Error retrieving component z[5,4]: The component has not been constructed.

Ideally the output should be something like this:

(0,3) -- 1
(1,2) -- 1
(2,4) -- 1
(3,1) -- 1
(4,5) -- 1
(5,0) -- 1

Any ideas?

Berbatov
  • 11
  • 2

1 Answers1

0

This should work (and answer your other derivative question)

# value extract

import pyomo.environ as pyo

nodes = [1,2,3,4,5,6]

model = pyo.ConcreteModel()

model.N = pyo.Set(initialize=nodes)

model.Z = pyo.Var(model.N, model.N, domain=pyo.Binary, initialize=0)  # only initializing here for demo...

# blah blah constraints & solve

# stuff in some fake results...
model.Z[1, 2] = 1
model.Z[2, 6] = 1
model.Z[3, 5] = 1
model.Z[6, 3] = 1

# model.display()

# make a dictionary of the route ...
# recall that binary "1" variables evaluate as True

route = {start: stop for (start, stop) in model.Z.index_set() if pyo.value(model.Z[start, stop])}
# print(route)

start_node = 1
print(f'from {start_node} ', end='')
while start_node in route.keys():
    end_node = route.get(start_node)
    print(f'-> {end_node} ' , end='')
    start_node = end_node
AirSquid
  • 10,214
  • 2
  • 7
  • 31
  • When inputting: route = {start: stop for (start, stop) in model.Z.index_set() if pyo.value(model.Z[start, stop])} # print(route), the error message is still coming up. 'ValueError: Error retrieving component x[1,1]: The component has not been constructed.' – Berbatov Mar 28 '22 at 19:02
  • So basically, I am looking to read any of my model.Z values that have been visited (i.e the values that are True). Is there a way of calling all these 'True' values maybe? – Berbatov Mar 28 '22 at 19:09
  • You might need to edit your post above with enough code to reproduce the error.... some subset of your problem. There must be some issue with how you are initializing values... – AirSquid Mar 28 '22 at 19:10
  • try `model.Z.display()` after solving and look for anomalies. – AirSquid Mar 28 '22 at 19:11
  • You are likely not initializing all of Z for `nodes x nodes` full set. So you can initialize with a zero (like I did) just to put a value in there, or if you have some defined set of "legal connections" like distances, you can use *that* subset of `nodes x nodes` as the basis for the dictionary and then you won't touch the non-initialized values. Or..... You could use that "legal connections" set as the index set when you construct Z, which would compact your model a bit. – AirSquid Mar 28 '22 at 19:19
  • I have editted the post to include some more of the code which should be enough so that the problem may be solved. – Berbatov Mar 29 '22 at 09:30
  • Also, when I try 'model.x.display(). I get the 'following output x : Size=0, Index=x_index Not constructed' – Berbatov Mar 29 '22 at 09:39