Драйвер простого генетического алгоритма openmdao не работает

У меня есть физический модуль, который принимает 14 входных данных и выдает 6 выходных данных: 1 в целевой функции (фитнес), а остальные - ограничения (штраф). Модуль физики немного сложен, но я нашел решения, удовлетворяющие моим требованиям, с помощью независимого случайного блуждания. Но когда я запускаю то же самое с Simple GA на Openmdao, я не получаю ни оптимального, ни штрафные функции (ограничения), похоже, не работают. Результат даже не дает набора данных, близкого к тому, что произвело случайное блуждание. Я пробовал варьировать размер популяции от 140 до 2000, параметр штрафа от 1 до 20, показатель штрафа от 1 до 2,5, Pm от 0,02 до 0,08. ПК оставлен на уровне 0,5. Я позволил коду работать более 2000 поколений, но оптимизация, похоже, не работает. Я также создал простую модель с 6 входными данными, одним ограничением и одной целевой функцией, тогда ограничения также не были удовлетворены. Будьте добры, подскажите решение. Та же физическая модель с драйвером COBYLA не оптимизируется.

РЕДАКТИРОВАТЬ-1:

Я приложил следующую реализацию OpenMDAO с запущенным модулем Physics.

Кроме того, когда я говорю, что драйвер COBYLA не может «оптимизировать», это означает, что каждый раз, когда я запускаю оптимизацию с разными начальными переменными проекта, я получаю несколько иной результат. Оптимум должен быть одинаковым каждый раз. Это из-за математической формулировки COBYLA?

С помощью ГА я обнаружил, что средняя приспособленность популяции действительно эффективно (хотя и очень незначительно) увеличивается в течение эффективного скользящего окна времени. Но это не останавливается. Я имею в виду, что оптимизатор работает уже более 80 часов.

При использовании SLSQP оптимизатор завершает работу уже после первой итерации. Я уменьшил значение допуска до 1e-40, после чего оно также не выходит за пределы первой итерации. Тем не менее, COBYLA смогла предоставить мне осуществимые проекты, такие же, как эксперименты со случайным блужданием.

from openmdao.api import Problem, Group, SimpleGADriver, ExplicitComponent,ExecComp, IndepVarComp, ScipyOptimizeDriver

class Obj_Prod(ExplicitComponent):

    def setup(self):
        self.add_input('ln',val=0.0)           
        self.add_input('lfc',val=0.0)       
        self.add_input('df',val=0.0)        
        self.add_input('dp',val=0.0)        
        self.add_input('tf',val=0.0)        
        self.add_input('hf',val=0.0)        
        self.add_input('lt',val=0.0)        
        self.add_input('delf1',val=0.0)     
        self.add_input('delf2',val=0.0)     
        self.add_input('delf3',val=0.0)     
        self.add_input('delf4',val=0.0)     
        self.add_input('delf5',val=0.0)     
        self.add_input('co',val=0.0)           
        self.add_input('front',val=0.0)

        self.add_output('geR',val=0.0)
        self.add_output('FCP',val=0.0)
        self.add_output('FS',val=0.0)
        self.add_output('vlres',val=0.0)
        self.add_output('diff_bre',val=0.0)
        self.add_output('diff_sets',val=0.0)

    def compute(self, inputs, outputs):

        ln                      = inputs['ln'][0]               
        lfc                     = inputs['lfc'][0]              
        df                      = inputs['df'][0]                 
        dp                      = inputs['dp'][0]                
        tf                      = inputs['tf'][0]                
        hf                      = inputs['hf'][0]                
        lt                      = inputs['lt'][0]                
        delf1                   = inputs['delf1'][0]              
        delf2                   = inputs['delf2'][0]              
        delf3                   = inputs['delf3'][0]              
        delf4                   = inputs['delf4'][0]              
        delf5                   = inputs['delf5'][0]              
        co                      = inputs['co'][0]                                  
        front                   = inputs['front'][0]

        equation_inputs = numpy.array([[ln,lfc,df,dp,tf,hf,lt,delf1,delf2,delf3,delf4,delf5,co,front]])

        Physics_obj             = Physics_Module()
        out                     = Physics_obj.main(equation_inputs)
        outputs['geR']          = -out[0][0]*1e-3
        outputs['FCP']          = out[0][1] - 1.1
        outputs['FS']           = out[0][2] - 1.1
        outputs['vlres']        = out[0][3]
        outputs['diff_bre']     = out[0][4]
        outputs['diff_sets']    = out[0][5]
        gc.collect()


