Skip to content

Commit 13e4f81

Browse files
committed
updated source code
1 parent 32edd75 commit 13e4f81

File tree

65 files changed

+24978
-3953
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+24978
-3953
lines changed

.DS_Store

6 KB
Binary file not shown.

.ipynb_checkpoints/main-checkpoint.py

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
"""
2+
File name: main.py
3+
THis file will import data, call the optimization model, provide optimization result
4+
Input data, then, run the optimization model
5+
6+
Outline:
7+
1. Estimating input parameters
8+
2.
9+
3. Mdeling
10+
4. Sensitivity analysis
11+
5.
12+
13+
Developer: Tanmoy Das
14+
Date: Dec 2022
15+
"""
16+
# %%
17+
globals().clear() # Clear previous workspace
18+
# import library
19+
import pandas as pd
20+
import geopandas as gpd
21+
import custom_functions, data_visualization
22+
import model_PAMIP, model_analysis
23+
import shapely
24+
import numpy as np
25+
from sklearn.cluster import MiniBatchKMeans
26+
27+
28+
# import data
29+
spill_data = pd.read_excel('Inputs/data_PAMIP.xlsx', sheet_name='spills', header=0).copy()
30+
station_data = pd.read_excel('Inputs/data_PAMIP.xlsx', sheet_name='stations', header=0).copy()
31+
sensitivity_dataR = gpd.read_file('Inputs/ArcGIS_data/Sensitivity_data5.shp').copy()
32+
# %% Input parameters of the model
33+
# ++ think what is same across all model and scenes , move them at the top+++
34+
# pre-determined inputs
35+
NumberStMax = 5
36+
DistanceMax = 10 # 5
37+
38+
39+
coordinates_spill = custom_functions.extract_coordinate(spill_data)
40+
coordinates_st = custom_functions.extract_coordinate(station_data)
41+
num_customers = len(coordinates_spill)
42+
num_facilities = len(coordinates_st)
43+
44+
# ++ convert 10 into km using google map (for reporting, not related to modeling in this code)
45+
coor1 = (63.31720065616187, -90.65327442130385)
46+
coor2 = (61.99735832040513, -92.36804572739923)
47+
custom_functions.compute_distance(coor1, coor2)
48+
49+
50+
#%%
51+
pairings = {(c, f): custom_functions.compute_distance(coordinates_spill[c], coordinates_st[f])
52+
for c in range(num_customers)
53+
for f in range(num_facilities)
54+
if custom_functions.compute_distance(tuple(coordinates_spill[c]), tuple(coordinates_st[f])) < DistanceMax}
55+
56+
57+
print("Number of viable pairings: {0}".format(len(pairings.keys())))
58+
59+
# Weights and scaling
60+
# W = [1, 2000, 1]
61+
max_spill_size = max(spill_data['Spill size'])
62+
max_sensitivity = max(sensitivity_dataR['Sensitivit'])
63+
max_timeR = pairings[max(pairings, key=pairings.get )]
64+
min_spill_size = min(spill_data['Spill size'])
65+
min_sensitivity = min(sensitivity_dataR['Sensitivit'])
66+
min_timeR = pairings[min(pairings, key=pairings.get )]
67+
68+
# x* = (x-x_min)/(x_max - x_min)
69+
70+
#Demand = list(spill_data['Resource needed']).copy()
71+
72+
SizeSpill_R = list(spill_data['Spill size']).copy()
73+
Sensitivity_R = custom_functions.calculate_sensitivity(coordinates_spill, sensitivity_dataR)
74+
TimeR_R = pairings.copy() # compute_TimeR +++
75+
76+
#%% Normalize terms in objective function
77+
SizeSpill = []; Sensitivity = []; TimeR = []
78+
SizeSpill = [((SizeSpill_R[i]-min_spill_size)/(max_spill_size-min_spill_size)) for i in range(len(SizeSpill_R))]
79+
Sensitivity = [((Sensitivity_R[i]-min_sensitivity)/(max_sensitivity-min_sensitivity)) for i in range(len(Sensitivity_R))]
80+
81+
# TimeR = {((list(TimeR_R.values())[i]-min_timeR)/(max_timeR-min_timeR)) for i in range(len(TimeR_R))}
82+
TimeR_Scaled = [((list(TimeR_R.values())[i]-min_timeR)/(max_timeR-min_timeR)) for i in range(len(TimeR_R))]
83+
keysD = TimeR_R.keys()
84+
TimeR = {}
85+
for i in range(len(keysD)):
86+
TimeR[list(keysD)[i]] = TimeR_Scaled[i]
87+
# %% Predictive Analytics
88+
# Tradeoff curve for number of stations
89+
# ----------------------------------------------------------------------------------------------------------------------
90+
NumberStMax_list = [1,2,3,4 ,5,6,7,8,9,10]
91+
W1 = [[0.1, 0.2, 0.7], [0.8, 0.1, 0.1]] # from model configuration table
92+
Tradeoff_output = []
93+
for i in range(len(NumberStMax_list)):
94+
Wi = W1[1]
95+
NumberStMax = NumberStMax_list[i]
96+
m = 'm1' # m2
97+
model, cover, select, amount, mvars, names, values, \
98+
cover_1s, select_1s, amountSt_groupby, coverage_percentage, \
99+
ResponseTimeT, assignment3, spill_df, station_df, \
100+
sol_y, assignment, assignment2, assignment_name= model_PAMIP.solve(Wi, coordinates_st, coordinates_spill,
101+
pairings, SizeSpill, Sensitivity, TimeR, NumberStMax, m, spill_data)
102+
103+
Tradeoff_output.append([NumberStMax, coverage_percentage, int(ResponseTimeT*80)/11])
104+
105+
Tradeoff_Output_df = pd.DataFrame(Tradeoff_output)
106+
Tradeoff_Output_df.columns = ['NumberStMax', 'Coverage %', 'Response time (in hours)']
107+
Tradeoff_Output_df.to_csv('Outputs/Tradeoff_Output_df.csv')
108+
109+
#%% Draw the tradeoff line graph
110+
NumberStMax_data = pd.read_csv('Outputs/Tradeoff_Output_df.csv').copy()
111+
selected = 5
112+
data_visualization.draw_tradeoff_plot(NumberStMax_data, selected)
113+
114+
115+
116+
117+
#%% Model configurations and solutions table
118+
# ----------------------------------------------------------------------------------------------------------------------
119+
# Comparing models with different weight vectors
120+
import random
121+
values = [.1, .2, .3, .4, .5, .6, .7, .8]
122+
Wd = []
123+
for i in range(1000):
124+
w1 = random.choice(values); w2 = random.choice(values); w3 = random.choice(values)
125+
if w1+w2+w3 == 1.0:
126+
Wd.append([w1, w2, w3])
127+
# drop duplication values from list W
128+
W_Set = set(tuple(element) for element in Wd)
129+
W0 = [list(t) for t in set(tuple(element) for element in W_Set)]
130+
131+
W = [W0[i] for i in range(10)]
132+
133+
#%%
134+
m = 'm2'
135+
model_output = []
136+
# Draw Network Diagram
137+
for i in range(5):
138+
Wi = W[i]
139+
model, cover, select, amount, mvars, names, values, \
140+
cover_1s, select_1s, amountSt_groupby, coverage_percentage, \
141+
ResponseTimeT, assignment3, spill_df, station_df, \
142+
sol_y, assignment, assignment2, assignment_name = model_PAMIP.solve(Wi, coordinates_st, coordinates_spill,
143+
pairings, SizeSpill, Sensitivity, TimeR,
144+
NumberStMax, m, spill_data)
145+
146+
print(f'coverage_percentage: {coverage_percentage}, i: {i}')
147+
model_output.append([Wi, model.ObjVal, coverage_percentage, int(ResponseTimeT*80)/11])
148+
print('-------------------------------------------------------------')
149+
Model_Output = pd.DataFrame(model_output)
150+
Model_Output.columns = ['Weights', 'Objective Value', 'Coverage %', 'Response time (in hours)']
151+
Model_Output.to_csv('Outputs/Model_Output.csv')
152+
153+
# %% Draw Network Diagram
154+
# ----------------------------------------------------------------------------------------------------------------------
155+
# Examine model results
156+
# Sensitivity analysis
157+
158+
W1 = [[0.1, 0.2, 0.7], [0.8, 0.1, 0.1]] # from model configuration table
159+
for i in range(2):
160+
Wi = W1[i]
161+
m = 'm2' # m2
162+
model, cover, select, amount, mvars, names, values, \
163+
cover_1s, select_1s, amountSt_groupby, coverage_percentage, \
164+
ResponseTimeT, assignment3, spill_df, station_df, \
165+
sol_y, assignment, assignment2, assignment_name= model_PAMIP.solve(Wi, coordinates_st, coordinates_spill,
166+
pairings, SizeSpill, Sensitivity, TimeR, NumberStMax, m, spill_data)
167+
168+
model_analysis.draw_network_diagram(DistanceMax, NumberStMax, spill_df, station_df, ResponseTimeT, coverage_percentage,
169+
assignment3, cover_1s, select_1s, amountSt_groupby, m, Wi)
170+
171+
#%%
172+
# Feb 20
173+
import folium
174+
gdb1 = gpd.read_file('C:/Users/tanmo/Downloads/lpr_000b21f_e/lpr_000b21f_e.gdb')
175+
gdb1.plot()
176+
# Draw empty map +++
177+
# map_shipping_spill = folium.Map(location=spill_coordinates.iloc[0], zoom_start=4, min_zoom=2.5, max_zoom=7)
178+
# Draw the Shipping route
179+
# map_shipping_spill.choropleth(geo_data="Inputs/ArcGIS_data/Shipping_and_Hydrography.geojson")
180+
181+
# save this map as transparent .svg of jpg file , then import it as .svg file to matplotlib
182+
#+++
183+
#%% Data Scene 2
184+
#%% Clustering
185+
# ----------------------------------------------------------------------------------------------------------------------
186+
# %%
187+
globals().clear() # Clear previous workspace
188+
# import library
189+
import pandas as pd
190+
import geopandas as gpd
191+
import custom_functions, data_visualization
192+
import model_PAMIP, model_analysis
193+
import shapely
194+
import numpy as np
195+
from sklearn.cluster import MiniBatchKMeans
196+
197+
198+
# import data
199+
spill_data = pd.read_excel('Inputs/data_PAMIP.xlsx', sheet_name='spills', header=0).copy()
200+
station_data = pd.read_excel('Inputs/data_PAMIP.xlsx', sheet_name='stations', header=0).copy()
201+
sensitivity_dataR = gpd.read_file('Inputs/ArcGIS_data/Sensitivity_data5.shp').copy()
202+
# %% Input parameters of the model
203+
# ++ think what is same accross all model and scenes , move them at the top+++
204+
# pre-determined inputs
205+
NumberStMax = 5
206+
DistanceMax = 10 # 5
207+
208+
coordinates_spill = custom_functions.extract_coordinate(spill_data)
209+
coordinates_st = custom_functions.extract_coordinate(station_data)
210+
num_customers = len(coordinates_spill)
211+
num_facilities = len(coordinates_st)
212+
213+
import numpy as np
214+
# Import excel file (containing 10k records)
215+
spill_data_10000 = pd.read_excel('Inputs/Spill_info_4000.xlsx', header=0).copy()
216+
# randomly select 2k records
217+
spill_data_scene2 = spill_data_10000.sample(n=2000)
218+
spill_size = spill_data_scene2[['Spill size']]
219+
220+
coordinates_spill = custom_functions.extract_coordinate(spill_data_scene2)
221+
# Cluster them into 50 cluster
222+
num_clusters = 50
223+
kmeans = MiniBatchKMeans(n_clusters=num_clusters, init_size=3*num_clusters,
224+
).fit(coordinates_spill)
225+
memberships = list(kmeans.labels_)
226+
centroids = list(kmeans.cluster_centers_) # Center point for each cluster
227+
weights = list(np.histogram(memberships, bins=num_clusters)[0]) # Number of customers in each cluster
228+
print('First cluster center:', centroids[0])
229+
print('Weights for first 10 clusters:', weights[:10])
230+
231+
# Draw
232+
icon_size_list = []
233+
# Draw the oil spills
234+
for point_spill in range(0, len(coordinates_spill)):
235+
icon_size = int((spill_size.iloc[point_spill, 0]/spill_size.max())*20)
236+
icon_size_list.append(icon_size)
237+
238+
data_visualization.draw_cluster(icon_size_list, coordinates_spill, memberships, centroids)
239+
240+
#%% Apply optimization model
241+
# Input parameters
242+
coordinates_spill = kmeans.cluster_centers_.tolist()
243+
pairings = custom_functions.compute_pairing(coordinates_spill, coordinates_st, DistanceMax)
244+
Size_DS1 = list(spill_data_scene2['Spill size']).copy()
245+
246+
247+
#%%
248+
cluster_index = {}
249+
for j in range(len(centroids)):
250+
cluster_index[j] = [i for i, x in enumerate(memberships) if x == j]
251+
SizeSpill_Rc = [sum([e for i, e in enumerate(Size_DS1) if i in cluster_index[ii]]) for ii in range(len(cluster_index))]
252+
Sensitivity_Rc = custom_functions.calculate_sensitivity(coordinates_spill, sensitivity_dataR)
253+
TimeRc = pairings.copy()
254+
255+
max_spill_size = max(SizeSpill_Rc)
256+
min_spill_size = min(SizeSpill_Rc)
257+
258+
max_sensitivity = max(Sensitivity_Rc)
259+
min_sensitivity = min(Sensitivity_Rc)
260+
261+
max_timeR = pairings[max(pairings, key=pairings.get )]
262+
min_timeR = pairings[min(pairings, key=pairings.get )]
263+
264+
SizeSpill = []; Sensitivity = []; TimeR = [];
265+
SizeSpill = [((SizeSpill_Rc[i]-min_spill_size)/(max_spill_size-min_spill_size)) for i in range(len(SizeSpill_Rc))]
266+
Sensitivity = [((Sensitivity_Rc[i]-min_sensitivity)/(max_sensitivity-min_sensitivity)) for i in range(len(Sensitivity_Rc))]
267+
268+
# TimeR = {((list(TimeR_R.values())[i]-min_timeR)/(max_timeR-min_timeR)) for i in range(len(TimeR_R))}
269+
TimeR_Scaled = [((list(TimeRc.values())[i]-min_timeR)/(max_timeR-min_timeR)) for i in range(len(TimeRc))]
270+
keysD = TimeRc.keys()
271+
TimeR = {}
272+
for i in range(len(keysD)):
273+
TimeR[list(keysD)[i]] = TimeR_Scaled[i]
274+
275+
276+
277+
m = 'm2'
278+
spill_data = spill_data_scene2
279+
280+
281+
#%%
282+
# Solve the model
283+
W1 = W #[[0.1, 0.2, 0.7], [0.2, 0.7, 0.1]] # from model configuration table
284+
for i in range(10):
285+
Wi = W1[i]
286+
m = 'm2' # m2
287+
model, cover, select, amount, mvars, names, values, \
288+
cover_1s, select_1s, amountSt_groupby, coverage_percentage, \
289+
ResponseTimeT, assignment3, spill_df, station_df, \
290+
sol_y, assignment, assignment2, assignment_name= model_PAMIP.solve(Wi, coordinates_st, coordinates_spill,
291+
pairings, SizeSpill, Sensitivity, TimeR, NumberStMax, m, spill_data_scene2)
292+
293+
model_analysis.draw_network_diagram(DistanceMax, NumberStMax, spill_df, station_df, ResponseTimeT, coverage_percentage,
294+
assignment3, cover_1s, select_1s, amountSt_groupby, m, Wi)

0 commit comments

Comments
 (0)