-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathFCNF.py
executable file
·103 lines (76 loc) · 2.61 KB
/
FCNF.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python
from gurobipy import *
import StringIO
import sys
# Flow conservation/sink/source
vertices = {0: 4, 1: 3, 2: 2, 3: 0, 4: -6, 5: -3}
# Capacities and cost. Format is key: edge, value: (capacity, cost per flow, cost to open)
edges = {(0,4): (4,1,1),
(0,3): (2,1,1),
(1,3): (3,1,1),
(2,5): (2,1,1),
(3,4): (2,1,1),
(3,5): (1,1,1)}
def mycallback(model, where):
if where == GRB.callback.MESSAGE:
print >>model.__output, model.cbGet(GRB.callback.MSG_STRING),
def transform(vertices, edges, params):
newEdges = {}
i = 0
for edge in edges:
newEdges[(edge[0], edge[1])] = params[i]
i += 1
# Fix javascript format
newVertices = {}
for v in vertices:
newVertices[int(v)] = vertices[v]
solution = optimize(newVertices, newEdges)
return solution
def optimize(vertices, edges, output=False):
m = Model()
x = {} # Flow on each edge
y = {} # Binary variable for each edge
edgeIn = { v:[] for v in vertices }
edgeOut = { v:[] for v in vertices }
# Add variables
for edge in edges:
u = edge[0]
v = edge[1]
y[edge] = m.addVar(vtype=GRB.BINARY, name="y" + str(edge))
x[edge] = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="x" + str(edge) )
edgeIn[v] = edgeIn[v] + [x[edge]]
edgeOut[u] = edgeOut[u] + [x[edge]]
m.update()
# Add constraints
for v in vertices:
m.addConstr(quicksum(edgeOut[v]) - quicksum(edgeIn[v]) == vertices[v], name="v%d" % v)
for edge in edges:
m.addConstr(x[edge] <= edges[edge][0]*y[edge], name=str(edge))
# Set objective
m.setObjective(quicksum((edges[edge][1]*x[edge] + edges[edge][2]*y[edge]) for edge in edges), GRB.MINIMIZE)
if not output:
m.params.OutputFlag = 0;
m.setParam('TimeLimit', 10)
output = StringIO.StringIO()
m.__output = output
m.optimize(mycallback)
if (m.status != 2):
return ["error"]
solEdges = []
solWidth = []
for edge in edges:
if (y[edge].X > .5): # if edge was opened
solEdges.append([edge[0], edge[1]])
solWidth.append(x[edge].X)
solution = [solEdges, solWidth, output.getvalue()]
return solution
def handleoptimize(jsdict):
if 'vertices' and 'edges' and 'params' in jsdict:
solution = transform(jsdict['vertices'], jsdict['edges'], jsdict['params'])
return {'solution': solution }
if __name__ == '__main__':
import json
jsdict = json.load(sys.stdin)
jsdict = handleoptimize(jsdict)
print 'Content-Type: application/json\n\n'
print json.dumps(jsdict)