2015-08-27 11 views
7

मैं पाइथन के scipy.optimize का उपयोग कर निम्न फ़ंक्शन को अधिकतम करने की कोशिश कर रहा हूं। हालांकि, बहुत कोशिश करने के बाद, यह काम नहीं लग रहा है। फ़ंक्शन और मेरा कोड नीचे चिपकाया गया है। मदद के लिए धन्यवाद!पायथन (scipy.optimize) के साथ अनुकूलन

समस्या

Maximize [sum (x_i/y_i)**gamma]**(1/gamma) 
subject to the constraint sum x_i = 1; x_i is in the interval (0,1). 

x पसंद चर का एक वेक्टर है; y पैरामीटर का एक वेक्टर है; gamma एक पैरामीटर है। x एस को एक के बराबर होना चाहिए। और प्रत्येक x अंतराल (0,1) में होना चाहिए।

कोड

def objective_function(x, y): 
    sum_contributions = 0 
    gamma = 0.2 

    for count in xrange(len(x)): 
     sum_contributions += (x[count]/y[count]) ** gamma 
    value = math.pow(sum_contributions, 1/gamma) 
    return -value 

cons = ({'type': 'eq', 'fun': lambda x: np.array([sum(x) - 1])}) 

y = [0.5, 0.3, 0.2] 
initial_x = [0.2, 0.3, 0.5] 

opt = minimize(objective_function, initial_x, args=(y,), method='SLSQP', 
constraints=cons,bounds=[(0, 1)] * len(x)) 
+0

यदि आप के बारे में विशिष्ट थे उपयोगी हो सकता है क्या लक्ष्य को उजागर करना अपरिहार्य 'की कोशिश कर के बहुत सारे' आपके प्रश्न का – Erik

+0

आपका कोड मेरे लिए काम करता है। आपको क्या समस्या है? मुझे इष्टतम 'x_opt: सरणी मिलती है ([0.29465573, 0.33480638, 0.37053789])'। मुझे बस इतना बदलना था कि 'सीमा' में 'लेन' (प्रारंभिक_एक्स) 'या' लेन (वाई) 'होना चाहिए, क्योंकि आपके कोड में' x' परिभाषित नहीं है। – askewchan

+1

@askewchan, एक संख्यात्मक स्थिरता मुद्दा हो सकता है। मेरे मैक पर मुझे 'नान' ज्ञान मिल रहा है, '' इटरेशन सीमा पार हो गई ' –

उत्तर

3

कभी कभी, संख्यात्मक अनुकूलक जो भी कारण के लिए काम नहीं करता। हम समस्या को थोड़ा अलग कर सकते हैं और यह सिर्फ काम करेगा। (0,1) की सीमा के लिए, (और तेजी से काम कर सकते हैं)

उदाहरण के लिए, हम एक को बदलने समारोह ऐसा है कि (-inf, +inf) में मूल्यों, तब्दील किया जा रहा करने के बाद, ऊपर (0,1)

में खत्म हो जाएगा हम के साथ एक समान चाल कर सकते हैं हो सकता है समानता बाधाएं। उदाहरण के लिए, हम आयाम को 3 से 2 तक कम कर सकते हैं, क्योंकि x में अंतिम तत्व 1-sum(x) होना चाहिए।

यदि यह अभी भी काम नहीं करेगा, तो हम एक अनुकूलक पर स्विच कर सकते हैं कि खुराक को व्युत्पन्न से जानकारी की आवश्यकता नहीं है, जैसे कि Nelder Mead

और Lagrange multiplier भी है।

In [111]: 

def trans_x(x): 
    x1 = x**2/(1+x**2) 
    z = np.hstack((x1, 1-sum(x1))) 
    return z 

def F(x, y, gamma = 0.2): 
    z = trans_x(x) 
    return -(((z/y)**gamma).sum())**(1./gamma) 
In [112]: 

opt = minimize(F, np.array([0., 1.]), args=(np.array(y),), 
       method='Nelder-Mead') 
opt 
Out[112]: 
    status: 0 
    nfev: 96 
success: True 
    fun: -265.27701747828007 
     x: array([ 0.6463264, 0.7094782]) 
message: 'Optimization terminated successfully.' 
    nit: 52 

परिणाम है:

In [113]: 

trans_x(opt.x) 
Out[113]: 
array([ 0.29465097, 0.33482303, 0.37052601]) 

और हम इसे कल्पना कर सकते हैं, के साथ:

In [114]: 

x1 = np.linspace(0,1) 
y1 = np.linspace(0,1) 
X,Y = np.meshgrid(x1,y1) 
Z = np.array([F(item, y) for item 
       in np.vstack((X.ravel(), Y.ravel())).T]).reshape((len(x1), -1), order='F') 
