Пример #1
0
 def load_scenario_data(self, raw_file, dyr_file):
     from stepspy import STEPS
     self.simulator = STEPS(is_default=False,
                            log_file='.\\simulation\\log_op.txt')
     self.simulator.load_powerflow_data(raw_file, 'PSS/E')
     self.simulator.load_dynamic_data(dyr_file, 'PSS/E')
     self.simulator.solve_powerflow('PQ')
     self.__loads_p = np.zeros(len(self.loads_shedding))  # 该方式下的负荷量
     for i in range(len(self.loads_shedding)):
         self.__loads_p[i] = self.simulator.get_load_data(
             self.loads_shedding[i], 'F', 'PP0_MW')
     return
Пример #2
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.main_table = QTabWidget()
        self.setCentralWidget(self.main_table)
        self.setWindowTitle('电力系统紧急切负荷智能优化软件')
        self.setWindowIcon(QIcon('.\\data\\safety.png'))
        self.main_table.setStyleSheet('background-color: grey')
        self.main_table.setTabPosition(QTabWidget.South)

        self.simulator = STEPS(is_default=False,
                               log_file='.\\simulation\\log_init.txt')

        self.init_window_menu()
        self.window_output()
Пример #3
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.main_table = QTabWidget()
        self.setCentralWidget(self.main_table)
        self.setWindowTitle('电力系统紧急切负荷智能优化软件')
        self.setWindowIcon(QIcon('.\\data\\safety.png'))
        self.main_table.setStyleSheet('background-color: grey')
        self.main_table.setTabPosition(QTabWidget.South)

        self.simulator = STEPS(is_default=False,
                               log_file='.\\simulation\\log_init.txt')

        self.init_window_menu()
        self.window_output()

    def init_window_menu(self):
        bar = self.menuBar()

        basic_parameter = bar.addMenu('基础设置')
        basic_parameter.addAction('电网模型')
        basic_parameter.addAction('导入切负荷站')
        basic_parameter.addAction('保存切负荷站')
        basic_parameter.addAction('导入直流闭锁')
        basic_parameter.addAction('保存直流闭锁')
        basic_parameter.addAction('安全约束')
        basic_parameter.triggered[QAction].connect(self.set_basic_parameter)

        basic_model_training = bar.addMenu('基础模型训练')
        basic_model_training.addAction('样本生成')
        basic_model_training.addAction('模型训练')
        basic_model_training.triggered[QAction].connect(self.train_basic_model)

        model_update = bar.addMenu('模型更新')
        model_update.addAction('样本生成')
        model_update.addAction('模型微调')
        model_update.triggered[QAction].connect(self.update_model)

        optimizer = bar.addMenu('优化计算')
        optimizer.addAction('单方案优化')
        optimizer.addAction('多方案优化')
        optimizer.triggered[QAction].connect(self.start_scenraio_optimizer)

        setting = bar.addMenu('帮助')
        setting.addAction('版权信息')
        setting.addAction('优化计算说明')

    def window_output(self):
        items = QDockWidget('输出', self)
        self.text_output = QTextBrowser()
        items.setWidget(self.text_output)
        items.setFloating(False)
        items.setFeatures(items.NoDockWidgetFeatures)
        self.addDockWidget(Qt.BottomDockWidgetArea, items)

        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)

    def set_basic_parameter(self, q):
        if q.text() == '电网模型':
            openfile_name = QFileDialog.getOpenFileName(
                self, '选择电网模型', '', 'file(*.raw)')
            if len(openfile_name[0]) == 0:
                return
            path_raw_file = openfile_name[0]
            if len(path_raw_file) == 0:
                return
            self.path_raw_file = path_raw_file
            self.simulator.load_powerflow_data(path_raw_file, 'PSS/E')
            self.text_output.append('加载电网模型: ' + path_raw_file)
            self.display_network_data()

        elif q.text() == '导入切负荷站':
            try:
                object.__getattribute__(self, 'scenario_table')
            except:
                dialog = QMessageBox(QMessageBox.Warning, '警告', '未导入电网运行文件!!!')
                dialog.exec_()
                return

            openfile_name = QFileDialog.getOpenFileName(
                self, '导入切负荷站设置', '', 'file(*.csv)')
            if len(openfile_name[0]) == 0:
                return
            path_name = openfile_name[0]
            if len(path_name) == 0:
                return
            self.scenario_table.set_loads_shedding_location(path_name)
            self.text_output.append('导入切负荷站设置: ' + path_name)

        elif q.text() == '保存切负荷站':
            try:
                object.__getattribute__(self, 'scenario_table')
            except:
                dialog = QMessageBox(QMessageBox.Warning, '警告', '未导入电网运行文件!!!')
                dialog.exec_()
                return

            self.scenario_table.save_loads_shedding_location(
                '.\\data\\loads_shedding.csv')
            self.text_output.append('保存切负荷站设置: ' +
                                    '.\\data\\loads_shedding.csv')
            return

        elif q.text() == '导入直流闭锁':
            try:
                object.__getattribute__(self, 'scenario_table')
            except:
                dialog = QMessageBox(QMessageBox.Warning, '警告', '未导入电网运行文件!!!')
                dialog.exec_()
                return

            openfile_name = QFileDialog.getOpenFileName(
                self, '导入直流闭锁设置', '', 'file(*.csv)')
            if len(openfile_name[0]) == 0:
                return
            path_name = openfile_name[0]
            if len(path_name) == 0:
                return
            self.scenario_table.set_block_hvdc_location(path_name)
            self.text_output.append('导入闭锁直流设置: ' + path_name)

        elif q.text() == '保存直流闭锁':
            try:
                object.__getattribute__(self, 'scenario_table')
            except:
                dialog = QMessageBox(QMessageBox.Warning, '警告', '未导入电网运行文件!!!')
                dialog.exec_()
                return
            self.scenario_table.save_hvdc_blocking_location(
                '.\\data\\hvdc_block.csv')
            self.text_output.append('保存闭锁直流设置: ' + '.\\data\\hvdc_block.csv')

        elif q.text() == '安全约束':
            try:
                object.__getattribute__(self, 'scenario_table')
            except:
                dialog = QMessageBox(QMessageBox.Warning, '警告', '未导入电网运行文件!!!')
                dialog.exec_()
                return

            dialog = SecurityConstraint(self.text_output)
            dialog.exec_()
        else:
            pass
        return

    def train_basic_model(self, q):
        if q.text() == '样本生成':
            dialog = UI_SGBM()
            dialog.exec_()

        elif q.text() == '模型训练':
            dialog = UI_DBNBM()
            dialog.exec_()

        else:
            return

    def update_model(self, q):
        if q.text() == '样本生成':
            dialog = UI_SGTL()
            dialog.exec_()
        elif q.text() == '模型微调':
            dialog = UI_DBNTL()
            dialog.exec_()
        else:
            return

    def start_scenraio_optimizer(self, q):
        if q.text() == '单方案优化':
            self.text_output.append('启动单方案优化程序')
            dialog = UI_AAMO()
            dialog.exec_()
        elif q.text() == '多方案优化':
            self.text_output.append('启动多方案优化程序')
            dialog = UI_AAMOTL()
            dialog.exec_()
        else:
            return

    def display_network_data(self):
        self.main_table.setStyleSheet('background-color: white')
        self.scenario_table = Table_Show(self.main_table, self.simulator,
                                         self.text_output)
        self.scenario_table.display_bus_table()
        self.scenario_table.display_generator_table()
        self.scenario_table.display_load_table()
        self.scenario_table.display_hvdc_table()
