2014-02-14 5 views
1

Я пытаюсь свести к минимуму (глобально) 3 функции, которые используют общие переменные, я попытался объединить их в одну функцию и свести к минимуму, используя L-BFGS-B (мне нужно установить границы для переменных), но показало, что очень сложно сбалансировать каждый параметр с весовыми коэффициентами, т. е. когда один сведен к минимуму, другой не будет. Я также попытался использовать метод SLSQP, чтобы свести к минимуму один из них при установке других в качестве ограничений, но ограничения часто игнорируются/не выполняются. Вот что нужно свести к минимуму, все математические данные выполняются в meritscalculation и meritoflength, meritofROC, meritofproximity, heightorderreturned возвращаются из вычислений как глобальные.python оптимизирует несколько функций с общими переменными

def lengthmerit(x0): 
    meritscalculation(x0) 
    print meritoflength 
    return meritoflength 

def ROCmerit(x0): 
    meritscalculation(x0) 
    print meritofROC 
    return meritofROC 

def proximitymerit(x0): 
    meritscalculation(x0) 
    print meritofproximity+heightorder 
    return meritofproximity+heightorder 

я хочу, чтобы свести к минимуму все из них с помощью общего х0 (с границами) в качестве независимой переменной, есть ли способ для достижения этой цели?

ответ

2

Это вы хотите сделать?

minimize a * amerit(x) + b * bmerit(x) + c * cmerit(x) 
over a, b, c, x: 
    a + b + c = 1 
    a >= 0.1, b >= 0.1, c >= 0.1 (say) 
    x in xbounds 

Если x это сказать [x0 x1 .. x9], создать новую переменную abcx = [a b c x0 x1 .. x9], Ограничить a + b + c = 1 со сроком одиннадцатиметровой добавляется к целевой функции, и минимизировать это:

define fabc(abcx): 
    """ abcx = a, b, c, x 
     -> a * amerit(x) + ... + penalty 100 (a + b + c - 1)^2 
    """ 
    a, b, c, x = abcx[0], abcx[1], abcx[2], abcx[3:] # split 
    fa = a * amerit(x) 
    fb = b * bmerit(x) 
    fc = c * cmerit(x) 
    penalty = 100 * (a + b + c - 1) ** 2 # 100 ? 
    f = fa + fb + fc + penalty 
    print "fabc: %6.2g = %6.2g + %6.2g + %6.2g + %6.2g a b c: %6.2g %6.2g %6.2g" % (
       f, fa, fb, fc, penalty, a, b, c) 
    return f 

и bounds = [[0.1, 0.5]] * 3 + xbounds, то есть каждый от a b c in 0.1 .. 0.5 или около того.
Длинные print s должен показать вам, почему один из a b c подхода 0 - может быть, один из amerit() bmerit() cmerit() является способ больше, чем другие? Plot s вместо print s тоже будет легко.

Резюме:
1) сформулировать проблему ясно на бумаге, так как в верхних
2) перевести это в питон.

+0

да это то, что я хотел сделать, так это в основном в том числе взвешиваний в процесс оптимизации и позволить компьютеру, чтобы сбалансировать его, не так ли?А также есть большая разница между каждой функцией 'merit()' (порядок 1000 примерно), как это влияет на границы для a, b, c? будет ли оно еще «[0,1, inf]» или что-то еще? В любом случае, я тестирую этот метод сейчас, большое вам спасибо за ваши усилия, вы были наиболее полезны – dilyar

0

здесь является результатом некоторого масштабирования и взвешивания

целевая функция:

merit_function=wa*meritoflength*1e3+wb*meritofROC+wc*meritofproximity+wd*heightorder*10+1000 * (wa+wb+wc+wd-1) ** 2 

вход:

abcdex=np.array((0.5, 0.5, 0.1, 0.3, 0.1...)) 

выход:

fun: array([ 7.79494644]) 

    x: array([ 4.00000000e-01, 2.50000000e-01, 1.00000000e-01, 
    2.50000000e-01...]) 


meritoflength : 0.00465499380753. #target 1e-5, usually start at 0.1 
meritofROC: 23.7317956542   #target ~1, range <33 
Heightorder: 0      #target :strictly 0, range <28 
meritofproximity : 0.0    #target:less than 0.02, range <0.052 

я понял после нескольких работает, все весовые коэффициенты имеют тенденцию оставаться на минимальных значениях привязки и возвращаться к ручной настройке проблемы масштабирования, с которой я начал работать.

Есть ли вероятность, что моя функция оптимизации не найдет истинный глобальный минимум?

вот как я минимизируется его:

minimizer_kwargs = {"method": "L-BFGS-B", "bounds": bnds, "tol":1e0 } 

ret = basinhopping(merit_function, abcdex, minimizer_kwargs=minimizer_kwargs, niter=10) 
zoom = ret['x'] 

res = minimize(merit_function, zoom, method = 'L-BFGS-B', bounds=bnds, tol=1e-6) 
+0

'tol = 1' ?? попробуйте 1e-4. Внимательно прочитайте документ [basinhopping doc] (http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.basinhopping.html): «Для лучших результатов« T »должно быть сопоставимо с разделом (в значение функции) между локальными минимумами "- он может быть чувствительным к x0, stepize ... тоже. И «весовые коэффициенты имеют тенденцию оставаться на минимальных значениях границы»: они должны суммироваться до 1? иначе увеличьте штрафный коэффициент 100. – denis

+0

причина, по которой я установил tol = 1, - это сканировать более крупный домен с меньшей точностью (или он будет тратить много времени на то, чтобы свести к минимуму большое значение), затем я использовал второй 'minim' чтобы улучшить минимальное значение, возвращаемое первой минимизацией, до более высокой точности. – dilyar

+0

Вы не можете ожидать хорошего минимума в течение почти 0 времени, в случае проблемы с большими размерами, с инструментом с неизвестными параметрами. Я бы посоветовал начать с крошечной проблемы, когда вы знаете ответ, чтобы получить некоторый опыт по сравнению с функцией value/runtime. – denis

Смежные вопросы