Z = np.fliplr(Z) 
Z = np.flipud(Z) 
plt.contourf(X, Y, Z, 50) 
plt.colorbar() 

enter image description here

+0

हाय @ सीटी झू, शानदार समाधान। 'X1 = x ** 2/(1 + x ** 2)' क्या करता है? 'X''' (-inf, + inf) 'के लिए –

+1

', 'इसे' x1' '(0, 1)' में 'x1'' में बदलें। सीमा निर्धारित करने के समान ही काम करने का क्रमबद्ध करें, क्योंकि ओपी को 'x अंतराल (0,1)' होना चाहिए। –

+0

यह वास्तव में बदलता है -इन 1 तक! यह केवल (0, + inf) –

1

यहां तक ​​कि कठिन इस सवाल थोड़ा दिनांकित है मैं जोड़ना चाहते थे एक वैकल्पिक समाधान जो भविष्य में इस प्रश्न पर ठोकर खा सकता है ।

यह आपकी समस्या को विश्लेषणात्मक रूप से हल करने योग्य है। आप (समानता विवश) अनुकूलन समस्या का लाग्रंगियन नीचे लिख कर शुरू कर सकते हैं:

L = \sum_i (x_i/y_i)^\gamma - \lambda (\sum x_i - 1) 

इष्टतम समाधान शून्य करने के लिए इस लाग्रंगियन के पहले व्युत्पन्न की स्थापना करके पाया जाता है:

0 = \partial L/\partial x_i = \gamma x_i^{\gamma-1}/\y_i - \lambda 
=> x_i \propto y_i^{\gamma/(\gamma - 1)} 

इस अंतर्दृष्टि का उपयोग करना अनुकूलन समस्या से आसानी से और कुशलता से हल किया जा सकता:

In [4]: 
def analytical(y, gamma=0.2): 
    x = y**(gamma/(gamma-1.0)) 
    x /= np.sum(x) 
    return x 
xanalytical = analytical(y) 
xanalytical, objective_function(xanalytical, y) 
Out [4]: 
(array([ 0.29466774, 0.33480719, 0.37052507]), -265.27701765929692) 

सीटी झू के समाधान सुरुचिपूर्ण है, लेकिन यह तीसरी सीओओ पर सकारात्मकता बाधा उल्लंघन कर सकते हैं rdinate।gamma = 0.2 के लिए इस अभ्यास में एक समस्या हो प्रतीत नहीं होता है, लेकिन अलग अलग gammas के लिए आप आसानी से मुसीबत में पड़:

In [5]: 
y = [0.2, 0.1, 0.8] 
opt = minimize(F, np.array([0., 1.]), args=(np.array(y), 2.0), 
       method='Nelder-Mead') 
trans_x(opt.x), opt.fun 
Out [5]: 
(array([ 1., 1., -1.]), -11.249999999999998) 

आपकी समस्या के रूप में ही संभावना सिंप्लेक्स बाधाओं के साथ अन्य अनुकूलन समस्याओं के लिए, लेकिन जिसके लिए कोई है विश्लेषणात्मक समाधान, अनुमानित ढाल विधियों या इसी तरह की तलाश में लायक हो सकता है। ये विधियां इस तथ्य का लाभ उठाती हैं कि इस सेट पर मनमाने ढंग से बिंदु के प्रक्षेपण के लिए तेज़ एल्गोरिदम है https://en.wikipedia.org/wiki/Simplex#Projection_onto_the_standard_simplex देखें।

(पूरा कोड और समीकरणों का एक बेहतर प्रतिपादन देखने के लिए Jupyter नोटबुक http://nbviewer.jupyter.org/github/andim/pysnippets/blob/master/optimization-simplex-constraints.ipynb पर एक नज़र डालें)

+0

एंडी, धन्यवाद। लेकिन ऑप्टिमाइज़ेशन समस्या जिसे मैं हल करने की कोशिश कर रहा था वह विश्लेषणात्मक माध्यमों का उपयोग करके हल करने वाले कुछ से अलग है। यहां पूरी समस्या है: http: //math.stackexchange.com/questions/2168338/explicit-solution-to-optimization-problem मुझे विश्लेषणात्मक समाधान और तेज़ संख्यात्मक अनुमानों के बारे में सुनकर खुशी होगी। धन्यवाद: - – user58925

+0

यदि तीसरा पैरामीटर सकारात्मक होना चाहिए, तो क्या इस काम को कुछ पसंद आएगा? '# ए = तीसरा समन्वय (सकारात्मक बाधा)' 'ए = abs (ए)' – mikey

संबंधित मुद्दे