Single_Opt_iter = 0

init_ln           = random.uniform(20.,35.,1)[0] 
init_lfc          = random.uniform(15.,30.,1)[0]
init_df           = random.uniform(5.,10.,1)[0]
init_dp           = random.uniform (11.,16.,1)[0]
init_tf           = random.uniform(1.,5.,1)[0]
init_hf           = random.uniform(4.,14.,1)[0]
init_lt           = random.uniform(8.,13.,1)[0]
init_delf1        = random.uniform(10.,30.,1)[0]
init_delf2        = random.uniform(7.,15.,1)[0]
init_delf3        = random.uniform(10.,30.,1)[0]
init_delf4        = random.uniform(5.,10.,1)[0]
init_delf5        = random.uniform(10.,30.,1)[0]
init_co           = random.uniform(10.,30.,1)[0]
init_front        = random.uniform(10.,30.,1)[0]
equation_inputs = numpy.array([[init_ln, init_lfc, init_df, init_dp, init_tf, init_hf, init_lt, init_delf1, init_delf2, init_delf3, init_delf4, init_delf5, init_co, init_front]])
ff2=open("input1.csv","a")
dump = equation_inputs
numpy.savetxt(ff2, dump, delimiter = ",")
ff2.close()

if __name__ == "__main__":
    global counter
    counter = 0

    prob = Problem()
    model = prob.model = Group()

    model.add_subsystem('p1', IndepVarComp('ln',init_ln))
    model.add_subsystem('p2', IndepVarComp('lfc', init_lfc))
    model.add_subsystem('p3', IndepVarComp('df', init_df))
    model.add_subsystem('p4', IndepVarComp('dp', init_dp))
    model.add_subsystem('p5', IndepVarComp('tf', init_tf))
    model.add_subsystem('p6', IndepVarComp('hf', init_hf))
    model.add_subsystem('p7', IndepVarComp('lt', init_lt))
    model.add_subsystem('p8', IndepVarComp('delf1', init_delf1))
    model.add_subsystem('p9', IndepVarComp('delf2', init_delf2))
    model.add_subsystem('p10', IndepVarComp('delf3', init_delf3))
    model.add_subsystem('p11', IndepVarComp('delf4', init_delf4))
    model.add_subsystem('p12', IndepVarComp('delf5', init_delf5))
    model.add_subsystem('p13', IndepVarComp('co', init_co))
    model.add_subsystem('p14', IndepVarComp('front', init_front))

    model.add_subsystem('Obj_Prod', Obj_Prod())

    model.connect('p1.ln', 'Obj_Prod.ln')
    model.connect('p2.lfc', 'Obj_Prod.lfc')
    model.connect('p3.df', 'Obj_Prod.df')
    model.connect('p4.dp', 'Obj_Prod.dp')
    model.connect('p5.tf', 'Obj_Prod.tf')
    model.connect('p6.hf', 'Obj_Prod.hf')
    model.connect('p7.lt', 'Obj_Prod.lt')
    model.connect('p8.delf1', 'Obj_Prod.delf1')
    model.connect('p9.delf2', 'Obj_Prod.delf2')
    model.connect('p10.delf3', 'Obj_Prod.delf3')
    model.connect('p11.delf4', 'Obj_Prod.delf4')
    model.connect('p12.delf5', 'Obj_Prod.delf5')
    model.connect('p13.co', 'Obj_Prod.co')
    model.connect('p14.front', 'Obj_Prod.front')

    model.add_design_var('p1.ln', lower=20., upper=35.)       #15
    model.add_design_var('p2.lfc', lower=15., upper=30.)      #15
    model.add_design_var('p3.df', lower=5., upper=10.)        #5
    model.add_design_var('p4.dp', lower=11., upper=16.)       #5
    model.add_design_var('p5.tf', lower=1., upper=5.)         #5
    model.add_design_var('p6.hf', lower=4., upper=14.)        #10
    model.add_design_var('p7.lt', lower=8., upper=13.)        #5
    model.add_design_var('p8.delf1', lower=10., upper=30.)    #20
    model.add_design_var('p9.delf2', lower=7., upper=15.)     #5
    model.add_design_var('p10.delf3', lower=10., upper=30.)   #20
    model.add_design_var('p11.delf4', lower=5., upper=10.)   #5
    model.add_design_var('p12.delf5', lower=10., upper=30.)   #20
    model.add_design_var('p13.co', lower=10., upper=30.)      #20
    model.add_design_var('p14.front', lower=10., upper=30.)   #20
    model.add_objective('Obj_Prod.geR')

    prob.driver = SimpleGADriver()
    prob.driver.options['bits'] = {'p1.ln': 22}
    prob.driver.options['bits'] = {'p2.lfc': 22}
    prob.driver.options['bits'] = {'p3.df': 14}
    prob.driver.options['bits'] = {'p4.dp': 18}
    prob.driver.options['bits'] = {'p5.tf': 12}
    prob.driver.options['bits'] = {'p6.hf': 17}
    prob.driver.options['bits'] = {'p7.lt': 16}
    prob.driver.options['bits'] = {'p8.delf1': 22}
    prob.driver.options['bits'] = {'p9.delf2': 18}
    prob.driver.options['bits'] = {'p10.delf3': 22}
    prob.driver.options['bits'] = {'p11.delf4': 14}
    prob.driver.options['bits'] = {'p12.delf5': 22}
    prob.driver.options['bits'] = {'p13.co': 22}
    prob.driver.options['bits'] = {'p14.front': 22}
    prob.driver.options['max_gen'] = 10000
    prob.driver.options['pop_size'] = 140
    prob.driver.options['run_parallel'] = False
    prob.driver.options['procs_per_model'] = 3
    prob.driver.options['Pm'] = 0.08
    prob.driver.options['Pc'] = 0.5
    prob.driver.options['elitism'] = True
    prob.driver.options['penalty_parameter'] = 10.
    prob.driver.options['penalty_exponent'] = 1.
    prob.model.add_constraint('Obj_Prod.FCP', lower=0.)
    prob.model.add_constraint('Obj_Prod.FS', lower=0.)
    prob.model.add_constraint('Obj_Prod.vlres', lower=0.)
    prob.model.add_constraint('Obj_Prod.diff_bre', lower=0.)
    prob.model.add_constraint('Obj_Prod.diff_sets', lower=0.)

    prob.setup()
    prob.run_driver()
    prob.cleanup()

