Find the variable values for different solutions by PoolSolutions
AnsweredI have a MIP and I am solving the model and collecting all the possible solutions by using PoolSolutions parameter, now I am trying to get the value of x variable for each solution but unfortunately, I am getting the same values of x each time, here is my code
# problem by using PoolSearchMode
from __future__ import print_function
import time
from gurobipy import *
import numpy as np
import networkx as nx
from networkx import diameter, eccentricity, connected_components
try:
n = 10
m = 20
G = nx.dense_gnm_random_graph(n, m)
V = G.nodes
A = G.edges
W = np.random.randint(1, 10, len(A))
for i, e in enumerate(A()):
G[e[0]][e[1]]['w'] = W[i]
print(nx.info(G))
print(nx.is_connected(G))
d = nx.get_edge_attributes(G, 'w')
B = [(j, i) for (i, j) in d.keys()]
NA = list(nx.non_edges(G))
A = list(G.edges())
V = G.nodes
n = len(V)
M = 2 * n
# number of partitions
c = 2
C = tuplelist(range(c))
# minimum number of nodes in each partition
a = 4
VV = tuplelist(range(n, n + c))
AA = []
for i in VV:
for j in V:
AA.append((i, j))
E = A + AA
outgoing = {i: [(j, k) for (k, j) in A if j == i] + [(k, j) for (k, j) in A if k == i] for i in V}
incoming = {i: [(j, k) for (j, k) in A + AA if k == i] + [(j, k) for (k, j) in A + AA if k == i] for i in V}
mo = Model()
# Variables
# x_i_j_k
x = mo.addVars(E, vtype=GRB.BINARY, name="x", lb=0)
# y_i_k
y = mo.addVars(V, C, vtype=GRB.BINARY, name="y", lb=0)
# f_i_j_k
f = mo.addVars(E + B, vtype=GRB.CONTINUOUS, name="f", lb=0)
obj = quicksum(x[i, j] * d[i, j] for (i, j) in A)
mo.setObjective(obj, GRB.MINIMIZE)
for i in V:
r1_name = "con_1" + str(i)
mo.addConstr(quicksum(y[i, k] for k in C) == 1, name=r1_name)
cont1 = 0
for k in C:
for (i, j) in A:
cont1 += 1
r2_name = "con_2" + str(cont1)
mo.addConstr(y[i, k] + y[j, k] - x[i, j] <= 1, name=r2_name)
cont2 = 0
for k in C:
for l in C:
for (i, j) in A:
if k != l:
cont2 += 1
r3_name = "con_3" + str(cont2)
mo.addConstr(y[i, k] + y[j, l] + x[i, j] <= 2, name=r3_name)
cont = 0
for k in VV:
r4_name = "con_4" + str(cont)
cont += 1
mo.addConstr(quicksum(x[k, i] for i in V) == 1, name=r4_name)
cont3 = 0
for k in C:
cont3 += 1
r5_name = "con_5" + str(k)
mo.addConstr(quicksum(f[k + n, i] for i in V) == quicksum(y[i, k] for i in V), name=r5_name)
cont4 = 0
for j in V:
cont4 += 1
r6_name = "con_6" + str(j)
mo.addConstr(quicksum(f[i, l] for (i, l) in incoming[j]) - quicksum(f[l, i] for (l, i) in outgoing[j]) == 1,
name=r6_name)
start = time.time()
cont5 = 0
for (i, j) in A:
cont5 += 1
r7_name = "con_7" + str(cont5)
mo.addConstr(f[i, j] + f[j, i] <= (n - (c - 1) * a) * x[i, j], name=r7_name)
cont6 = 0
for (k, i) in AA:
cont6 += 1
r8_name = "con_8" + str(cont6)
mo.addConstr(a * x[k, i] <= f[k, i], name=r8_name)
cont7 = 0
for (k, i) in AA:
cont7 += 1
r9_name = "con_9" + str(cont7)
mo.addConstr(f[k, i] <= (n - (c - 1) * a) * x[k, i], name=r9_name)
mo.optimize()
# Limit how many solutions to collect
mo.setParam(GRB.Param.PoolSolutions, 1000)
# Limit the search space by setting a gap for the worst possible solution
# that will be accepted
mo.setParam(GRB.Param.PoolGap, 0.05)
# do a systematic search for the k-best solutions
mo.setParam(GRB.Param.PoolSearchMode, 2)
# save problem
mo.write('poolsearch.lp')
# Optimize
mo.optimize()
mo.setParam(GRB.Param.OutputFlag, 0)
# Status checking
status = mo.Status
if status in (GRB.INF_OR_UNBD, GRB.INFEASIBLE, GRB.UNBOUNDED):
print('The model cannot be solved because it is infeasible or '
'unbounded')
sys.exit(1)
elif status != GRB.OPTIMAL:
print('Optimization was stopped with status ' + str(status))
sys.exit(1)
# else:
# # Print best selected set
# print('Selected elements in best solution:')
# for (i, j) in A:
# if x[i, j].X == 1:
# print((i, j))
# Print number of solutions stored
nSolutions = mo.SolCount
print('Number of solutions found: ' + str(nSolutions))
# Print objective values of solutions
for e in range(nSolutions):
mo.setParam(GRB.Param.SolutionNumber, e)
print('%g ' % mo.PoolObjVal, end='')
if e % 15 == 14:
print('')
print('')
# print the solutions
for nsol in range(nSolutions):
print(nsol)
mo.setParam(GRB.Param.SolutionNumber, nsol)
G = nx.Graph()
for (i, j) in A:
if x[i, j].X == 1:
print((i, j))
G.add_edge(i, j, weight=d[i, j])
S = [G.subgraph(c).copy() for c in nx.connected_components(G)]
avg_dia=0
for l in range(len(S)):
avg_dia+= diameter(S[l])
print(avg_dia)
except AttributeError as e:
print('Encountered an attribute error: ' + str(e))
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum, or try Gurobot, our chatbot interface offering instant, expert-level support. -
Hi Ahmad,
After setting the parameter SolutionNumber to the \(i\)-th best solution, the value of each variable can be accessed by querying the attribute Xn and not X (this attribute always reports the variable values in the current solution). In the last part of your code when checking whether a variable is assigned to value 1 or not, you need to check:
if x[i, j].Xn > 0.5:
I ran your code and I was able to see different values assigned to variables \(x\).
Best regards,
Maliheh
1 -
Thank you so much Maliheh, now it is working in a proper way
0
Post is closed for comments.
Comments
3 comments