Пример #4
0
# this case in section 2.10 of Power System Control and Stability by P.M. Anderson
# April 1, 2021
# Changgang Li
from stepspy import STEPS  # import modules

simulator = STEPS(
    is_default=True, log_file="ieee9_pf.log"
)  # create simulator, use default simulator, and redirect logs to file ieee9.log
simulator.set_allowed_maximum_bus_number(
    10000
)  # set allowed maximum bus number, no bus with bus number greater than this number is allowed

simulator.load_powerflow_data('../ieee9.raw', 'PSS/E')  # load powerflow data
simulator.set_powerflow_solver_parameter('b', 'FLAT START Logic',
                                         True)  # enable flat start logic
simulator.set_powerflow_solver_parameter(
    'b', 'NON DIVERGENT SOLUTION LOGIC',
    False)  # enable non-divergent solution
simulator.set_powerflow_solver_parameter(
    'd', 'MAX ACTIVE POWER IMBALANCE IN MW',
    0.001)  # maximum active power mismatch
simulator.set_powerflow_solver_parameter(
    'd', 'MAX REACTIVE POWER IMBALANCE IN MVAR',
    0.001)  # maximum reactive power mismatch
simulator.solve_powerflow('NR')  # solve with Newton-Raphson method
simulator.save_extended_powerflow_result(
    "ieee9_pf.csv")  # show powerflow result
