У меня есть физический модуль, который принимает 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()
Вы переопределяете prob.driver.options['bits']
много раз... Вам нужно объявить его однажды со словарем со всеми вашими переменными в качестве ключей (для которых вы хотите установить биты)
Можете ли вы сказать мне, как это сделать? Разве разные входные данные не должны иметь разные биты в зависимости от размера десятичных чисел и диапазона значений, которые я хочу, чтобы оптимизатор принимал? Однобитовое значение, основанное на самом большом числе и максимальном количестве десятичных разрядов, которые я хочу, не будет ли это слишком много памяти? Я говорю что-то не так? Добрый совет.
Я хочу сказать, что синтаксис Python, который вы используете, не соответствует вашим намерениям. В вашем коде «биты» будут установлены только для последней переменной (p14.front
), потому что вы перезаписываете ее в каждой строке. То, что вы хотите, выглядит примерно так: prob.driver.options['bits'] = {'p1.ln': 22, 'p2.lfc': 22, 'p3.df': 14}
(я включил только 3 переменные, просто поместите их все таким же образом)
Я понял. Спасибо. Я посмотрю, какую разницу это создаст.
Без примера кода здесь действительно сложно дать какой-либо хороший ответ. SimpleGA названа так, потому что это
simple
. Алгоритм не будет хорошо работать на всех задачах. При этом тот факт, что вы не можете получить простую модель, чтобы дать ответ с помощью COBYLA, также свидетельствует о наличии проблемы с вашей реализацией. Если бы вы разместили простую задачу запуска, мы могли бы взглянуть