def run(self, Testsys=case24_ieee_rts(), BETAlimit=0.0017, ITER_max=10000, SIMUNIT=1000): Nb = Testsys["bus"].shape[0] # Load test system,Nb为节点数,Ng为发电机组数,Nl为馈线数 Ng = Testsys["gen"].shape[0] Nl = Testsys["branch"].shape[0] # Set initial value iter = 0 betavalue = float('inf') # The stopping criteria停止迭代的标准 row_index = 0 # Build matrices that have fix dimension to avoid changing size in each loop eqstatus_total = np.zeros( (ITER_max, Ng + Nl + 3)) # 建一个100000*(33+38+3)的矩阵 beta_table = np.zeros((1, ITER_max // SIMUNIT)) # "//"除法得到的才是整数 edns_table = np.zeros((1, ITER_max // SIMUNIT)) # 存放评价指标,大小为1*1000 lole_table = np.zeros((1, ITER_max // SIMUNIT)) plc_table = np.zeros((1, ITER_max // SIMUNIT)) genbus = np.nonzero((Testsys["bus"][:, PD]))[ 0] # 第三列(python中坐标是2)是节点的有功功率,表示节点有有功负荷,此处返回该列非零元素的索引,共有17个元素非零 sizegenbus = genbus.shape[0] # 有负荷的节点数量赋值给sizegenbus Testsys["load"] = sum(Testsys["bus"][:, PD]) # 系统需要的总有功功率 Testsys["gencost"] = np.tile([2, 0, 0, 3, 0, 0, 0], (Ng, 1)) # np.tile建立重复矩阵块(设置机组费用) # treat all load as negtive generator and set their parameters, then add these vitual generators to real gens # 将所有载荷视为负发电机,并设置其参数,然后将这些发电机加到实际的发电机中 loadcost = np.tile([2, 0, 0, 3, 0, 1, 0], (sizegenbus, 1)) # np.tile建立重复矩阵块(负荷的“机组费用”) Testsys["gencost"] = np.append(Testsys["gencost"], loadcost, axis=0) Index = copy.deepcopy(Testsys["gen"][0:sizegenbus, :]) # 将前17台机组的数据取出 Index[:, 0:10] = np.hstack( (Testsys["bus"][genbus, 0].reshape(-1, 1), -Testsys["bus"][genbus, 2].reshape(-1, 1), -Testsys["bus"][genbus, 3].reshape(-1, 1), np.zeros( (sizegenbus, 1)), -Testsys["bus"][genbus, 3].reshape(-1, 1), np.zeros((sizegenbus, 1)), Testsys["baseMVA"] * np.ones( (sizegenbus, 1)), np.ones((sizegenbus, 1)), np.zeros( (sizegenbus, 1)), -Testsys["bus"][genbus, 2].reshape(-1, 1))) # 负荷参数代替取出的机组数据,将负荷套入机组模型,上面矩阵取数注意与matlab相比坐标要减一 Testsys["gen"] = np.append(Testsys["gen"], Index, axis=0) del Index Testsys["bus"][genbus, 2:4] = 0 # 将原来节点中的第3、4列(有功、无功)负荷设为零 totalprob = failprob() # 引用前面定义的函数 ppopt = ppoption( PF_DC=1, VERBOSE=0, OUT_ALL=0, OPF_ALG_DC=200, OPF_FLOW_LIM=1 ) # 可以通过ppoption()采用默认变量来看里面需要什么样的输入,这个按照matlab来输入没问题吧? result = runopf(casedata=Testsys, ppopt=ppopt) while (betavalue > BETAlimit) & (iter < ITER_max): eqstatus_indi = mc_sampling( totalprob, SIMUNIT, Ng, Nl) # eqstatus为元件的状态矩阵,为1表示元件故障,为0表示原件正常 eqstatus_indi = np.hstack( (eqstatus_indi, np.ones((eqstatus_indi.shape[0], 1)), np.zeros((eqstatus_indi.shape[0], 2)))) # 在eqstatus_indi矩阵中加入三列,第一列代表状态重复次数,第二列记载切负荷量大小(没有切负荷则为零),第三列记载是否为容量不足 eqstatus_indi, ia1 = np.unique(eqstatus_indi, axis=0, return_inverse=True) # 找出抽样中的相同结果 for i in range(eqstatus_indi.shape[0]): eqstatus_indi[i, Ng + Nl] = sum(ia1 == i) # 将重复记录次数在第Ng + Nl + 1 if iter: x = 0 y = eqstatus_indi.shape[0] for i in range(y): indi_x = eqstatus_indi[x, 0:Ng + Nl] for j in range(row_index): if (indi_x == eqstatus_total[j, 0:Ng + Nl]).all(): eqstatus_total[j, Ng + Nl] = eqstatus_total[ j, Ng + Nl] + eqstatus_indi[ x, Ng + Nl] # 遇见相同的,就在eqstatus_total的计数中累加次数 eqstatus_indi = np.delete(eqstatus_indi, x, axis=0) x = x - 1 break x = x + 1 parfortemp = np.zeros((eqstatus_indi.shape[0], 2)) para = [0] * eqstatus_indi.shape[0] n_sample = [0] * eqstatus_indi.shape[0] for i in range(eqstatus_indi.shape[0]): para[i] = [0] * 5 para[i][0] = eqstatus_indi[i, 0:Ng + Nl] para[i][1] = Testsys para[i][2] = ppopt para[i][3] = Ng para[i][4] = Nl with Pool(self.n_processors) as p: load_shedding = list(p.map(mc_simulation, para)) parfortemp[:, 0] = np.asarray(load_shedding) parfortemp[:, 1] = (parfortemp[:, 0]) != 0 eqstatus_indi[:, Ng + Nl + 1:Ng + Nl + 3] = parfortemp eqstatus_total[row_index:row_index + eqstatus_indi.shape[0], :] = eqstatus_indi row_index = row_index + eqstatus_indi.shape[0] else: parfortemp = np.zeros((eqstatus_indi.shape[0], 2)) para = [0] * eqstatus_indi.shape[0] c = [0] * eqstatus_indi.shape[0] for i in range(eqstatus_indi.shape[0]): para[i] = [0] * 5 para[i][0] = eqstatus_indi[i, 0:Ng + Nl] para[i][1] = Testsys para[i][2] = ppopt para[i][3] = Ng para[i][4] = Nl with Pool(self.n_processors) as p: load_shedding = list(p.map(mc_simulation, para)) # 计算负荷短缺值 parfortemp[:, 0] = np.asarray(load_shedding) parfortemp[:, 1] = (parfortemp[:, 0]) != 0 # 记录是否负荷短缺 eqstatus_indi[:, Ng + Nl + 1:Ng + Nl + 3] = parfortemp eqstatus_total[row_index:row_index + eqstatus_indi.shape[0], :] = eqstatus_indi row_index = row_index + eqstatus_indi.shape[0] ## Update index edns = sum( eqstatus_total[0:row_index, Ng + Nl] * eqstatus_total[0:row_index, Ng + Nl + 1]) / (iter + SIMUNIT) lole = sum(eqstatus_total[0:row_index, Ng + Nl] * eqstatus_total[0:row_index, Ng + Nl + 2]) / ( iter + SIMUNIT) * 8760 plc = sum( eqstatus_total[0:row_index, Ng + Nl] * eqstatus_total[0:row_index, Ng + Nl + 2]) / (iter + SIMUNIT) betavalue = (sum(eqstatus_total[0:row_index, Ng + Nl] * (eqstatus_total[0:row_index, Ng + Nl + 1] - edns) **2))**0.5 / (iter + SIMUNIT) / edns beta_table[0, ((iter + SIMUNIT) // SIMUNIT) - 1] = betavalue edns_table[0, ((iter + SIMUNIT) // SIMUNIT) - 1] = edns lole_table[0, ((iter + SIMUNIT) // SIMUNIT) - 1] = lole plc_table[0, ((iter + SIMUNIT) // SIMUNIT) - 1] = plc iter = iter + SIMUNIT return edns
def save_recovery_result(): G0 = case24_ieee_rts() G1 = case39() G2 = case57() G3 = case118() G4 = Power_Graph.case_preprocess(case300()) G = G2 round = 5 delete_num = 15 ramp_rate = 0.3 seq_len = 5 path = 'exhaustive/case' + str(len(G['bus'])) if os.path.exists(path) == False: os.mkdir(path) file_name = path + '/case' + str(len(G['bus'])) + '_exh2' + '.txt' new_file = open(file_name, 'w') new_file.write('ramp_rate = ' + str(ramp_rate) + '\n') new_file.write('length of recovery seq ' + str(seq_len) + '\n') g = Power_Graph() g.init_by_case(G) g.set_ramp_rate(ramp_rate) delete_list = [] while len(delete_list) != delete_num: ran_num = random.randint(1, len(G['bus'])) if ran_num not in delete_list: delete_list.append(ran_num) #delete_list = [66, 289, 298, 255, 72, 87, 263, 290, 83, 167, 241, 13, 225, 243, 232, 34, 147, 269, 132, 249, 122, 2, 37, 127, 94, 199, 202, 76, 156, 67, 131, 248, 188, 238, 15, 84, 44, 8, 220, 189, 206, 162, 169, 107, 17, 282, 164, 198, 115, 261] #delete_list = [44, 54, 11, 3, 6, 28, 2, 15, 30, 9] new_file.write('delete length ' + str(len(delete_list)) + '\n') new_file.write('delete list ' + str(delete_list) + '\n') for item in delete_list: g.delete_bus(item) cf = Power_Failure(g) for item in delete_list: cf.failed_bus_id.append(item) cf.failure_process() new_file.write('num of failed bus ' + str(len(cf.failed_bus_id)) + '\n') new_file.write('failed bus ' + str(cf.failed_bus_id) + '\n') steady_bus_num = 0 steady_branch_num = 0 for graph in cf.steady_list: steady_bus_num += len(graph.bus_id) steady_branch_num += len(graph.branch) new_file.write('num of steady bus ' + str(steady_bus_num) + '\n') new_file.write('num of steady branch ' + str(steady_branch_num) + '\n\n') ini_g = Power_Graph() ini_g.init_by_case(G) gr = Grid_Recovery(cf.steady_list, ini_g) candidate_num = len(gr.connect_bus_list(cf.steady_list)) new_file.write('num of failed bus which can be recovered ' + str(candidate_num) + '\n') ini_residual_per = gr.cal_residual_power() new_file.write('residual power before recovery ' + str(ini_residual_per) + '\n\n') R_srg = Recovery_SAG.Recovery_SAG(cf.steady_list, ini_g) R_srg.initialize_param(44, 16, round) candidate_P_set = R_srg.cal_candidate_set() sorted_list = sorted(candidate_P_set.items(), key=lambda item: item[1], reverse=True) new_file.write('candidate P set ' + '\n') for item in sorted_list: new_file.write(str(item[0]) + ' ' + str(item[1]) + '\n') new_file.write('\n') R_ex = Recovery_exhaustive(cf.steady_list, ini_g) for num in range(1, seq_len + 1): seq_dic = R_ex.recovery_exhaustive(num) sorted_list = sorted(seq_dic.items(), key=lambda item: item[1], reverse=True) new_file.write('exhaustive search recovery sequence length: ' + str(num) + '\n') for item in sorted_list: new_file.write(str(item[0]) + ' ' + str(item[1]) + '\n') new_file.write('\n') new_file.close()
seq.append(item) if len(seq) == num: break print 'random based recovery seq', seq return self.recover_with_sequence(seq), seq if __name__ == '__main__': G = case24_ieee_rts() #G = case118() g = Power_Graph() g.init_by_case(G) g.set_ramp_rate(0.3) g.draw_P_graph() print 'draw initial graph' #g.delete_branch(24, 70) g.delete_branch(2, 4) cf = Power_Failure(g) cf.failure_process() for graph in cf.steady_list: print 'steady graph', graph.bus_id cf.draw_graph() print 'draw steady graph before recovery'
def test_case24(): net = from_ppc(c24.case24_ieee_rts()) pp.runopp(net) assert net.OPF_converged
def mc_simulation(eqstatus, Testsys, ppopt, Ng, Nl): statusgen = eqstatus[0:Ng] Testsys["gen"][0:Ng, 8] = 1 - statusgen statusbranch = eqstatus[Ng:Ng + Nl] Testsys["branch"][0:Nl, 10] = 1 - statusbranch Result = runopf(casedata=Testsys, ppopt=ppopt) dns = Result["f"] + Testsys["load"] if dns < 0.1: dns = 0 return dns Testsys = case24_ieee_rts() # Load test system,Nb为节点数,Ng为发电机组数,Nl为馈线数 Nb = Testsys["bus"].shape[0] Ng = Testsys["gen"].shape[0] Nl = Testsys["branch"].shape[0] # Set initial value BETAlimit = 0.0017 ITER_max = 100000 SIMUNIT = 100 iter = 0 lole = 0 edns = 0 betavalue = float('inf') row_index = 0 # Build matrices that have fix dimension to avoid changing size in each loop eqstatus_total = np.zeros((ITER_max, Ng + Nl + 3))
def save_recovery_result_2(): G0 = case24_ieee_rts() G1 = case39() G2 = case57() G3 = case118() G4 = Power_Graph.case_preprocess(case300()) G_list = [G0, G1, G2, G3, G4] G = G4 P = 30 R = 16 round = 9 delete_num = 15 #iter_times = 11 ramp_rate = 0.3 seq_len = 9 random_rep_num = 50 ramp_arr = np.arange(0.1, 1.1, 0.1) P_arr = np.arange(10, 32, 2) R_arr = np.arange(2, 32, 2) for p in P_arr: path = 'recovery_result4/case' + str(len(G['bus'])) + '_0.3' if os.path.exists(path) == False: os.mkdir(path) file_name = path + '/case' + str(len( G['bus'])) + '_setup_' + str(p) + '.txt' new_file = open(file_name, 'w') new_file.write('ramp_rate = ' + str(ramp_rate) + '\n') new_file.write('P=' + str(p) + ' , ' + 'R=' + str(R) + ' , ' + 'round=' + str(round) + '\n') new_file.write('length of recovery seq ' + str(seq_len) + '\n') g = Power_Graph() g.init_by_case(G) g.set_ramp_rate(ramp_rate) delete_list = [] while len(delete_list) != delete_num: ran_num = random.randint(1, len(G['bus'])) if ran_num not in delete_list: delete_list.append(ran_num) delete_list = [ 66, 289, 298, 255, 72, 87, 263, 290, 83, 167, 241, 13, 225, 243, 232, 34, 147, 269, 132, 249, 122, 2, 37, 127, 94, 199, 202, 76, 156, 67, 131, 248, 188, 238, 15, 84, 44, 8, 220, 189, 206, 162, 169, 107, 17, 282, 164, 198, 115, 261 ] #delete_list=[192, 27, 15, 153, 198, 189, 171, 33, 256, 265, 25, 218, 284, 6, 261, 155, 131, 260, 97, 93, 55, 95, 124, 69, 37, 34, 94, 201, 12, 144, 1, 254, 193, 83, 59, 230, 289, 9, 200, 264, 277, 246, 143, 179, 100, 232, 233, 91, 151, 170] #delete_list=[105, 49, 69, 110, 28, 62, 31, 41, 96, 15, 108, 67, 63, 115, 79, 101, 83, 76, 61, 75, 45, 12, 32, 113, 98, 111, 91, 95, 68, 9] #delete_list = [74, 45, 51, 1, 106, 3, 82, 67, 90, 114, 81, 30, 7, 17, 79, 103, 95, 46, 115, 118, 40, 117, 96, 116, 88, 27, 57, 110, 28, 21] #delete_list=[25, 17, 8, 32, 37, 24, 9, 28, 47, 15] #delete_list = [37, 18, 31, 20, 1, 35, 15, 57, 54, 2, 17, 6, 51, 3, 55] new_file.write('delete length ' + str(len(delete_list)) + '\n') new_file.write('delete list ' + str(delete_list) + '\n') for item in delete_list: g.delete_bus(item) cf = Power_Failure(g) for item in delete_list: cf.failed_bus_id.append(item) cf.failure_process() new_file.write('num of failed bus ' + str(len(cf.failed_bus_id)) + '\n') new_file.write('failed bus ' + str(cf.failed_bus_id) + '\n') steady_bus_num = 0 steady_branch_num = 0 for graph in cf.steady_list: steady_bus_num += len(graph.bus_id) steady_branch_num += len(graph.branch) new_file.write('num of steady bus ' + str(steady_bus_num) + '\n') new_file.write('num of steady branch ' + str(steady_branch_num) + '\n\n') ini_g = Power_Graph() ini_g.init_by_case(G) R_SAG = Recovery_SAG(cf.steady_list, ini_g) R_SAG.initialize_param(p, R, round) candidate_set = R_SAG.cal_candidate_set() RRC_set = R_SAG.cal_RRC_set() RRC_seq = {} RRC_residual_per = {} for i in range(1, seq_len + 1): RRC_residual_per[i] = 0.0 for item in RRC_set.items(): # print item new_file.write(str(item[0]) + '\n') current_set = item[1] sorted_list = sorted(current_set.items(), key=lambda item: item[1], reverse=True) for k, v in sorted_list: new_file.write(str(k) + ' ' + str(v) + '\n') if v > RRC_residual_per[len(k)]: RRC_seq[len(k)] = k RRC_residual_per[len(k)] = v new_file.write('\n') R_SAG.construct_SAG() new_file.write('node num of SRG ' + str(len(R_SAG.SAG.node_list)) + '\n\n') for current in range(2, seq_len + 1): SAG_seq = R_SAG.cal_SAG_recovery_seq_2(current) steady_list = copy.deepcopy(cf.steady_list) gr = Grid_Recovery(steady_list, ini_g) ini_residual_per = gr.cal_residual_power() SRG_residual_per = gr.recover_with_sequence(SAG_seq) steady_list = copy.deepcopy(cf.steady_list) gr = Grid_Recovery(steady_list, ini_g) degree_residual_per, degree_seq = gr.recovery_degree_2(current) steady_list = copy.deepcopy(cf.steady_list) gr = Grid_Recovery(steady_list, ini_g) low_degree_residual_per, low_degree_seq = gr.recovery_low_degree_2( current) steady_list = copy.deepcopy(cf.steady_list) gr = Grid_Recovery(steady_list, ini_g) load_residual_per, load_seq = gr.recovery_load_2(current) steady_list = copy.deepcopy(cf.steady_list) gr = Grid_Recovery(steady_list, ini_g) low_load_residual_per, low_load_seq = gr.recovery_low_load_2( current) sum = 0.0 for i in range(0, random_rep_num): steady_list = copy.deepcopy(cf.steady_list) gr = Grid_Recovery(steady_list, ini_g) residual_per, seq = gr.recovery_random_2(current) sum += residual_per aver_residual_per = sum / random_rep_num new_file.write('current length of seq: ' + str(current) + '\n') new_file.write('SRG recovery seq ' + str(SAG_seq) + '\n') new_file.write('RRC recovery seq ' + str(RRC_seq[current]) + '\n') new_file.write('high degree based recovery seq ' + str(degree_seq) + '\n') new_file.write('low degree based recovery seq ' + str(low_degree_seq) + '\n') new_file.write('high load based recovery seq ' + str(load_seq) + '\n') new_file.write('low load based recovery seq ' + str(low_load_seq) + '\n') new_file.write('\n') new_file.write('residual percent of power before recovery ' + str(ini_residual_per) + '\n') new_file.write('residual percent of power after SRG recovery ' + str(SRG_residual_per) + '\n') new_file.write('residual percent of power after RRC recovery ' + str(RRC_residual_per[current]) + '\n') new_file.write( 'residual percent of power after high degree based recovery ' + str(degree_residual_per) + '\n') new_file.write( 'residual percent of power after low degree based recovery ' + str(low_degree_residual_per) + '\n') new_file.write( 'residual percent of power after high load based recovery ' + str(load_residual_per) + '\n') new_file.write( 'residual percent of power after low load based recovery ' + str(low_load_residual_per) + '\n') new_file.write( 'average residual percent of power after random based recovery ' + str(aver_residual_per) + '\n') new_file.write('\n\n') new_file.close()