Пример #5
0
# this case in section 2.10 of Power System Control and Stability by P.M. Anderson
# April 1, 2021
# Changgang Li
from stepspy import STEPS # import modules

simulator = STEPS(is_default=True, log_file="ieee9.log") # create simulator, use default simulator, and redirect logs to file ieee9.log
simulator.set_allowed_maximum_bus_number(10000) # set allowed maximum bus number, no bus with bus number greater than this number is allowed

simulator.load_powerflow_data('../IEEE9.raw','PSS/E') # load powerflow data
simulator.set_powerflow_solver_parameter('b','FLAT START Logic', True) # enable flat start logic
simulator.set_powerflow_solver_parameter('i','MAX ITERATION', 50) # set up maximum iteration
simulator.set_powerflow_solver_parameter('b','EXPORT JACOBIAN LOGIC', False) # disable exporting Jacobian matrix
simulator.set_powerflow_solver_parameter('b','NON DIVERGENT SOLUTION LOGIC', True) # enable non-divergent solution
simulator.set_powerflow_solver_parameter('d','MAX VOLTAGE CHANGE IN PU', 0.3) # set up maximum voltage change in each iteration
simulator.set_powerflow_solver_parameter('d','MAX ANGLE CHANGE IN DEG', 60.0) # set up maximum angle change in each iteration
simulator.set_powerflow_solver_parameter('d','MAX ACTIVE POWER IMBALANCE IN MW', 0.001) # maximum active power mismatch
simulator.set_powerflow_solver_parameter('d','MAX REACTIVE POWER IMBALANCE IN MVAR', 0.001) # maximum reactive power mismatch
simulator.solve_powerflow('NR') # solve with Newton-Raphson method
simulator.show_powerflow_result() # show powerflow result
simulator.save_network_Y_matrix("y.csv",export_full=True) # export Y matrix, both sparse and full version

simulator.set_dynamic_model_database_capacity(1000000) # set dynamic model database capacity, in bytes
simulator.load_dynamic_data('../IEEE9_PM.dyr','PSS/E') # load dynamic data

buses = simulator.get_all_buses() # get all buses
gens = simulator.get_all_generators() # get all generators

for bus in buses: # prepare bus voltage and frequency meter for all buses
    simulator.prepare_bus_meter(bus, "voltage in pu")
    simulator.prepare_bus_meter(bus, "frequency in Hz")
for gen in gens: # prepare rotor angle meter for all generators
Пример #6
0
from stepspy import STEPS, POUCH_CSV

simulator = STEPS(is_default=False, log_file='test.log')
simulator.info()

simulator.set_toolkit_log_file("newtest.log", log_file_append_mode=False)

simulator.set_parallel_thread_number(1)

simulator.set_dynamic_model_database_capacity(10000000)

max_bus = simulator.get_allowed_maximum_bus_number()
info = "The default maximum bus number is: " + str(max_bus)
print(info)
simulator.set_allowed_maximum_bus_number(10000)
max_bus = simulator.get_allowed_maximum_bus_number()
info = "The default maximum bus number is changed to: " + str(max_bus)
print(info)

simulator.load_powerflow_data('IEEE39.raw', 'PSS/E')
simulator.check_powerflow_data()
simulator.check_network_connectivity()

simulator.build_dynamic_network_Y_matrix()
simulator.save_dynamic_network_Y_matrix('ymatrix_dyn.csv')

simulator.build_network_Z_matrix()
simulator.save_network_Z_matrix('zmatrix_dyn.csv')

