Генетический алгоритм Популяционный индивид как массив

#python #optimization #genetic-algorithm #pymoo

Вопрос:

У меня нет большого опыта использования генетических алгоритмов, поэтому я хотел бы попросить сообщество дать несколько полезных комментариев. Я хочу извиниться за свои терминологические ошибки. Пожалуйста, поправьте меня, если это необходимо.

Проблема, которую я хочу оптимизировать, заключается в оптимальном потоке энергии в островковой микросетке. В простой микросетке у нас есть 2 дизельных генератора (DG), 1 фотоэлектрическая матрица, 1 Система накопления энергии (ESS) и нагрузка. Давайте предположим, что мы знаем значения выходной мощности нагрузки и фотоэлектрической матрицы для следующих периодов.

Таким образом, целевая функция должна быть сведена к минимуму-это операционные затраты как сумма операционных затрат на каждый компонент микросети в каждый момент t периода T :

где a , b некоторые коэффициенты эксплуатационных затрат, является двоичной переменной состояния дизельного генератора (0/1 или ВКЛ/ВЫКЛ) и P выходной мощностью компонента микросети в данный момент t .

И вот некоторые из ограничений (реальная проблема вряд ли и нелинейно ограничена, поэтому я записал только три ограничения):

  1. Баланс сил

  1. Максимальная глубина дисгармонии ESS

  1. Предельная мощность дизельных генераторных установок

Итак, это смешанная целочисленная задача с нелинейными ограничениями. Я попытался адаптировать проблему для ее решения с помощью генетического алгоритма. Я использовал библиотеку Python pymoo для мультиобъективной оптимизации с алгоритмом NSGA2. Давайте рассмотрим и для этого T у нас есть некоторые Load PV данные и мощности:

 from pymoo.model.problem import FunctionalProblem
from pymoo.factory import get_sampling, get_crossover, get_mutation
from pymoo.operators.mixed_variable_operator import MixedVariableSampling, MixedVariableMutation, MixedVariableCrossover
from pymoo.algorithms.nsga2 import NSGA2
from pymoo.factory import get_sampling, get_crossover, get_mutation, get_termination
from pymoo.optimize import minimize

PV = np.array([10, 19.8, 16, 25, 7.8, 42.8, 10]) #PV inverter output power, kW
Load = np.array([100, 108, 150, 150, 90, 16, 170]) #Load, kW

balance_eps = 0.001 #equality constraint relaxing coefficient

DG1_pmin = 0.3 #DG1 min power
DG2_pmin = 0.3 #DG2 min power
P_dg1 = 75 #DG1 rated power, kW
P_dg2 = 75 #DG1 rated power, kW

P_PV_inv = 50 #PV inverter rated power, kW

P_ESS_inv = 30 #ESS bidirectional inverter absolute rated discharge/charge power, kW

ESS_c = 100 #ESS capacity, kWh

SOC_min = 30
SOC_max = 100
    
objs = [lambda x: x[0]*x[2]*200   x[1]*x[3]*200   x[4]*0.002 #objective function]

constr_eq = [lambda x: ((Load[t] - x[0]*x[2] - x[1]*x[3] - x[4] - PV[t] )**2)]

constr_ieq = [lambda x: -SOC_t   100*x[4]/ESS_c   SOC_min,
    lambda x: SOC_t - 100*x[4]/ESS_c - SOC_max]

problem = FunctionalProblem(n_var=n_var, objs, constr_eq=constr_eq, constr_eq_eps=1e-03, constr_ieq=constr_ieq, 
          xl=np.array([0, 0, DG1_pmin*P_dg1, DG2_pmin*P_dg2, -P_ESS_inv]), xu=np.array([1, 1, P_dg1, P_dg2, P_ESS_inv]))

mask = ["int", "int", "real", "real", "real"]

sampling = MixedVariableSampling(mask, {
    "real": get_sampling("real_random"),
    "int": get_sampling("int_random")})

crossover = MixedVariableCrossover(mask, {
    "real": get_crossover("real_sbx", prob=1.0, eta=3.0),
    "int": get_crossover("int_sbx", prob=1.0, eta=3.0)})

mutation = MixedVariableMutation(mask, {
    "real": get_mutation("real_pm", eta=3.0),
    "int": get_mutation("int_pm", eta=3.0)})

algorithm = NSGA2(
    pop_size=150,
    sampling=sampling,
    crossover=crossover,
    mutation=mutation,
    eliminate_duplicates=True)
 

We have n_var = 5 decision variables which are being optimized: . We should also have an access to the previous value of SOC .
I wrote a recursive code to implement a consecutive optimization chain:

 x=[]
s=[]
SOC_t = 100 #SOC at t = -1

for t in range (0, 7):

    res = minimize(
        problem,
        algorithm,
        seed=1,
        termination = get_termination("n_gen", 300),
        save_history=True, verbose=False)

    SOC_t = SOC_t - 100*res.X[4]/ESS_c

    print(res.X[:2], np.around(res.X[2:].astype(np.double), 3), np.around(SOC_t, 2))
    x.append(res.X)
    s.append(SOC_t) 
 

So, we have initialized populations with size 150 for every time step t and individuals in that populations looked like . Running this code I get these optimization results found:

 [1 1] [27.272 34.635 28.071] 71.93
[0 1] [28.127 58.168 30.   ] 41.93
[1 1] [50.95  71.423 11.599] 30.33
[1 1] [53.966 70.97  0.034] 30.3
[1 1] [24.636 59.236 -1.702] 32.0
[0 0] [40.831  29.184 -26.832] 58.83
[1 1] [68.299 63.148 28.572] 30.26
 

Even my little experience in Genetic Algorithms allows me to state, that such approach is inappropriate and unefficient.

So, here is my question (if you’re still reading my post 🙂

Is there a way to optimize such problem using not consecutive optimization of a particular variables set at t , but defining individuals in population as arrays with size ( T , n_var )?

For the problem described an individual in population may look like

Is it possible to implement such approach? If yes, how to do it in pymoo ?

Thank you very much for your time! Any comments and suggestions will be appreciated.