-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptimize.py
123 lines (105 loc) · 6.55 KB
/
optimize.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
""" Interdiction events from optimization model """
import numpy as np
import math
def optimize_interdiction_batch(ADJ):
trgtfile = r'data/data_MTMCI/MTMCI_IntNodes.txt'
Tintevent = np.loadtxt(trgtfile, dtype=int)
intrdct_events = np.zeros(ADJ.shape)
intrdct_nodes = Tintevent
for j in np.arange(0, len(Tintevent)):
iupstream = (ADJ[:, Tintevent[j] - 1] == 1)
intrdct_events[iupstream, Tintevent[j] - 1] = 1
return intrdct_events, intrdct_nodes
def optimizeroute_multidto(dtorefvec, subflow, supplyfit, expmax, subroutepref, dtoEdgeTable, dtoSLRISK, dtoADDVAL,
dtoCTRANS, losstolval, dtoslsuc):
iactiveedges = np.concatenate((np.where(subflow > 0), np.where(dtoslsuc > 0)), axis=1)
edgeparms = []
for edge in range(len(iactiveedges[0])):
edgeparms.append(np.array([subflow[iactiveedges[0][edge], iactiveedges[1][edge]],
dtoSLRISK[iactiveedges[0][edge], iactiveedges[1][edge]], iactiveedges[0][edge],
iactiveedges[1][edge]]))
edgeparms = np.array(edgeparms)
if supplyfit < losstolval: # need to consolidate supply chain
edgesort = edgeparms[edgeparms[:, 1].argsort()[::-1]]
# primary movement
iprimary = list(np.intersect1d(np.where(edgesort[:, 2] == 0)[0],
np.where(edgesort[:, 3] != len(dtorefvec) - 1)[0]))
upper_lim = min(round(len(iactiveedges[0]) * (supplyfit / (supplyfit + losstolval))), len(iactiveedges[0]) - 1)
if upper_lim > 0:
edgecut = np.arange(0, upper_lim)
else:
edgecut = []
# Preserve at least one primary movement
minrisk_primary = np.amin(edgesort[iprimary, 1])
ikeep_primary = np.where(edgesort[iprimary, 1] == minrisk_primary)[0]
if len(ikeep_primary) != 1:
maxprofit_primary = max(edgesort[iprimary[ikeep_primary], 0])
ikeep_primary = ikeep_primary[edgesort[iprimary[ikeep_primary], 0] == maxprofit_primary]
if len(ikeep_primary) != 1:
ikeep_primary = ikeep_primary[0]
if len(edgecut) > 0:
edgecut = np.delete(edgecut, np.intersect1d(edgecut, [iprimary[ikeep_primary[0]]] +
list(np.where(edgesort[edgecut, 2] ==
edgesort[iprimary[ikeep_primary[0]], 3])[0])))
# remove highest risk edges
for j in range(0, len(edgecut)):
icheckroute = np.where(subflow(edgesort[edgecut[j], 3],
np.intersect1d(dtorefvec, dtoEdgeTable['EndNodes'].str[1]
[np.where(dtoEdgeTable['EndNodes'].str[0] ==
dtorefvec[edgesort[edgecut[j], 3]])[0]]))
> 0)
actroutes = dtoEdgeTable['EndNodes'].str[1][np.where(dtoEdgeTable['EndNodes'].str[0] ==
dtorefvec[edgesort[edgecut[j], 3]])[0]]
checknoderoutes = (
len(actroutes[icheckroute]) == len(np.where(edgesort[edgecut, 3] == edgesort[edgecut[j], 3])))
if checknoderoutes:
cutsenders = np.where(dtorefvec[np.in1d(dtorefvec,
dtoEdgeTable['EndNodes'].str[0]
[np.where(dtoEdgeTable['EndNodes'].str[1] ==
dtorefvec[edgesort[edgecut[j], 3]])[0]])]
== 1)
for i in range(len(cutsenders)):
subroutepref[cutsenders[i], edgesort[edgecut[j], 3]] = 0
if len(icheckroute) == 1:
subroutepref[edgesort[edgecut[j], 2]] = 0
irmvsender = (edgesort[:, 4] == edgesort[edgecut[j], 3])
subroutepref[edgesort[irmvsender, 2]] = 0
else:
subroutepref[edgesort[edgecut[j], 2]] = 0
elif supplyfit >= losstolval: # need to expand supply chain
potnodes = np.delete(dtorefvec, np.in1d(dtorefvec, np.concatenate(([1], dtorefvec[np.int_(
np.unique(edgeparms[:, 2:4]))].flatten())))).reshape(-1, 1)
edgeadd = np.arange(0, min(max(math.ceil(supplyfit / losstolval), 1), min(expmax, len(potnodes))))
if len(np.where(potnodes)[0]) == 0:
pass
else:
newedgeparms = []
potsenders = np.int_(np.unique(edgeparms[:, 2:4])) # dto node index
potsenders = potsenders[potsenders != len(dtorefvec)]
for k in range(0, len(potsenders)):
ipotreceive = np.where(np.in1d(potnodes,
dtoEdgeTable['EndNodes'].str[1][np.where(dtoEdgeTable['EndNodes'].str[0]
== dtorefvec[potsenders[k], 0])
[0]]) == 1)[0]
if len(np.where(ipotreceive)[0]) == 0:
continue
ipotedge_col = np.where(np.in1d(dtorefvec, potnodes[ipotreceive]) == 1)[0]
for i in range(len(ipotedge_col)):
newedgeparms.append([(dtoADDVAL[potsenders[k], ipotedge_col[i]] -
dtoCTRANS[potsenders[k], ipotedge_col[i]]),
dtoSLRISK[potsenders[k], ipotedge_col[i]], potsenders[k], ipotedge_col[i],
ipotreceive[i]])
newedgeparms = np.array(newedgeparms)
edgesort = newedgeparms[newedgeparms[:, 0].argsort()[::-1]]
subroutepref[np.int_(edgesort[edgeadd, 2]), np.int_(edgesort[edgeadd, 3])] = 1
rows = np.in1d(dtoEdgeTable['EndNodes'].str[0], dtorefvec[np.int_(edgesort[edgeadd, 3])])
ireceivers = [dtoEdgeTable.loc[row, 'EndNodes'] for row in range(len(rows)) if rows[row]]
ireceivers = np.array(ireceivers)
send_row = []
rec_col = []
for jj in range(0, len(ireceivers[:, 0])):
send_row = np.append(send_row, np.where(np.in1d(dtorefvec, ireceivers[jj, 0]) == 1)[0])
rec_col = np.append(rec_col, np.where(np.in1d(dtorefvec, ireceivers[jj, 1]) == 1)[0])
subroutepref[np.int_(send_row), np.int_(rec_col)] = 1
subroutepref[np.int_(rec_col), len(dtorefvec)] = 1
return subroutepref