nbus = simulator.get_bus_count()
print(nbus)
Пример #7
0
#coding = utf-8
'''
Here is a demo of showing how to slove powerflow with stepspy.
Changgang Li, 2019/08/25
'''

from stepspy import STEPS  # import the class 'STEPS'

simulator = STEPS(is_default=True)  # create a STEPS simulator instance
simulator.info()

powerflow_data_file = 'IEEE9.raw'  # file name of powerflow data. Use absolute path if necessary
powerflow_data_type = 'PSS/E'  # powerflow data type. Currently, use 'PSS/E' only

simulator.load_powerflow_data(
    powerflow_data_file,
    powerflow_data_type)  # load powerflow data into the simulator

data_type = 'D'  # if you want to set or get doubule data, set data_type as 'F' or 'D'.
data_name = 'MAX ACTIVE POWER IMBALANCE IN MW'  # the data name in the powerflow solver of the simulator
# the data_type and data_name should be consistent. make sure the data_type is correct.
# If the data is double, use 'F' or 'D'. If the data is integer, use 'I'. If the data is boolean, use 'B'. If the data is string, use 'S'
'''
(1) when data_type is 'D' or 'F' you can set/get the following data
 'MAX ACTIVE POWER IMBALANCE IN MW': maximum allowed active power mismatch at each bus, in MW. This is the powerflow convergence threshold of P equations.
 'MAX REACTIVE POWER IMBALANCE IN MVAR': maximum allowed reactive power mismatch at each bus, in MVar. This is the powerflow convergence threshold of Q equations.
 'ITERATION ACCELERATOR': acceleration factor for iteration. by default it is 1.0. if >1.0, then the powerflow solver is accelerated. if <1.0, the powerflow solver is decellerated.
 
 (2) when data_type is 'I', you can set/get the following data
 'MAX ITERATION': maximum iteration count allowed for solving powerflow. If set as 1, you can get the solution step by step.
 
Пример #8
0
    def generate_load_shedding_sample(self, simulation_pars):
        from stepspy import STEPS
        sample_num = simulation_pars['sample_num']
        shedding_percent = simulation_pars['shedding_percent']

        simulator = STEPS(
            is_default=False,
            log_file='.\simulation\log_{}.txt'.format(sample_num))
        simulator.load_powerflow_data(self.raw_file, 'PSS/E')
        simulator.load_dynamic_data(self.dyr_file, 'PSS/E')
        simulator.solve_powerflow('PQ')

        buses = simulator.get_all_buses()
        for bus in buses:
            AREA = simulator.get_bus_data(bus, 'I', 'AREA')
            if AREA == 37:
                simulator.prepare_bus_meter(bus, 'FREQUENCY IN HZ')

        simulator.set_dynamic_simulation_time_step(0.002)
        simulator.set_dynamic_simulator_output_file(
            '.\\simulation\\sample_{}'.format(sample_num))
        simulator.start_dynamic_simulation()
        simulator.run_dynamic_simulation_to_time(0.5)

        for hvdc in self.hvdc_block:
            simulator.manually_block_hvdc(hvdc)
            simulator.trip_fixed_shunt((hvdc[1], '1'))

        simulator.run_dynamic_simulation_to_time(0.6)
        for i in range(len(self.loads_shedding)):
            simulator.scale_load(self.loads_shedding[i],
                                 -1 * shedding_percent[i])

        simulator.run_dynamic_simulation_to_time(5.0)
        simulator.stop_dynamic_simulation()

        min_frequency = self.get_min_frequency(
            '.\\simulation\\sample_{}.csv'.format(sample_num))
        if min_frequency > self.min_frequency:
            return [sample_num, min_frequency, 1]
        else:
            return [sample_num, min_frequency, 0]
from stepspy import STEPS  # import modules
from stepspy import POUCH_CSV  # import modules
import matplotlib.pyplot as plt

simulator = STEPS(
    is_default=True, log_file="ieee9.log"
)  # create simulator, use default simulator, and redirect logs to file ieee9.log
simulator.set_allowed_maximum_bus_number(
    10000
)  # set allowed maximum bus number, no bus with bus number greater than this number is allowed

simulator.load_powerflow_data('../IEEE9.raw', 'PSS/E')  # load powerflow data
simulator.solve_powerflow('NR')  # solve with Newton-Raphson method
simulator.show_powerflow_result()  # show powerflow result

simulator.set_dynamic_model_database_capacity(
    1000000)  # set dynamic model database capacity, in bytes
simulator.load_dynamic_data('../IEEE9_detail.dyr',
                            'PSS/E')  # load dynamic data

buses = simulator.get_all_buses()  # get all buses
gens = simulator.get_all_generators()  # get all generators

for bus in buses:  # prepare bus voltage meter for all buses
    simulator.prepare_bus_meter(bus, "voltage in pu")
for bus in buses:  # prepare bus frequency meter for all buses
    simulator.prepare_bus_meter(bus, "frequency in Hz")
for gen in gens:  # prepare rotor angle meter for all generators
    simulator.prepare_generator_meter(gen, "rotor angle in deg")
for gen in gens:  # prepare rotor speed deviation meter for all generators
    simulator.prepare_generator_meter(gen, "rotor speed deviation in pu")
Пример #10
0
class ADELSMTL():  # 代理辅助模型驱动的差分进化切负荷模型
    def __init__(self, size=50, iter_num=200, F=0.8, CR=0.4):
        self.__size = size
        self.__iter_num = iter_num
        self.__F = F
        self.__CR = CR

    # 以下为加载代理辅助模型,目前只有频率模型
    def load_frequency_classification_prediction_model(self, file):
        K.clear_session()
        self.frequency_classification_model = load_model(file)

    # 以下为加载运行场景
    def load_scenario_data(self, raw_file, dyr_file):
        from stepspy import STEPS
        self.simulator = STEPS(is_default=False,
                               log_file='.\simulation\log.txt')
        self.simulator.load_powerflow_data(raw_file, 'PSS/E')
        self.simulator.load_dynamic_data(dyr_file, 'PSS/E')
        self.simulator.solve_powerflow('PQ')

        self.__dim = len(self.loads_shedding)  # 个体特征维数

        self.__loads_p = np.zeros(len(self.loads_shedding))  # 该方式下的负荷量
        for i in range(len(self.loads_shedding)):
            self.__loads_p[i] = self.simulator.get_load_data(
                self.loads_shedding[i], 'F', 'PP0_MW')

    def set_load_shedding_location(self, path_name):
        data = pd.read_csv(path_name, header=0, engine='python')
        loads_shedding = data['负荷'].values.tolist()
        for i in range(len(loads_shedding)):
            loads_shedding[i] = eval(loads_shedding[i])

        self.max_percent = data['最大切除比例'].values.tolist()
        self.loads_shedding = loads_shedding
        self.__dim = len(self.loads_shedding)  # 个体特征维数
        self.x_min = np.zeros(self.__dim)
        self.x_max = np.array(self.max_percent)

    #以下为种群初始化
    def initialize_population(self):
        self.population = np.zeros((self.__size, self.__dim))
        for i in range(self.__dim):
            for j in range(self.__size):  # 初始种群在限度范围内随机初始化
                self.population[j, i] = random.uniform(self.x_min[i],
                                                       self.x_max[i])

        self.population_fitness = np.zeros(self.__size)
        for i in range(self.__size):
            self.population_fitness[i] = self.get_individual_fitness(
                self.population[i, :])

    def correct_F(self, current):
        lanba = math.exp(1 - self.__iter_num / (self.__iter_num + 1 - current))
        F = 1.0 * 2**lanba
        return F

    def correct_CR(self):
        CR = 0.5 * (1 + random.random())
        return CR

    # 以下为进化过程
    def operate_evolution(self):
        '''实施进化计算'''
        k = 0
        while True:
            F = self.correct_F(k)
            mutation_population = self.operate_population_mutation(F)

            process_population = self.operate_population_crossover(
                mutation_population)

            self.operate_selection(process_population)

            for j in range(self.__size):
                self.population_fitness[j] = self.get_individual_fitness(
                    self.population[j, :])
            mean_fitness = np.mean(self.population_fitness)
            max_fitness = np.max(self.population_fitness)
            min_fitness = np.min(self.population_fitness)

            min_fit_index = np.argmin(self.population_fitness)
            best_ind = self.population[min_fit_index, :]

            k = k + 1
            if k > self.__iter_num:
                break

        for i in range(self.__size):
            self.population_fitness[i] = self.get_individual_fitness(
                self.population[i, :])

        min_index = np.argmin(self.population_fitness)
        self.best_individual = self.population[min_index, :]
        return

    def operate_population_mutation(self, F):
        '''对种群实施变异'''
        self.__F = F
        mutation_population = np.zeros((self.__size, self.__dim))
        for i in range(self.__size):
            list_num = list(range(0, self.__size, 1))
            list_num.remove(i)
            res = random.sample(list_num, 3)
            mutation_individual = self.population[res[0], :] + self.__F * (
                self.population[res[1], :] - self.population[res[2], :]
            )  # 变异操作,产生新个体

            for j in range(self.__dim):  # 特征越限处理
                if mutation_individual[j] < self.x_min[
                        j] or mutation_individual[j] > self.x_max[j]:
                    mutation_individual = self.x_min + random.random() * (
                        self.x_max - self.x_min)
                    break

            mutation_population[i, :] = mutation_individual
        return mutation_population

    def operate_population_crossover(self, mutation_population):
        '''进行交叉操作'''
        self.__CR = self.correct_CR()
        process_population = np.zeros((self.__size, self.__dim))
        for i in range(self.__size):
            randn = random.randint(0, self.__dim)
            for j in range(self.__dim):
                rand_float = random.random()
                if rand_float <= self.__CR or randn == j:
                    process_population[i, j] = mutation_population[i, j]
                else:
                    process_population[i, j] = self.population[i, j]
        return process_population

    def operate_selection(self, process_population):
        '''对个体进行选择和更新'''
        for i in range(self.__size):
            ind_1 = self.population[i, :]
            ind_2 = process_population[i, :]
            better_ind = self.select_individual_cla(ind_1, ind_2)
            self.population[i, :] = better_ind
        return

    def select_individual_cla(self, ind_1, ind_2):
        ind_1_cla = self.frequency_classification_model.predict_classes(
            5 * ind_1.reshape((1, -1)))
        ind_1_cla = ind_1_cla[0, 0]
        ind_2_cla = self.frequency_classification_model.predict_classes(
            5 * ind_2.reshape((1, -1)))
        ind_2_cla = ind_2_cla[0, 0]

        if ind_1_cla == 1 and ind_2_cla == 1:
            fit_1 = self.get_individual_fitness(ind_1)
            fit_2 = self.get_individual_fitness(ind_2)
            if fit_1 > fit_2:
                better_ind = ind_2
            else:
                better_ind = ind_1
        elif ind_1_cla == 0 and ind_2_cla == 1:
            better_ind = ind_2

        elif ind_1_cla == 0 and ind_2_cla == 0:
            better_ind = np.zeros(self.__dim)
            for i in range(self.__dim):
                better_ind[i] = random.uniform(self.x_min[i], self.x_max[i])
        else:
            better_ind = ind_1
        return better_ind

    # 以下为个体适应度计算函数
    def get_individual_fitness(self, individual):  # individual应该是个一维数组
        value = np.sum(individual * self.__loads_p)  # 切负荷总量
        return value

    def get_best_individual(self):
        min_shedding_power = self.get_individual_fitness(self.best_individual)
        return self.best_individual, min_shedding_power
Пример #11
0
class ADELSM():  # 代理辅助模型驱动的差分进化切负荷模型
    def __init__(self, size=100, iter_num=200):
        self.__size = size
        self.__iter_num = iter_num
        self.__F = 0.8
        self.__CR = 0.4

        self.__process = []

    def set_load_shedding_location(self, path_name):
        data = pd.read_csv(path_name, header=0, engine='python')
        loads_shedding = data['负荷'].values.tolist()
        for i in range(len(loads_shedding)):
            loads_shedding[i] = eval(loads_shedding[i])

        self.max_percent = data['最大切除比例'].values.tolist()
        self.loads_shedding = loads_shedding
        self.__dim = len(self.loads_shedding)  # 个体特征维数
        self.x_min = np.zeros(self.__dim)
        self.x_max = np.array(self.max_percent)

    def set_blocking_hvdc_location(self, path_name):
        data = pd.read_csv(path_name, header=0, engine='python')
        data = data['直流'].values.tolist()
        for i in range(len(data)):
            data[i] = eval(data[i])
        self.hvdc_block = data

    # 以下为加载代理辅助模型,目前只有频率模型
    def load_frequency_classification_prediction_model(self, file):
        K.clear_session()
        self.frequency_classification_model = load_model(file)

    # 以下为加载运行场景
    def load_scenario_data(self, raw_file, dyr_file):
        from stepspy import STEPS
        self.simulator = STEPS(is_default=False,
                               log_file='.\\simulation\\log_op.txt')
        self.simulator.load_powerflow_data(raw_file, 'PSS/E')
        self.simulator.load_dynamic_data(dyr_file, 'PSS/E')
        self.simulator.solve_powerflow('PQ')
        self.__loads_p = np.zeros(len(self.loads_shedding))  # 该方式下的负荷量
        for i in range(len(self.loads_shedding)):
            self.__loads_p[i] = self.simulator.get_load_data(
                self.loads_shedding[i], 'F', 'PP0_MW')
        return

    # 以下为设置差分进化算法的参数
    def set_evolution_parameter(self, par_name, value):
        if par_name == '交叉因子':
            self.__CR = value

        elif par_name == '变异因子':
            self.__F = value
        else:
            pass

    #以下为种群初始化
    def initialize_population(self):
        self.population = np.zeros((self.__size, self.__dim))
        for i in range(self.__dim):
            for j in range(self.__size):  # 初始种群在限度范围内随机初始化
                self.population[j, i] = random.uniform(self.x_min[i],
                                                       self.x_max[i])

        self.population_fitness = np.zeros(self.__size)
        for i in range(self.__size):
            self.population_fitness[i] = self.get_individual_fitness(
                self.population[i, :])

    # 以下为进化过程
    def operate_evolution(self):
        '''实施进化计算'''
        k = 0
        while True:
            mutation_population = self.operate_population_mutation()
            process_population = self.operate_population_crossover(
                mutation_population)
            self.operate_selection(process_population)
            for j in range(self.__size):
                self.population_fitness[j] = self.get_individual_fitness(
                    self.population[j, :])
            mean_fitness = np.mean(self.population_fitness)
            max_fitness = np.max(self.population_fitness)
            min_fitness = np.min(self.population_fitness)

            self.process_output.append('第{}代-平均值{}-最大值{}-最小值{}'.format(
                k, int(mean_fitness), int(max_fitness), int(min_fitness)))
            self.process_output.verticalScrollBar().setValue(
                self.process_output.verticalScrollBar().maximum())
            QApplication.processEvents()
            k = k + 1
            if k > self.__iter_num:
                break

        for i in range(self.__size):
            self.population_fitness[i] = self.get_individual_fitness(
                self.population[i, :])
        return

    def operate_evolution_one_enpouch(self):
        mutation_population = self.operate_population_mutation()
        process_population = self.operate_population_crossover(
            mutation_population)
        self.operate_selection(process_population)
        for j in range(self.__size):
            self.population_fitness[j] = self.get_individual_fitness(
                self.population[j, :])
        mean_fitness = np.mean(self.population_fitness)
        max_fitness = np.max(self.population_fitness)
        min_fitness = np.min(self.population_fitness)
        return int(mean_fitness), int(max_fitness), int(min_fitness)

    def operate_population_mutation(self):
        '''对种群实施变异'''
        mutation_population = np.zeros((self.__size, self.__dim))
        for i in range(self.__size):
            list_num = list(range(0, self.__size, 1))
            list_num.remove(i)
            res = random.sample(list_num, 3)
            mutation_individual = self.population[res[0], :] + self.__F * (
                self.population[res[1], :] - self.population[res[2], :]
            )  # 变异操作,产生新个体

            for j in range(self.__dim):  # 特征越限处理
                if mutation_individual[j] < self.x_min[
                        j] or mutation_individual[j] > self.x_max[j]:
                    mutation_individual = self.x_min + random.random() * (
                        self.x_max - self.x_min)
                    break

            mutation_population[i, :] = mutation_individual
        return mutation_population

    def operate_population_crossover(self, mutation_population):
        '''进行交叉操作'''
        process_population = np.zeros((self.__size, self.__dim))
        for i in range(self.__size):
            randn = random.randint(0, self.__dim)
            for j in range(self.__dim):
                rand_float = random.random()
                if rand_float <= self.__CR or randn == j:
                    process_population[i, j] = mutation_population[i, j]
                else:
                    process_population[i, j] = self.population[i, j]
        return process_population

    def operate_selection(self, process_population):
        '''对个体进行选择和更新'''
        for i in range(self.__size):
            ind_1 = self.population[i, :]
            ind_2 = process_population[i, :]
            better_ind = self.select_individual_cla(ind_1, ind_2)
            self.population[i, :] = better_ind
        return

    def select_individual_cla(self, ind_1, ind_2):
        ind_1_cla = self.frequency_classification_model.predict_classes(
            5 * ind_1.reshape((1, -1)))
        ind_1_cla = ind_1_cla[0, 0]
        ind_2_cla = self.frequency_classification_model.predict_classes(
            5 * ind_2.reshape((1, -1)))
        ind_2_cla = ind_2_cla[0, 0]

        if ind_1_cla == 1 and ind_2_cla == 1:
            fit_1 = self.get_individual_fitness(ind_1)
            fit_2 = self.get_individual_fitness(ind_2)
            if fit_1 > fit_2:
                better_ind = ind_2
            else:
                better_ind = ind_1
        elif ind_1_cla == 0 and ind_2_cla == 1:
            better_ind = ind_2

        elif ind_1_cla == 0 and ind_2_cla == 0:
            better_ind = np.zeros(self.__dim)
            for i in range(self.__dim):
                better_ind[i] = random.uniform(self.x_min[i], self.x_max[i])
        else:
            better_ind = ind_1
        return better_ind

    # 以下为个体适应度计算函数
    def get_individual_fitness(self, individual):  # individual应该是个一维数组
        value = np.sum(individual * self.__loads_p)  # 切负荷总量
        return value

    def save_best_individual(self, file):
        min_index = np.argmin(self.population_fitness)
        best_individual = self.population[min_index, :]
        with open(file, 'w', newline='') as f:
            csv_write = csv.writer(f)
            csv_write.writerow(self.loads_shedding)
            csv_write.writerow(best_individual)

        loads_name = []
        for load in self.loads_shedding:
            NAME = self.simulator.get_bus_data(load[0], 'S', 'NAME')
            loads_name.append(NAME)
        return best_individual, self.__loads_p, self.loads_shedding, loads_name

    def check_evolution_result(self, best_individual):
        buses = self.simulator.get_all_buses()
        for bus in buses:
            AREA = self.simulator.get_bus_data(bus, 'I', 'AREA')
            if AREA == 37:
                self.simulator.prepare_bus_meter(bus, 'FREQUENCY IN HZ')
        self.simulator.set_dynamic_simulation_time_step(0.002)
        self.simulator.set_dynamic_simulator_output_file(
            '.\\simulation\\代理辅助模型校验结果')
        self.simulator.start_dynamic_simulation()
        self.simulator.run_dynamic_simulation_to_time(0.5)

        for hvdc in self.hvdc_block:
            self.simulator.manually_block_hvdc(hvdc)
            self.simulator.trip_fixed_shunt((hvdc[1], '1'))

        self.simulator.run_dynamic_simulation_to_time(0.6)
        for i in range(len(self.loads_shedding)):
            self.simulator.scale_load(self.loads_shedding[i],
                                      -1 * best_individual[i])

        self.simulator.run_dynamic_simulation_to_time(5.0)
        self.simulator.stop_dynamic_simulation()

        sample_data = pd.read_csv('.\\simulation\\代理辅助模型校验结果.csv',
                                  header=0,
                                  engine='python')
        columns = list(sample_data)
        frequency_column = []
        for column in columns:
            if 'FREQUENCY' in column:
                frequency_column.append(column)
            else:
                pass
        frequency_data = sample_data.loc[:, frequency_column]
        min_frequency = np.min(frequency_data.values)
        return min_frequency