2016-01-12 6 views
18

मैं एक व्यक्ति का उपयोग करने वाले इष्टतम N इकाइयों को ढूंढकर उपयोगिता फ़ंक्शन को अधिकतम करने की कोशिश कर रहा हूं। बाधाओं में से एक यह है कि उनके पास सीमित धन है, m। तो मैं एक बाधा स्थापित करने की कोशिश कर रहा हूं जहां लंबाई 3, N कीमतों की संख्या, P लंबाई 3 की एक सरणी भी m से अधिक नहीं हो सकती है।दो तर्कों का उपयोग करके Scipy Optimizer बाधा

उदाहरण की तरह इस प्रकार है:

P = np.array([3,4,5]) 
N = np.array([1,2,1]) 
m = 50 
sum(P*N) > m 

इस अनुकूलन के लिए, P पिछले एक अनुकूलन के आधार पर दिया जाता है।

cons_c = [{'type':'ineq', 'fun': lambda N: 10 - sum(np.round(N)*P)},{'type':'ineq', 'fun': lambda N: 24 - sum(N*T)}] 
bnds = [(0.,None) for x in range(len(N))] 
optimized_c = scipy.optimize.minimize(utility_c, N, (P,Q,T), method='SLSQP', bounds=bnds, constraints=cons_c) 

समारोह:

def utility_c(N,P,Q,T): 

    print "N: {0}".format(N) 
    print "P: {0}".format(P) 
    print "Q: {0}".format(Q) 
    print "T: {0}".format(T) 
    N = np.round(N) 
    m = 10 - sum(N*P) 
    b = sum(N*Q) 
    t = 24 - sum(N*T) 
    print "m in C: {0}".format(m) 
    print "b: {0}".format(b) 
    print "t: {0}".format(t) 
    # if m < 0 or t < 0: 
    #  return 0 
    return 1/ ((b**0.3)*(t**0.7))+(5*(m**0.5)) 

समस्या मैं अभी भी नकारात्मक m मिलता है अब यहाँ मेरे वास्तविक कोड है! तो स्पष्ट रूप से मैं बाधा को ठीक से पार नहीं कर रहा हूं। मुझे लगता है कि ऐसा इसलिए है क्योंकि P ठीक से उपयोग नहीं किया जाता है?

आउटपुट:

N: [ 1. 1. 1.] 
P: [ 5. 14. 4.] 
Q: [ 1. 3. 1.] 
T: [ 1. 1. 1.01] 
m in C: -13.0 

मैं क्या कोशिश की है:

मैं भी आर्ग में P गुजर, इसलिए तरह की कोशिश की है:

cons_c = [{'type':'ineq', 'fun': lambda N,P: 10 - sum(np.round(N)*P), 'args':P},{'type':'ineq', 'fun': lambda N: 24 - sum(N*T)}] 

लेकिन यह बताता है मुझे 'लम्बाडा 2-तर्क चाहता है और 4

प्राप्त हुआ 363,210

** अद्यतन: **

का उपयोग कर 'args' में (F,) कार्यक्रम एक त्रुटि को ऊपर उठाने के बिना चलाने की अनुमति नहीं है, लेकिन बाधा अभी भी पकड़ करने के लिए विफल रहता है।

इसके अलावा, nanm के बाद वापस किया गया है, ऋणात्मक मूल्य के रूप में परिभाषित किया गया है, जो निश्चित रूप से पूरी तरह से उछाल से बाहर निकलता है।

** पूर्ण परियोजना कोड: **

import scipy.optimize 
import numpy as np 
import sys 

def solve_utility(P,Q,T): 
    """ 
    Here we are given the pricing already (P,Q,T), but solve for the quantities each type 
    would purchase in order to maximize their utility (N). 
    """ 

    def utility_a(N,P,Q,T): 
     N = np.round(N) 
     m = 50 - sum(N*P) 
     b = sum(N*Q) 
     t = 8 - sum(N*T) 
     return 1/ ((b**0.5)*(t**0.5))+(5*(m**0.5)) 

    def utility_b(N,P,Q,T): 
     N = np.round(N) 
     m = 50 - sum(N*P) 
     b = sum(N*Q) 
     t = 8 - sum(N*T) 
     return 1/ ((b**0.7)*(t**0.3))+(5*(m**0.5)) 

    def utility_c(N,P,Q,T): 
     N = np.round(N) 
     print "N: {0}".format(N) 
     print "P: {0}".format(P) 
     print "Q: {0}".format(Q) 
     print "T: {0}".format(T) 
     m = 10 - sum(N*P) 
     b = sum(N*Q) 
     t = 24 - sum(N*T) 
     print "m in C: {0}".format(m) 
     print "b: {0}".format(b) 
     print "t: {0}".format(t) 
     return 1/ ((b**0.3)*(t**0.7))+(5*(m**0.5)) 



    # Establishing constraints so no negative money or time: 
    N = np.array([2,2,1]) 
    cons_a = [{'type':'ineq', 'fun': lambda N, P: 50 - sum(np.round(N)*P), 'args':(P,)},{'type':'ineq', 'fun': lambda N: 8 - sum(N*T)}] 
    cons_b = [{'type':'ineq', 'fun': lambda N, P: 50 - sum(np.round(N)*P), 'args':(P,)},{'type':'ineq', 'fun': lambda N: 8 - sum(N*T)}] 
    cons_c = [{'type':'ineq', 'fun': lambda N, P: 10 - sum(np.round(N)*P), 'args':(P,)},{'type':'ineq', 'fun': lambda N: 24 - sum(N*T)}] 

    maxes = P/50 
    bnds = [(0.,None) for x in range(len(N))] 
    b = [()] 

    optimized_a = scipy.optimize.minimize(utility_a, N, (P,Q,T), method='SLSQP', constraints=cons_a) 
    optimized_b = scipy.optimize.minimize(utility_b, N, (P,Q,T), method='SLSQP', constraints=cons_b) 
    optimized_c = scipy.optimize.minimize(utility_c, N, (P,Q,T), method='SLSQP', constraints=cons_c) 

    if not optimized_a.success: 
     print "Solving Utilities A didn't work..." 
     return None 
    if not optimized_b.success: 
     print "Solving Utilities B didn't work..." 
     return None 
    if not optimized_c.success: 
     print "Solving Utilities C didn't work..." 
     return None 
    else: 
     print "returning N: {0}".format(np.array([optimized_a.x,optimized_b.x,optimized_c.x])) 
     return np.array([optimized_a.x,optimized_b.x,optimized_c.x]) 