Без примера кода здесь действительно сложно дать какой-либо хороший ответ. SimpleGA названа так, потому что это simple. Алгоритм не будет хорошо работать на всех задачах. При этом тот факт, что вы не можете получить простую модель, чтобы дать ответ с помощью COBYLA, также свидетельствует о наличии проблемы с вашей реализацией. Если бы вы разместили простую задачу запуска, мы могли бы взглянуть

Justin Gray 24.02.2019 15:18

Вы переопределяете prob.driver.options['bits'] много раз... Вам нужно объявить его однажды со словарем со всеми вашими переменными в качестве ключей (для которых вы хотите установить биты)

onodip 01.03.2019 23:42

Можете ли вы сказать мне, как это сделать? Разве разные входные данные не должны иметь разные биты в зависимости от размера десятичных чисел и диапазона значений, которые я хочу, чтобы оптимизатор принимал? Однобитовое значение, основанное на самом большом числе и максимальном количестве десятичных разрядов, которые я хочу, не будет ли это слишком много памяти? Я говорю что-то не так? Добрый совет.

rishav kanth 02.03.2019 15:22

Я хочу сказать, что синтаксис Python, который вы используете, не соответствует вашим намерениям. В вашем коде «биты» будут установлены только для последней переменной (p14.front), потому что вы перезаписываете ее в каждой строке. То, что вы хотите, выглядит примерно так: prob.driver.options['bits'] = {'p1.ln': 22, 'p2.lfc': 22, 'p3.df': 14} (я включил только 3 переменные, просто поместите их все таким же образом)

onodip 03.03.2019 20:34

Я понял. Спасибо. Я посмотрю, какую разницу это создаст.

rishav kanth 04.03.2019 07:47
Загадки Python - Генерация простых чисел!
Загадки Python - Генерация простых чисел!
Обычно существует несколько способов решения задач даже пограничной сложности. Как же определить оптимальное и эффективное решение?
0
5
205
0

Другие вопросы по теме