def cost(sol, Geox, Geoy, PD, Type, Tractx, Tracty, PD_beforenormalize, cnum): """Calculate the overall cost of a new solution: two type: demand-population, supply-transmission(transmission-demand) Input: sol - new solution: location in the form of the index Geox - Geoy - PD - Type - Tractx - Tracty - Output: cost of the new solution and the population assignment for the demand nodes of the new solution """ Popu_assign, Popu_assign2 = np.zeros(len(sol)), np.zeros(len(sol)) Sum_Cost = 0 for i in range(len(Tractx)): Dist = np.empty(len(sol), dtype=float) for k in range(len(sol)): Dist[k] = math.sqrt((Tracty[i] - Geoy[sol[k][0]])**2 + (Tractx[i] - Geox[sol[k][1]])**2) index = sf.minimumk(Dist, min(cnum, len(sol))) ratio = sf.FeatureScaling3( np.sum(np.exp(Dist[index])) / np.exp(Dist[index])) for k in range(len(index)): Popu_assign[index[k]] += PD_beforenormalize[i] * ratio[k] Popu_assign2[index[k]] += PD[i] * ratio[k] if (Type == 'Population'): Sum_Cost += Popu_assign2[index[k]] * Dist[index[k]] else: Sum_Cost += Dist[index[k]] return Sum_Cost, Popu_assign
def cost_cal(self, Type, Tract_pop, Tractx, Tracty): """Calculate the normalized demand-population cost """ Geox1 = sf.FeatureScaling(self.Geox) Geoy1 = sf.FeatureScaling(self.Geoy) Tract_pop1 = sf.FeatureScaling(Tract_pop) Tractx1 = sf.FeatureScaling(Tractx) Tracty1 = sf.FeatureScaling(Tracty) self.cost = ans.cost(self.loc[self.supplynum:, :], Geox1, Geoy1, Tract_pop1, Type, Tractx1, Tracty1)
def cost_cal(self, Type, Tract_pop, Tractx, Tracty, cnum): """Calculate the normalized demand-population cost """ Geox1 = sf.FeatureScaling(self.Geox) Geoy1 = sf.FeatureScaling(self.Geoy) Tract_pop1 = sf.FeatureScaling(Tract_pop) Tractx1 = sf.FeatureScaling(Tractx) Tracty1 = sf.FeatureScaling(Tracty) self.cost, temp = ans.cost(self.demandloc, Geox1, Geoy1, Tract_pop1, Type, Tractx1, Tracty1, Tract_pop, cnum)
def cost_cal(self, Type, Tract_pop, Tractx, Tracty): """Calculate the normalized demand-population cost """ Geox1 = sf.FeatureScaling(self.Geox) Geoy1 = sf.FeatureScaling(self.Geoy) Tract_pop1 = sf.FeatureScaling(Tract_pop) Tractx1 = sf.FeatureScaling(Tractx) Tracty1 = sf.FeatureScaling(Tracty) self.cost = ans.cost(np.array(self.nodelocindex), Geox1, Geoy1, Tract_pop1, Type, Tractx1, Tracty1, Tract_pop, dt.cnum)[0]
def network_setup(self, Tract_density, Tractx, Tracty, i, lon, lat, cnum): """Initialize everything for networks: location, distance matrix, degreesequence, cost, cluster_coeff, efficiency, diameter Input: Tract_density - 1D numpy array: population data of each tract in the area Tractx - 1D numpy array Tracty - 1D numpy array i - the number of the network in the system: i = 1, 2, 3 representing water, power and gas Output: \ """ self.Nodelocation(Tract_density, Tractx, Tracty, lon, lat, cnum) ##from GOOGLE API get the elevation self.GoogleAPIele() self.Distmatrix() #Decision of network adjacent matrix of three networks while (1): self.sampleseq = np.random.poisson(dt.fitdegree[i], size=self.nodenum) if (self.sampleseq.all() != 0): #if(np.max(self.sampleseq) >= 5): #continue break self.connection(self.sampleseq, dt.num) self.create_edgelist() self.degree, self.Ndegree = sf.degreeNdegree(self.Adjmatrix) #Plot each single infrastructure network # self.drawnetwork(dt.Type1, dt.llon, dt.rlon, dt.llat, dt.rlat) #plt.savefig("{} network.png".format(self.name), dpi = 2000) ##Calculate the network topology features self.cal_topology_feature() self.cost_cal(dt.Type2, Tract_density, Tractx, Tracty, cnum)
def mstseednode(self): """Set up the minimum spanning tree of the seeded nodes """ mst = sf.mst(self.dseedmatrix) for i in range(len(mst)): self.adjmatrix[self.seedindex[mst[i][0]], self.seedindex[mst[i][1]]] = 1
def Connect(loc, m, sourcenum): """Connect the vertices generated in Function Nodeloc - generate the adjacent matrix Input: loc - vertex location geographically m - the most m cloest facilities to be connected Output: distmatrix - the distance matrix of the vertices adjmatrix - the adjacent matrix of the vertices """ distmatrix = np.zeros([len(loc), len(loc)]) for i in range(len(loc)): for j in range(len(loc)): distmatrix[i, j] = sf.dist(loc[i, 0], loc[i, 1], loc[j, 0], loc[j, 1]) #Calculate the adjacent matrix adjmatrix = np.zeros([len(loc), len(loc)]) for i in range(len(distmatrix) - sourcenum): index = sorted(range(len(distmatrix[i + sourcenum, :])), key=lambda k: distmatrix[i + sourcenum, :][k]) adjmatrix[i + sourcenum, index[0:m]] = 1 adjmatrix[index[0:m], i + sourcenum] = 1 return distmatrix, adjmatrix
def cost(Network, Tract_pop, Tractx, Tracty, Geox, Geoy, cnum): """Calculate the overall cost all a new solution: two type: demand-population, supply-transmission(transmission-demand) """ x = sf.FeatureScaling2(Network.demandx, np.min(Geox), np.max(Geox) - np.min(Geox)) y = sf.FeatureScaling2(Network.demandy, np.min(Geoy), np.max(Geoy) - np.min(Geoy)) Tract_pop1 = sf.FeatureScaling(Tract_pop) Tractx1 = sf.FeatureScaling(Tractx) Tracty1 = sf.FeatureScaling(Tracty) Sum_Cost = 0 Popu_assign2 = np.zeros(len(x)) for i in range(len(Tractx1)): Dist = np.empty(len(x), dtype=float) for k in range(len(x)): Dist[k] = math.sqrt((Tracty1[i] - y[k])**2 + (Tractx1[i] - x[k])**2) index = sf.minimumk(Dist, min(cnum, len(x))) ratio = sf.FeatureScaling3( np.sum(np.exp(Dist[index])) / np.exp(Dist[index])) for k in range(len(index)): Popu_assign2[index[k]] += Tract_pop1[i] * ratio[k] Sum_Cost += Popu_assign2[index[k]] * Dist[index[k]] Network.cost = Sum_Cost
def Distmatrix(self): """Calculate the distance matrix for the vertices in the network """ self.Dismatrix = np.zeros((self.nodenum, self.nodenum)) for i in range(len(self.Dismatrix)): for j in range(len(self.Dismatrix)): self.Dismatrix[i, j] = sf.dist(self.y[i], self.x[i], self.y[j], self.x[j]) self.Dismatrix[j, i] = self.Dismatrix[i, j]
def Connect(self, m): """Connect the vertices generated in Function Nodeloc - generate the adjacent matrix Input: m - the most m cloest facilities to be connected Output: distmatrix - the distance matrix of the vertices adjmatrix - the adjacent matrix of the vertices """ self.distmatrix = np.zeros([len(self.loc), len(self.loc)]) for i in range(len(self.loc)): for j in range(len(self.loc)): self.distmatrix[i, j] = sf.dist(self.Geoloc[i, 0], self.Geoloc[i, 1], self.Geoloc[j, 0], self.Geoloc[j, 1]) #Calculate the adjacent matrix self.adjmatrix = np.zeros([len(self.loc), len(self.loc)]) for i in range(len(self.demandseries)): minindex = np.array(sf.minimumk(self.distmatrix[:self.demandseries[i], self.demandseries[i]], m)) self.adjmatrix[minindex, self.demandseries[i]] = 1
def Distmatrix(self): """Define the distance matrix of this dependency Ex: self.distmatrix[i, j] - the distance between node i in network3 and middle point of link j in internet from network1 to network2 Output: 2D numpy array, the distance matrix of the dependency """ self.distmatrix = np.zeros((self.nodenum3, self.linknum), dtype=float) for i in range(self.nodenum3): for j in range(self.linknum): self.distmatrix[i, j] = sf.dist(self.network3.y[self.network3.demandseries[i]], self.network3.x[self.network3.demandseries[i]], \ self.internet1net2.edgelist[j]["middley"], self.internet1net2.edgelist[j]["middlex"])
def Distmatrix(self): """Define the distance matrix of this dependency Ex: self.distmatrix[i, j] - the distance between node i in network1 and node j in network2 Output: 2D numpy array, the distance matrix of the dependency """ self.distmatrix = np.zeros((self.nodenum1, self.nodenum2), dtype=float) for i in range(self.nodenum1): for j in range(self.nodenum2): self.distmatrix[i, j] = sf.dist(self.network1.y[self.network1.demandseries[i]], self.network1.x[self.network1.demandseries[i]], \ self.network2.y[self.network2.supplyseries[j]], self.network2.x[self.network2.supplyseries[j]])
def Adjmatrix(self): """Define the adjacent matrix of this dependency Input: \ Output: 2D numpy array, the adjacent matrix of the dependency """ self.adjmatrix = np.zeros((self.nodenum1, self.nodenum2), dtype=int) for i in range(self.nodenum2): minindex = np.array( sf.minimumk(self.distmatrix[:, i], self.nearestnum)) self.adjmatrix[minindex, i] = 1
def distmatrix(self): """Set up the distance matrix of the network """ import numpy as np self.nodexnormal, self.nodeynormal = sf.FeatureScaling( self.nodex), sf.FeatureScaling(self.nodey) self.dmatrix = np.empty((self.nodenum, self.nodenum), dtype=float) self.dnormalmatrix = np.empty((self.nodenum, self.nodenum), dtype=float) for i in range(self.nodenum): for j in range(i, self.nodenum): self.dmatrix[i, j] = sf.dist(self.nodey[i], self.nodex[i], self.nodey[j], self.nodex[j]) self.dmatrix[j, i] = self.dmatrix[i, j] self.dnormalmatrix[i, j] = sf.dist(self.nodeynormal[i], self.nodexnormal[i], self.nodeynormal[j], self.nodexnormal[j]) self.dnormalmatrix[j, i] = self.dnormalmatrix[i, j]
def assignprob(self, density): """Calculate the assignment probability based on population density Input: density - the density of the population distribution Output: the cumu_prob along with the index transformatino metric """ prob = sf.FeatureScaling3(density**self.gamma) temp1 = len(prob[0]) probflatten = prob.flatten() cumu_prob = [] cumu_prob_index = [] for i in range(len(probflatten)): cumu_prob_index.append([i % temp1, int(i / temp1)]) if (i == 0): cumu_prob.append(probflatten[i]) else: cumu_prob.append(probflatten[i] + cumu_prob[-1]) return cumu_prob, cumu_prob_index
def Nodelocation(self, Tract_pop, Tractx, Tracty, longitude, latitude, cnum): """Annealing simulation to decide the node location """ import annealsimulation self.latl, self.lonl = [], [] while (len(self.latl) != self.nodenum): lat = np.random.randint(len(self.Geoy) - 1) lon = np.random.randint(len(self.Geox) - 1) if (lat not in self.latl or lon not in self.lonl): self.latl.append(lat) self.lonl.append(lon) self.latl, self.lonl = np.array(self.latl), np.array(self.lonl) self.demandlat, self.demandlon = self.latl[ self.demandseries], self.lonl[self.demandseries] self.tranlat, self.tranlon = self.latl[self.transeries], self.lonl[ self.transeries] self.supplylat, self.supplylon = self.latl[ self.supplyseries], self.lonl[self.supplyseries] self.demandloc = np.stack((self.demandlat, self.demandlon)).transpose() self.tranloc = np.stack((self.tranlat, self.tranlon)).transpose() self.supplyloc = np.stack((self.supplylat, self.supplylon)).transpose() #Demand node Geox1 = sf.FeatureScaling(self.Geox) Geoy1 = sf.FeatureScaling(self.Geoy) Tract_pop1 = sf.FeatureScaling(Tract_pop) Tractx1 = sf.FeatureScaling(Tractx) Tracty1 = sf.FeatureScaling(Tracty) self.demandloc, self.demandc, self.popuassign = ans.anneal2( self.demandloc, 'Population', Geox1, Geoy1, Tract_pop1, Tractx1, Tracty1, Tract_pop, cnum) self.demandy1 = Geoy1[self.demandloc[:, 0]] self.demandx1 = Geox1[self.demandloc[:, 1]] self.demandy = self.Geoy[self.demandloc[:, 0]] self.demandx = self.Geox[self.demandloc[:, 1]] #Transmission node self.tranloc, self.tranc, temp = ans.anneal2(self.tranloc, 'Facility', Geox1, Geoy1, Tract_pop1, self.demandx1, self.demandy1, Tract_pop, cnum) self.trany1 = Geoy1[self.tranloc[:, 0]] self.tranx1 = Geox1[self.tranloc[:, 1]] self.trany = self.Geoy[self.tranloc[:, 0]] self.tranx = self.Geox[self.tranloc[:, 1]] #Supply node self.supplyloc, self.supplyc, temp = ans.anneal2( self.supplyloc, 'Facility', Geox1, Geoy1, Tract_pop1, self.tranx1, self.trany1, Tract_pop, cnum) self.supplyy1 = Geoy1[self.supplyloc[:, 0]] self.supplyx1 = Geox1[self.supplyloc[:, 1]] self.supplyy = self.Geoy[self.supplyloc[:, 0]] self.supplyx = self.Geox[self.supplyloc[:, 1]] ##Coordinates of nodes self.y = np.concatenate((self.supplyy, self.trany, self.demandy)) self.x = np.concatenate((self.supplyx, self.tranx, self.demandx)) ##Latitudes and longitudes of nodes self.demandlatitude, self.demandlongitude = latitude[ self.demandloc[:, 0]], longitude[self.demandloc[:, 1]] self.tranlatitude, self.tranlongitude = latitude[ self.tranloc[:, 0]], longitude[self.tranloc[:, 1]] self.supplylatitude, self.supplylongitude = latitude[ self.supplyloc[:, 0]], longitude[self.supplyloc[:, 1]] self.latitude = np.concatenate( (self.supplylatitude, self.tranlatitude, self.demandlatitude)) self.longitude = np.concatenate( (self.supplylongitude, self.tranlongitude, self.demandlongitude))
Shelby_Water.x, Shelby_Water.y, Shelby_Water.Type = WX, WY, WType Shelby_Power.x, Shelby_Power.y, Shelby_Power.Type = PX, PY, PType Shelby_Gas.x, Shelby_Gas.y, Shelby_Gas.Type = GX, GY, GType supplytrandemandxy(Shelby_Water) supplytrandemandxy(Shelby_Power) supplytrandemandxy(Shelby_Gas) ShelbyNetwork = [Shelby_Water, Shelby_Power, Shelby_Gas] edge = [Wedge, Pedge, Gedge] for i in range(len(ShelbyNetwork)): Network = ShelbyNetwork[i] Network.Distmatrix() Adjmatrix(Network, edge[i], Network.Type) Network.degree, Network.Ndegree = sf.degreeNdegree(Network.Adjmatrix) Network.drawnetwork(dt.Type1, dt.llon, dt.rlon, dt.llat, dt.rlat) Network.cal_topology_feature() # cost(Network, Tract_pop, Tractx, Tracty, Geox, Geoy) cost(Network, Tract_pop, Tractx, Tracty, Geox, Geoy, dt.cnum) # ##------------------------------------------------------------------------------ #plt.figure(figsize = (20, 12)) #Base = bm.BaseMapSet(dt.Type1, dt.llon, dt.rlon, dt.llat, dt.rlat) # #Wx, Wy = Base(Wlon, Wlat) #Px, Py = Base(Plon, Plat) #Gx, Gy = Base(Glon, Glat) # ###Water network
dt.para_pdemand2wpinterlink) #Initialilze the dependency of gas-power links on power demand nodes for increasing pressure pdemand2gpinterlink = phynode2interlink(gdemand2psupply, Power, dt.para_pdemand2gpinterlink) interdependency = [ gdemand2psupply, wdemand2psupply, pdemand2glink, pdemand2wlink, pdemand2wpinterlink, pdemand2gpinterlink ] #Save all data required for solving nonlinear optimization in julia #Network information for Network in networklist: Network.datacollection() sf.savenetworkfeature(Network, Temp) #interdependency for i in range(len(interdependency)): path1 = './p2jdata/adjdist/' + str( Temp) + '/' + interdependency[i].name + 'adj.csv' path2 = './p2jdata/adjdist/' + str( Temp) + '/' + interdependency[i].name + 'distnode2node.csv' np.savetxt(path1, interdependency[i].adjmatrix, delimiter=',') np.savetxt(path2, interdependency[i].distmatrix, delimiter=',') if (i >= 2): path3 = './p2jdata/adjdist/' + str( Temp) + '/' + interdependency[i].name + 'link2nodeid.csv' np.savetxt(path3,
topo_eff2[i].append(Network.topo_efficiency) eff2[i].append(Network.efficiency) cluster_coeff2[i].append(Network.cluster_coeff) topodiameter2[i].append(Network.topodiameter) diameter2[i].append(Network.diameter) cost2[i].append(Network.cost) degree2[i].append(Network.degree) Temp += 1 print(Temp) ##Remove the element of the infinity value in list network.efficiency eff1 = [sf.Removeinf(eff1[0]), sf.Removeinf(eff1[1]), sf.Removeinf(eff1[2])] key1, key2 = ['Method1', 'Method2', 'The real network'], ['Water', 'Power', 'Gas'] #Compare several features of networks genering using different methods and original networks ##Cost: demand - population value = [Shelby_Water.cost, Shelby_Power.cost, Shelby_Gas.cost] cost1_ave, cost2_ave, cost1_std, cost2_std, cost1_cv, cost2_cv = sf.statistical_analysis('Cost', cost1, cost2, value, dt.color_compare, dt.num_compare, key1, key2) ##Cluster_coeff value = [Shelby_Water.cluster_coeff, Shelby_Power.cluster_coeff, Shelby_Gas.cluster_coeff] cluster1_ave, cluster2_ave, cluster1_std, cluster2_std, cluster1_cv, cluster2_cv = sf.statistical_analysis('Cluster coefficient', cluster_coeff1, cluster_coeff2, value, dt.color_compare, dt.num_compare, key1, key2) ##Spatial efficiency
def connection(self, sampleseq, num): """Calculate the adjacent matrix between supply node and transmission node Input: the nodal neighborhood degree sequence, d: the number of adjacent nodes Output: the adjacent matrix between supply and transmission nodes """ self.Adjmatrix = np.zeros((self.nodenum, self.nodenum), dtype=int) for i in range(self.supplynum): minindex = np.array( sf.minimumk( self.Dismatrix[self.supplyseries[i], self.trandemandseries], sampleseq[self.supplyseries[i]])) self.Adjmatrix[self.supplyseries[i], self.trandemandseries[minindex]] = 1 # self.Adjmatrix[minindex, self.supplyseries[i]] = 1 for i in range(self.trannum): if (np.sum(self.Adjmatrix[self.supplyseries, self.transeries[i]]) == 0): minindex = np.array( sf.minimumk( self.Dismatrix[self.supplyseries, self.transeries[i]], num)) self.Adjmatrix[minindex, self.transeries[i]] = 1 # self.Adjmatrix[self.transeries[i], minindex] = 1 # for i in range(self.supplynum): # minindex = np.array(sf.minimumk(self.Dismatrix[self.supplyseries[i], self.supplyseries], num)) # self.Adjmatrix[self.supplyseries[i], minindex] = 1 # self.Adjmatrix[minindex, self.supplyseries[i]] = 1 # for i in range(self.trannum): # if(np.sum(self.Adjmatrix[self.supplyseries, self.transeries[i]]) != 0): # continue # minindex = np.array(sf.minimumk(self.Dismatrix[self.supplyseries, self.transeries[i]], num)) # self.Adjmatrix[minindex, self.transeries[i]] = 1 ## self.Adjmatrix[self.transeries[i], minindex] = 1 # for i in range(self.trannum): minindex = np.array( sf.minimumk( self.Dismatrix[self.transeries[i], self.demandseries], min(sampleseq[self.transeries[i]], self.demandnum))) + self.supplynum + self.trannum self.Adjmatrix[self.transeries[i], minindex] = 1 # self.Adjmatrix[minindex, self.transeries[i]] = 1 # for i in range(self.demandnum): # if(np.sum(self.Adjmatrix[self.transeries, self.demandseries[i]]) == 0): # minindex = np.array(sf.minimumk(self.Dismatrix[self.transeries, self.demandseries[i]], 1)) + self.supplynum # self.Adjmatrix[minindex, self.demandseries[i]] = 1 # for i in range(self.trannum): # minindex = np.array(sf.minimumk(self.Dismatrix[self.transeries[i], self.transeries], num)) + self.supplynum # self.Adjmatrix[self.transeries[i], minindex] = 1 for i in range(self.demandnum): if (np.sum(self.Adjmatrix[self.transeries, self.demandseries[i]]) == 0): minindex = np.array( sf.minimumk( self.Dismatrix[self.transeries, self.demandseries[i]], num)) + self.supplynum self.Adjmatrix[minindex, self.demandseries[i]] = 1 # self.Adjmatrix[self.demandseries[i], minindex] = 1 for i in range(self.demandnum): minindex = np.array( sf.minimumk( self.Dismatrix[self.demandseries[i], self.demandseries], min(sampleseq[self.demandseries[i]] + 1, self.demandnum))) + self.supplynum + self.trannum minindex = minindex[1:-1] for j in range(len(minindex)): if (self.Adjmatrix[self.demandseries[i], minindex[j]] == 1 or self.Adjmatrix[minindex[j], self.demandseries[i]] == 1): continue self.Adjmatrix[self.demandseries[i], minindex[j]] = 1