# solve_utility(P,Q,T,N) 


def solve_profits(): 
    """ 
    Here we build the best pricing strategy to maximize solve_profits 
    """ 

    P = np.array([ 3,  10.67,  2.30]) # Pricing 
    Q = np.array([ 1,  4,  1]) # Quantity of beer for each unit 
    T = np.array([ 1,  1, 4]) # Time cost per unit 
    N = np.array([ 1,  0,  1]) # Quantities of unit taken by customer 

    def profit(X): 
     P,Q,T = X[0:3], X[3:6], X[6:9] 
     Q[1] = round(Q[1]) # needs to be an integer 
     N = solve_utility(P,Q,T) 
     print "N: {0}".format(N) 
     N = np.sum(N,axis=1) 
     # print "P: {0}".format(P) 
     # print "Q: {0}".format(Q) 
     # print "T: {0}".format(T) 
     denom = sum(N*P*Q) - sum(Q*N) 
     return 1/ (sum(N*P*Q) - sum(Q*N)) 

    cons = [{'type':'ineq', 'fun': lambda X: X[8] - X[6] - 0.01 }, # The time expense for a coupon must be 0.01 greater than regular 
      {'type':'ineq', 'fun': lambda X: X[4] - 2 }, # Packs must contain at least 2 beers 
      {'type':'eq', 'fun': lambda X: X[3] - 1}, # Quantity has to be 1 for single beer 
      {'type':'eq', 'fun': lambda X: X[5] - 1}, # same with coupons 
      {'type':'ineq', 'fun': lambda X: X[6] - 1}, # Time cost must be at least 1 
      {'type':'ineq', 'fun': lambda X: X[7] - 1}, 
      {'type':'ineq', 'fun': lambda X: X[8] - 1}, 
      ] 
    X = np.concatenate([P,Q,T]) 
    optimized = scipy.optimize.minimize(profit, X, method='L-BFGS-B', constraints=cons) 

    if not optimized.success: 
     print "Solving Profits didn't work..." 
    else: 
     return optimized.x, N 

X, N = solve_profits() 
print "X: {0} N {1}".format(X,N) 
P,Q,T = X[0:3], X[3:6], X[6:9] 
rev = sum(P * Q * N) 
cost = sum(Q * N) 
profit = (rev-cost)*50 
print "N: {0}".format(N) 
print "P: {0}".format(P) 
print "Q: {0}".format(Q) 
print "T: {0}".format(T) 
print "profit = {0}".format(profit) 
+1

वहाँ एक कारण है कि आप अपने बाधा में गोल का उपयोग है का पालन करने की जरूरत नहीं है

scipy का अनुकूलन महान नहीं है? – Moritz

+0

और मुझे लगता है कि यह शिकायत करता है क्योंकि यह पी के तीन तत्वों के साथ सूची देखता है। 'Args = (पी,) ' – Moritz

+0

@ मॉरिट्स अभी भी दुर्भाग्य से – thefoxrocks

उत्तर

3

आप को अलग optimized_a और चलाने के लिए, आपको त्रुटि फेंक देता है देखते हैं, तो त्रुटि 8 - यह सकारात्मक व्युत्पन्न त्रुटि है।

दोनों बीएफजीएस और एसएलएसक्यूपी ढाल खोज विधियां हैं, जिसका अर्थ है कि वे अपना प्रारंभिक अनुमान लेते हैं, और ढाल और इसके व्युत्पन्न का मूल्यांकन करते हैं, और एक कदम उठाने के लिए सबसे अच्छी दिशा की तलाश करते हैं, हमेशा डाउनहिल पर कदम रखते हैं और जब परिवर्तन में रोकते हैं मान या तो आपके द्वारा निर्धारित सहिष्णुता के नीचे है या यह न्यूनतम तक पहुंचता है।

त्रुटि से पता चलता है कि (कम से कम आपके अनुमानित अनुमान पर), समस्या में एक मजबूत व्युत्पन्न नहीं है। आम तौर पर, एसक्यूएलएसपी उन समस्याओं पर सबसे अच्छा उपयोग किया जाता है जिन्हें वर्गों के योग के रूप में तैयार किया जा सकता है। शायद अधिक यथार्थवादी प्रारंभिक अनुमान की कोशिश करने में मदद मिलेगी। मैं निश्चित रूप से अधिकांश कोड को त्याग दूंगा और पहले अनुकूलित_ए के साथ एक न्यूनतम उदाहरण चलाऊंगा, और एक बार जब आप इसे काम कर लेते हैं तो बाकी का अनुसरण किया जा सकता है।

शायद एक गैर ग्रेडियेंट आधारित सॉल्वर काम करेगा, या समस्या के आकार और आपके पास पैरामीटर पर यथार्थवादी सीमाओं के आधार पर, एक वैश्विक अनुकूलन व्यावहारिक हो सकता है। यदि आप एक अच्छा व्युत्पन्न

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