|
| 1 | +#这是居民区停车场有序充电的仿真程序 |
| 2 | + |
| 3 | +以下程序为一个整体的.py文件 |
| 4 | +``` |
| 5 | +# -*- coding: utf-8 -*- |
| 6 | +""" |
| 7 | +Created on Thu May 18 14:21:11 2017 |
| 8 | +Orderly Charging Method with Topsis Algorithm |
| 9 | +@author: Leung |
| 10 | +""" |
| 11 | +``` |
| 12 | +只需要numpy包,因此先载入: |
| 13 | +``` |
| 14 | +import numpy as np |
| 15 | +``` |
| 16 | +并定义一个类,*AISITERO*: |
| 17 | +``` |
| 18 | +class AISITERO: |
| 19 | +``` |
| 20 | +程序初始化(注意 *def* 前面有缩进,下面的 *def* 也一样): |
| 21 | +``` |
| 22 | + def __init__(self,weight,num,sercost): |
| 23 | + self.weight=weight #topsis算法权重 |
| 24 | + self.num=num #电动汽车及充电桩数量 |
| 25 | + self.sercost=sercost #服务费 |
| 26 | + self.price=[] #峰谷平电价 |
| 27 | + self.residentload=[] #居民用电负荷 |
| 28 | + self.bodong=[] #居民用电负荷波动 |
| 29 | + self.avapiles=[] #可用充电桩数量 |
| 30 | + self.carimf=[] #电动汽车信息 |
| 31 | + self.lefttime=[]#np.zeros(num) #外出时间 |
| 32 | + self.cometime=[]#np.zeros(num) #回来时间 |
| 33 | + self.cargo=[] |
| 34 | + self.totaltime=0 #总等待时间 |
| 35 | + self.offpower=np.zeros(num) #电量耗尽不能出行次数 |
| 36 | + self.leftpower=np.ones(num)*0.6 #剩余电量百分比 |
| 37 | + self.outpower=[]#np.zeros(num) #出行剩余电量值 |
| 38 | + self.ischarging=np.zeros((num,),dtype=np.int) #未充电为0在充电为1 |
| 39 | + self.off=0 #不能出行次数 |
| 40 | + self.waittime=np.zeros(num) #等待时间 |
| 41 | + self.longgest=0 #最长充电时间 |
| 42 | + self.totalcost=0 #充电金额 |
| 43 | + self.money=[] #每个时刻的充电金额 |
| 44 | + self.isgoout=[]#np.zeros((num,),dtype=np.int) #不出行为0出行为1 |
| 45 | + self.where=np.zeros((num,),dtype=np.int) #在外为1在小区为0 |
| 46 | + self.tempwhere=np.zeros((num,),dtype=np.int) #前一个状态 |
| 47 | + self.chargingnum=[] #充电数量 |
| 48 | + self.staytime=np.zeros(num) #停留时间 |
| 49 | + self.day=30 #仿真天数 |
| 50 | + self.ke=0 #仿真时刻 |
| 51 | + self.nengcho=0 #能充电的数量 |
| 52 | + self.totalload=[] #总负荷 |
| 53 | + self.satisfaction=np.zeros(7) #充电满意程度规律 |
| 54 | + self.zuidari=0 |
| 55 | + self.zuidashi=0 |
| 56 | + self.riqi=0 |
| 57 | +``` |
| 58 | +获取初始数据函数: |
| 59 | +``` |
| 60 | + def readimf(self): |
| 61 | + self.residentload=np.loadtxt('小区居民日常负荷数据.txt') |
| 62 | + self.carimf=np.loadtxt('carimf.txt') |
| 63 | + self.price=np.loadtxt('price.txt') |
| 64 | + self.cargo=np.loadtxt('cargo.txt') |
| 65 | +``` |
| 66 | +每天生成新状态: |
| 67 | +``` |
| 68 | + def newdaystate(self,riqi): |
| 69 | + i=0 |
| 70 | + self.lefttime=[] |
| 71 | + self.cometime=[] |
| 72 | + self.isgoout=[] |
| 73 | + self.outpower=[] |
| 74 | + che=self.cargo[(riqi-1)*60:riqi*60] |
| 75 | + while i<self.num: |
| 76 | + self.isgoout.append(int(che[i][2])) |
| 77 | + self.lefttime.append(che[i][0]) |
| 78 | + self.cometime.append(che[i][1]) |
| 79 | + self.outpower.append(che[i][3]) |
| 80 | + i+=1 |
| 81 | + self.offpower=np.zeros(self.num) |
| 82 | +``` |
| 83 | +每个时间节点的变动: |
| 84 | +``` |
| 85 | + def newdaystate(self,riqi): |
| 86 | + #每天生成新状态 |
| 87 | + i=0 |
| 88 | + self.lefttime=[] |
| 89 | + self.cometime=[] |
| 90 | + self.isgoout=[] |
| 91 | + self.outpower=[] |
| 92 | + che=self.cargo[(riqi-1)*60:riqi*60] |
| 93 | + while i<self.num: |
| 94 | + self.isgoout.append(int(che[i][2])) |
| 95 | + self.lefttime.append(che[i][0]) |
| 96 | + self.cometime.append(che[i][1]) |
| 97 | + self.outpower.append(che[i][3]) |
| 98 | + i+=1 |
| 99 | + self.offpower=np.zeros(self.num) |
| 100 | + |
| 101 | + def newstate(self): |
| 102 | + #变动新状态 |
| 103 | + self.bodong=self.residentload[int(self.ke*4)][1]#+random.uniform(-5,5) |
| 104 | + i=0 |
| 105 | + while i<self.num: #记录上一个状态,不能直接赋值,不然会有问题 |
| 106 | + if self.where[i]==0: |
| 107 | + self.tempwhere[i]=0 |
| 108 | + else: |
| 109 | + self.tempwhere[i]=1 |
| 110 | + i+=1 |
| 111 | + i=0 |
| 112 | + while i<self.num: #判断电动汽车是否在外 |
| 113 | + if self.lefttime[i]>self.ke: |
| 114 | + self.where[i]=0 |
| 115 | + elif self.cometime[i]>self.ke: |
| 116 | + self.where[i]=1 |
| 117 | + else: |
| 118 | + self.where[i]=0 |
| 119 | + i+=1 |
| 120 | + i=0 |
| 121 | + self.where=list(map(lambda x,y:x*y,self.where,self.isgoout)) |
| 122 | + print('是否外出:') |
| 123 | + print(self.where) |
| 124 | + while i<self.num: |
| 125 | + if self.tempwhere[i]!=self.where[i]: #状态发生改变的 |
| 126 | + if self.where[i]==0: #从外面回来? |
| 127 | + self.waittime[i]=0 |
| 128 | + self.staytime=list(map(lambda x,y:y-x,self.lefttime,np.ones(self.num)*self.ke)) |
| 129 | + else: #从小区出去? |
| 130 | + self.ischarging[i]=0 |
| 131 | + if self.leftpower[i]==1: |
| 132 | + self.satisfaction[0]+=1 |
| 133 | + self.satisfaction[6]+=1 |
| 134 | + elif self.leftpower[i]>0.9: |
| 135 | + self.satisfaction[1]+=1 |
| 136 | + self.satisfaction[6]+=1 |
| 137 | + elif self.leftpower[i]>0.8: |
| 138 | + self.satisfaction[2]+=1 |
| 139 | + self.satisfaction[6]+=1 |
| 140 | + elif self.leftpower[i]>0.7: |
| 141 | + self.satisfaction[3]+=1 |
| 142 | + self.satisfaction[6]+=1 |
| 143 | + elif self.leftpower[i]>0.6: |
| 144 | + self.satisfaction[4]+=1 |
| 145 | + self.satisfaction[6]+=1 |
| 146 | + elif self.leftpower[i]<0.2: |
| 147 | + self.satisfaction[5]+=1 |
| 148 | + self.satisfaction[6]+=1 |
| 149 | + else: |
| 150 | + self.satisfaction[6]+=1 |
| 151 | + self.leftpower[i]*=self.outpower[i] #这里重新生成剩余电量,应该以里程来生成,而不是直接乘随机数 |
| 152 | + if self.leftpower[i]<0.1: |
| 153 | + self.where[i]=0 |
| 154 | + self.waittime[i]+=0.25 |
| 155 | + self.offpower[i]+=1 |
| 156 | + else: |
| 157 | + if self.where[i]==0: #未外出的 |
| 158 | + if self.ischarging[i]==1: |
| 159 | + self.leftpower[i]+=self.carimf[i][4] |
| 160 | + self.waittime[i]=0 |
| 161 | + if self.leftpower[i]>1: |
| 162 | + self.leftpower[i]=1 |
| 163 | + self.ischarging[i]=0 |
| 164 | + else: |
| 165 | + if self.isgoout[i]==1: |
| 166 | + if self.leftpower[i]!=1: |
| 167 | + self.waittime[i]+=0.25 |
| 168 | + else: #外出的 |
| 169 | + self.waittime[i]=0 |
| 170 | + i+=1 |
| 171 | + print('用户等待时间(小时):') |
| 172 | + print(self.waittime) |
| 173 | + print('电动汽车剩余电量比例:') |
| 174 | + print(self.leftpower) |
| 175 | + if self.riqi>1: |
| 176 | + if self.longgest<max(self.waittime): |
| 177 | + self.longgest=max(self.waittime) |
| 178 | + self.zuidari=self.riqi |
| 179 | + self.zuidashi=self.ke |
| 180 | +``` |
| 181 | +*Topsis* 排序: |
| 182 | +``` |
| 183 | + def topsis(self): |
| 184 | + power=np.ones(self.num)-self.leftpower |
| 185 | + index=[self.waittime,self.staytime,power] |
| 186 | + np.savetxt('index.txt',index) |
| 187 | + index=np.loadtxt('index.txt') #因为列表类型的问题,写出再读入就好了,2333333 |
| 188 | + #index=list(index) |
| 189 | + print("评估矩阵:") |
| 190 | + print(index) |
| 191 | + a=len(index[0]) |
| 192 | + b=len(index) |
| 193 | + pfh=np.empty([b,1]) |
| 194 | + i=0;j=0 |
| 195 | + ndata=index*index |
| 196 | + while j<b : |
| 197 | + pfh[j]=sum(ndata[j]) |
| 198 | + j+=1 |
| 199 | + j=0 |
| 200 | + guiy=np.empty([b,a]) |
| 201 | + while i<a : |
| 202 | + while j<b : |
| 203 | + guiy[j][i]=index[j][i]/pfh[j]**0.5 |
| 204 | + j+=1 |
| 205 | + j=0;i+=1 |
| 206 | + print("标准化评估矩阵:") |
| 207 | + print(guiy) |
| 208 | + i=0 |
| 209 | + weigf=np.empty([b,a]) |
| 210 | + while i<a : |
| 211 | + while j<b : |
| 212 | + weigf[j][i]=self.weight[j]*guiy[j][i] |
| 213 | + j+=1 |
| 214 | + j=0;i+=1 |
| 215 | + i=0 |
| 216 | + print("权重标准化矩阵:") |
| 217 | + print(weigf) |
| 218 | + best=np.empty([b,1]) |
| 219 | + worst=np.empty([b,1]) |
| 220 | + while j<b : |
| 221 | + best[j]=max(weigf[j]) |
| 222 | + worst[j]=min(weigf[j]) |
| 223 | + j+=1 |
| 224 | + j=0 |
| 225 | + print("最优指标值:") |
| 226 | + print(best) |
| 227 | + print("最差指标值:") |
| 228 | + print(worst) |
| 229 | + Dbest=np.zeros(self.num) |
| 230 | + Dworst=np.zeros(self.num) |
| 231 | + while i<a : |
| 232 | + while j<b : |
| 233 | + Dbest[i]+=(best[j]-weigf[j][i])**2 |
| 234 | + Dworst[i]+=(worst[j]-weigf[j][i])**2 |
| 235 | + j+=1 |
| 236 | + j=0;i+=1 |
| 237 | + i=0 |
| 238 | + Dbest=Dbest**0.5;Dworst=Dworst**0.5 |
| 239 | + print("与最优指标的距离:") |
| 240 | + print(Dbest) |
| 241 | + print("与最差指标的距离:") |
| 242 | + print(Dworst) |
| 243 | + cr=np.zeros([a,1]) |
| 244 | + while i<a : |
| 245 | + cr[i]=Dworst[i]/(Dbest[i]+Dworst[i]) |
| 246 | + i+=1 |
| 247 | + i=0 |
| 248 | + while i<a : |
| 249 | + if self.ischarging[i]==1: |
| 250 | + cr[i]=0 |
| 251 | + if self.where[i]==1: |
| 252 | + cr[i]=0 |
| 253 | + if self.leftpower[i]==1: |
| 254 | + cr[i]=0 |
| 255 | + i+=1 |
| 256 | + i=0 |
| 257 | + rank=np.zeros(a) |
| 258 | + while i<self.nengcho : |
| 259 | + lo=cr.argmax() |
| 260 | + if cr[lo]!=0: |
| 261 | + rank[lo]=i+1 |
| 262 | + cr[lo]=0 |
| 263 | + i+=1 |
| 264 | + print("优先度:") |
| 265 | + print(cr) |
| 266 | + print('topsis排序:') |
| 267 | + print(rank) |
| 268 | + i=0 |
| 269 | + if self.nengcho!=0: |
| 270 | + while i<a: |
| 271 | + if rank[i]!=0: |
| 272 | + self.ischarging[i]=1 |
| 273 | + self.totaltime+=self.waittime[i] |
| 274 | + self.waittime[i]=0 |
| 275 | + i+=1 |
| 276 | +``` |
| 277 | +可用充电桩数量计算: |
| 278 | +``` |
| 279 | + def avanum(self): |
| 280 | + t=0 |
| 281 | + t=sum(self.ischarging) |
| 282 | + self.chargingnum.append(t) |
| 283 | + self.nengcho=np.floor((1000-self.bodong)/9)-t |
| 284 | + if self.nengcho<0: |
| 285 | + self.nengcho=0 |
| 286 | + #if self.ke>21 and self.ke<24: |
| 287 | + #self.nengcho=np.round(self.ke%21) |
| 288 | + print('还能充电充电桩个数:%d'%self.nengcho) |
| 289 | + #self.nengcho=60 |
| 290 | +``` |
| 291 | +记录总负荷: |
| 292 | +``` |
| 293 | + def totload(self): |
| 294 | + charging=0;i=0 |
| 295 | + while i<self.num: |
| 296 | + if self.ischarging[i]==1: |
| 297 | + charging+=1 |
| 298 | + i+=1 |
| 299 | + load=7*charging+self.bodong |
| 300 | + self.totalload.append([load,self.bodong]) |
| 301 | +``` |
| 302 | +计算不能出行的次数: |
| 303 | +``` |
| 304 | + def cantout(self): |
| 305 | + i=0 |
| 306 | + while i<self.num: |
| 307 | + if self.offpower[i]!=0: |
| 308 | + self.off+=1 |
| 309 | + i+=1 |
| 310 | +``` |
| 311 | +计算充电金额: |
| 312 | +``` |
| 313 | + def totprice(self): |
| 314 | + prices=0;i=0 |
| 315 | + while i<self.num: |
| 316 | + if self.ischarging[i]==1: |
| 317 | + prices+=self.price[int(self.ke*4)][2]*0.25 |
| 318 | + prices+=self.sercost*0.25 #服务要不要加? |
| 319 | + i+=1 |
| 320 | + self.totalcost+=prices |
| 321 | + self.money.append(self.totalcost) |
| 322 | +``` |
| 323 | +保存数据: |
| 324 | +``` |
| 325 | + def savedata(self): |
| 326 | + np.savetxt('totalload.txt',self.totalload) |
| 327 | + np.savetxt('chargingnumber.txt',self.chargingnum) |
| 328 | + np.savetxt('totalmoney.txt',self.money) |
| 329 | + np.savetxt('totalcost.txt',[self.totalcost,self.totalcost]) #为什么保存一个数会出错?? |
| 330 | + np.savetxt('satisfaction.txt',self.satisfaction) |
| 331 | +``` |
| 332 | +主程序逻辑: |
| 333 | +``` |
| 334 | + def Run(self): |
| 335 | + #主程序逻辑 |
| 336 | + self.readimf() |
| 337 | + for i in np.linspace(1,self.day,self.day): |
| 338 | + self.riqi=int(i) |
| 339 | + self.newdaystate(self.riqi) |
| 340 | + self.cantout() |
| 341 | + self.ke=0 |
| 342 | + print('\n\n第%d天:' % int(i)) |
| 343 | + while self.ke<24: |
| 344 | + print('\n时间:第%d天 %2d:%2d\n'% (int(i),int(self.ke),int((60*self.ke)%60))) |
| 345 | + self.newstate() |
| 346 | + self.avanum() |
| 347 | +
|
| 348 | + #if self.ke<22 and self.ke>7: #是否避开峰时 |
| 349 | + if (self.ke>10 and self.ke<15) or (self.ke>18 and self.ke<21): |
| 350 | + self.ischarging=np.zeros(self.num) |
| 351 | + self.chargingnum[int(self.ke*4)]=0 |
| 352 | + self.nengcho=0 |
| 353 | + if self.nengcho>0: |
| 354 | + self.topsis() |
| 355 | + print('每个充电桩状态:') |
| 356 | + print(self.ischarging) |
| 357 | + self.totload() |
| 358 | + self.totprice() |
| 359 | + self.ke+=0.25 |
| 360 | +
|
| 361 | + ttt=self.totaltime/self.num/self.day |
| 362 | + print('总充电时间:%f'%self.totaltime) |
| 363 | + print('总充电金额:%f'%self.totalcost) |
| 364 | + print('电量耗尽总次数:%d'%self.off) |
| 365 | + print('最长等待时间:%.2f'%self.longgest) |
| 366 | + print('日期:%d,'%self.zuidari,'时间:%.2f'%self.zuidashi) |
| 367 | + print('平均等待时间:%.2f'%ttt) |
| 368 | + print('充电完成情况:') |
| 369 | + print(self.satisfaction) |
| 370 | + self.savedata() |
| 371 | +``` |
| 372 | +主函数执行模块(此处 *def* 没有缩进!!!): |
| 373 | +``` |
| 374 | +def main(): |
| 375 | + AI=AISITERO([0.25,0.25,0.5],60,0.8) |
| 376 | + AI.Run() |
| 377 | +if __name__=='__main__': |
| 378 | + main() |
| 379 | +``` |
| 380 | +仿真过程结束,获得结果数据为: |
| 381 | +- 仿真时间内每15分钟的负荷数据; |
| 382 | +- 仿真时间内每15分钟的充电数量; |
| 383 | +- 仿真时间内每15分钟的充电费用累加值; |
| 384 | +- 停车充电满意度数值。 |
0 commit comments