Newer
Older
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 25 15:58:34 2018
@author: GVKD1542
"""
''' GENERAL '''
from numpy.random import random as rd
from numpy import ceil
from numpy import floor
import threading
from globals import *
import time
def phi(instance,i,j=-1):
#(unused?) function giving correspondance between (i,j) indexing in a matrix and k (linear) indexing in a set
#defines both direct and inverse functions
# matrix indexing --> set indexing
if(j!=-1):
if(i<j):
k=i
i=j
j=k
res = sum(instance.n-k for k in range(1,j))+(i-j)
return res
# set indexing --> matrix indexing
else:
n = instance.n
k=i
l,p=1,1
while(i>(n-1)):
i-=instance.n-1
n-=1
p+=1
l=i+p
return (l,p)
def set_bounds(instance, i, j):
#creates the appropriate bounds for the solution values
if(i<=j):
return(-1,-1)
if(j==0): #bridge connecting to the depot
return (0,2)
return (0,1) #other bridge
def lower_tri_filter(instance,i,j):
# unused?) pyomo filter for selecting only valid bridges (i,j)
return j<i
def rule_deg(instance,i):
#returns the rule for constructing degree constraints
return sum( ( instance.x[i,j] if i>j else instance.x[j,i] ) for j in instance.nodes if i!=j ) == (2 if i>0 else 2*instance.number_of_vehicles)
def stop_loop():
#returns a random bool
return np.random.random()>0.1
def continue_column_generation(instance,loop_count):
#must check whether enough constraints have been generated
#define an arbitrary max number of iterations
if loop_count>=max_column_generation_count :
return False
#for the future : devise a strategy based on instance (possibly on the value of the objective function)
#to decide whether or not we must stop the constraint generation
return True
def solution_is_integer(instance):
#returns bool describing wheter instance.x only has integers
# with slack epsilon (eps)
for b in instance.x.keys():
try:
val = instance.x[b].value
expr = abs(round(val)-val)>eps
except TypeError:
raise NameError("found None for x[i,j] where i="+str(n)+" and j="+str(m))
if expr:
return False
return True
def is_int(x):
#returns bool describing wheter pyo.Par/pyo.Var x is integer
# with slack epsilon (eps)
return abs(round(x.value)-x.value)<eps
def integerize_solution(instance):
#rounds solution values of instance that has been considered integer enough
for b in instance.x.keys():
instance.x[b].value = round(instance.x[b].value)
def show_entries(instance):
#shows the entries of instance
for p in instance.component_objects(Param,active=True):
parameter = getattr(instance,str(p))
print(parameter)
for i in parameter :
if (type(i) in [int,float64,float] and i > 5) or (type(i)==tuple and 6 in i):
break
if type(parameter[i]) in [int,str,float,float64]:
print(parameter[i])
else:
print(parameter[i].value)
def count_fixed_variables(instance):
count = 0
for b in instance.x.keys():
if instance.x[b].fixed == True :
count+=1
return count
def to_dict(instance):
#return a conversion of instance.x to a dictionary containing only valid bridges (i>j)
convert = {}
for brige in instance.x.keys():
convert[bridge] = instance.x[bridge].value
return converts
def to_list_locations(instance):
d = []
for i in instance.nodes:
d.append((instance.locations[i,0],instance.locations[i,1]))
return d
def get_safe_counter():
lock = threading.Lock()
return safe_counter(lock)
class safe_counter():
def __init__(self,lock):
self.val = 0
self.lock = lock
def increment(self):
try:
self.lock.acquire()
self.val += 1
finally:
self.lock.release()
def get(self):
return self.val
def get_and_increment(self):
try :
self.lock.acquire()
num = self.val
self.val +=1
return num
finally :
self.lock.release()
def list_to_string(ls):
#returns more readible string of a list
expr = ""
for el in ls:
expr += str(el)+"/"
return expr[:-1]
def integer_percent(instance):
count = 0
pos = 0
for b in instance.x.keys():
count += 1
if is_int(instance.x[b]):
pos += 1
return round(pos/count*100,2)
class timer():
def __init__(self):
self.origin = time.time()
self.pred = self.origin
self.curr = self.origin
def lap(self):
self.curr = time.time()
elapsed = round(self.curr - self.pred,2)
self.pred = time.time() #we don't take self.curr for more precision
return str(elapsed)
def empty_lap(self):
self.cur = time.time()
def print_elapsed(self):
el = self.lap()
return("in "+el+" seconds (global clock : "+str(round(time.time()-self.origin,2))+")")
def reset(self):
self = timer()
def global_time(self):
return time.time()-self.origin
time_record = timer()
def pprint(message):
print(message)
print(time_record.print_elapsed())
print()
def reset_timer():
time_record.reset()
def empty_time_lap():
time_record.empty_lap()
def max_time_not_reached():
return time_record.global_time() < max_global_time