-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPyomoSolver.py
156 lines (108 loc) · 4.69 KB
/
PyomoSolver.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import numpy as np
import pyomo.environ as pyo
import time
class PyomoSolver:
def __init__(self, N, M, C = None, D = None):
self.N = N
self.M = M
if C is None or D is None:
self.dynamic = True
model = pyo.ConcreteModel()
model.Users = pyo.RangeSet(0, N - 1)
model.Items = pyo.RangeSet(0, M - 1)
# the next line declares a variable
model.x = pyo.Var(model.Users, model.Items, domain=pyo.NonNegativeReals, bounds=(0, 1))
model.C = pyo.Param(model.Items, mutable=True)
model.D = pyo.Param(model.Users, mutable=True)
def cap_constraint_rule(m, i):
return sum(m.x[u, i] for u in range(N)) <= m.C[i]
def dem_constraint_rule(m, u):
return sum(m.x[u, i] for i in range(M)) <= m.D[u]
model.CapConstraint = pyo.Constraint(model.Items, rule=cap_constraint_rule)
model.DemConstraint = pyo.Constraint(model.Users, rule=dem_constraint_rule)
model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
model.Theta = pyo.Param(model.Users, model.Items, mutable=True)
for u in range(N):
for i in range(M):
model.Theta[u, i] = 1
def obj_expression(m):
return -1 * pyo.summation(m.Theta, m.x)
model.OBJ = pyo.Objective(rule=obj_expression)
self.model = model
self.pyomo_opt = pyo.SolverFactory('glpk')
else:
self.dynamic = False
model = pyo.ConcreteModel()
model.Users = pyo.RangeSet(0, N - 1)
model.Items = pyo.RangeSet(0, M - 1)
# the next line declares a variable
model.x = pyo.Var(model.Users, model.Items, domain=pyo.NonNegativeReals, bounds=(0, 1))
def cap_constraint_rule(m, i):
return sum(m.x[u, i] for u in range(N)) <= C[i]
def dem_constraint_rule(m, u):
return sum(m.x[u, i] for i in range(M)) <= D[u]
model.CapConstraint = pyo.Constraint(model.Items, rule=cap_constraint_rule)
model.DemConstraint = pyo.Constraint(model.Users, rule=dem_constraint_rule)
model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
model.Theta = pyo.Param(model.Users, model.Items, mutable=True)
for u in range(N):
for i in range(M):
model.Theta[u, i] = 1
def obj_expression(m):
return -1 * pyo.summation(m.Theta, m.x)
model.OBJ = pyo.Objective(rule=obj_expression)
self.model = model
self.pyomo_opt = pyo.SolverFactory('glpk')
def _solve_system_static(self, R, C=None, D=None, x_prev = None, p_init=None):
N, M = R.shape
if p_init is not None:
c = self.model.CapConstraint
for index in c:
self.model.dual[c[index]] = p_init[index]
if x_prev is not None:
for u in range(N):
for i in range(M):
self.model.x[u, i] = x_prev[u, i]
for u in range(N):
for i in range(M):
self.model.Theta[u, i] = R[u, i]
self.pyomo_opt.solve(self.model)
x_opt = np.zeros((N, M))
for u in range(N):
for i in range(M):
x_opt[u, i] = np.int32(self.model.x[u, i].value)
return np.int32(x_opt)
def _solve_system_dynamic(self, R, C, D, x_prev=None, p_init=None):
N, M = R.shape
if p_init is not None:
c = self.model.CapConstraint
for index in c:
self.model.dual[c[index]] = p_init[index]
if x_prev is not None:
for u in range(N):
for i in range(M):
self.model.x[u, i] = x_prev[u, i]
for u in range(N):
for i in range(M):
self.model.Theta[u, i] = R[u, i]
for u in range(N):
self.model.D[u] = D[u]
for i in range(M):
self.model.C[i] = C[i]
self.pyomo_opt.solve(self.model)
x_opt = np.zeros((N, M))
for u in range(N):
for i in range(M):
x_opt[u, i] = np.int32(self.model.x[u, i].value)
return np.int32(x_opt)
def solve_system(self, *args, **kwargs):
if self.dynamic:
return self._solve_system_dynamic(*args, **kwargs)
else:
return self._solve_system_static(*args, **kwargs)
def get_prices(self):
c = self.model.CapConstraint
prices = np.zeros(self.M)
for index in c:
prices[index] = np.abs(self.model.dual[c[index]])
return prices