-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfixanddive.py
executable file
·82 lines (57 loc) · 2.03 KB
/
fixanddive.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env python3.9
# Copyright 2022, Gurobi Optimization, LLC
# Implement a simple MIP heuristic. Relax the model,
# sort variables based on fractionality, and fix the 25% of
# the fractional variables that are closest to integer variables.
# Repeat until either the relaxation is integer feasible or
# linearly infeasible.
import sys
import gurobipy as gp
from gurobipy import GRB
# Key function used to sort variables based on relaxation fractionality
def sortkey(v1):
sol = v1.X
return abs(sol-int(sol+0.5))
if len(sys.argv) < 2:
print('Usage: fixanddive.py filename')
sys.exit(0)
# Read model
model = gp.read(sys.argv[1])
# Collect integer variables and relax them
intvars = []
for v in model.getVars():
if v.VType != GRB.CONTINUOUS:
intvars += [v]
v.VType = GRB.CONTINUOUS
model.Params.OutputFlag = 0
model.optimize()
# Perform multiple iterations. In each iteration, identify the first
# quartile of integer variables that are closest to an integer value in the
# relaxation, fix them to the nearest integer, and repeat.
for iter in range(1000):
# create a list of fractional variables, sorted in order of increasing
# distance from the relaxation solution to the nearest integer value
fractional = []
for v in intvars:
sol = v.X
if abs(sol - int(sol+0.5)) > 1e-5:
fractional += [v]
fractional.sort(key=sortkey)
print('Iteration %d, obj %g, fractional %d' %
(iter, model.ObjVal, len(fractional)))
if len(fractional) == 0:
print('Found feasible solution - objective %g' % model.ObjVal)
break
# Fix the first quartile to the nearest integer value
nfix = max(int(len(fractional)/4), 1)
for i in range(nfix):
v = fractional[i]
fixval = int(v.X+0.5)
v.LB = fixval
v.UB = fixval
print(' Fix %s to %g (rel %g)' % (v.VarName, fixval, v.X))
model.optimize()
# Check optimization result
if model.Status != GRB.OPTIMAL:
print('Relaxation is infeasible')
break