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))
-
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
Please sign in to leave a comment.
Comments
2 comments