Optimierung mit mehreren Variablen und Constraints
Verfasst: Dienstag 28. April 2020, 14:22
Hallo zusammen,
Für einen Kurs an meiner Uni muss ich eine Optimierungsaufgabe mithilfe von scipy/numpy und matplotlib lösen.
Allerdings haben wir die Optimierung von Funktionen bisher nur mit einzelnen Variablen + Parametern gelöst, jedoch nicht
mit mehreren Variablen + Parametern.
Ebenfalls ist das meine erste richtige Anwendung von Python, ich bin also noch ziemlich unerfahren...
Ich habe jetzt bereits einige Stunden herumprobiert, komme jedoch einfach nicht weiter...
Die Modellparameter lauten y = 100 , z = 1.03 , n = 1.02 und beta = 0.95
Die Entsprechende Funktion lautet U(c1,c2,c3) = c1 ^ (1/2) + beta * c2 ^ (1/2) + beta ² * (c3 ^ (1/2))
Mit den Constraints: c1 + q = y
c2 <= (n/z) * q
c3 = (n²/z²) * q - (n/z) * c2
Hierbei stehen c1, c2 und c3 für den Konsum sowie q für das gesparte Kapital.
Ziel der Aufgabe ist es, unter den Nebenbedingungen die Funktion zu maximieren bzw. die maximierenden Variablen c1,c2,c3 und q zu ermitteln. Da bereits def U(sol, params) vorgegeben war, habe ich die 4 Variablen sol zugewiesen: (sol[0] steht für c1, sol[1] für c2, sol[2] für c3 und sol[3] für q.
Anschließend soll die Funktion geplottet werden, doch hier erhalte ich immer den selben Fehlerterm
Und auch der entsprechende Plot ist lediglich eine gerade Linie...
Ich wäre wirklich froh wenn mir jemand sagen kann wo mein Fehler liegt!
Liebe Grüße,
Lanceister
Für einen Kurs an meiner Uni muss ich eine Optimierungsaufgabe mithilfe von scipy/numpy und matplotlib lösen.
Allerdings haben wir die Optimierung von Funktionen bisher nur mit einzelnen Variablen + Parametern gelöst, jedoch nicht
mit mehreren Variablen + Parametern.
Ebenfalls ist das meine erste richtige Anwendung von Python, ich bin also noch ziemlich unerfahren...
Ich habe jetzt bereits einige Stunden herumprobiert, komme jedoch einfach nicht weiter...
Code: Alles auswählen
# Write all import statements here
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
Code: Alles auswählen
# Define model parameters here
params = np.array([100,1.03,1.02,0.95])
Mit den Constraints: c1 + q = y
c2 <= (n/z) * q
c3 = (n²/z²) * q - (n/z) * c2
Hierbei stehen c1, c2 und c3 für den Konsum sowie q für das gesparte Kapital.
Ziel der Aufgabe ist es, unter den Nebenbedingungen die Funktion zu maximieren bzw. die maximierenden Variablen c1,c2,c3 und q zu ermitteln. Da bereits def U(sol, params) vorgegeben war, habe ich die 4 Variablen sol zugewiesen: (sol[0] steht für c1, sol[1] für c2, sol[2] für c3 und sol[3] für q.
Code: Alles auswählen
def U(sol,params):
"""
Returns the lifetime utility of a young person as a function of his consumption and money holdings (sol)
as well as the parameters of the model (params)
"""
y, z, n, beta = params
return - (sol[0] ** (1/2) + beta * sol[1] ** (1/2) + (beta ** 2) * sol[2] ** (1/2))
# Write your code here
def V(params):
"""
Returns the solution to the optimization problem as a function of the parameters of the model
"""
y, z, n, beta = params
cons = ({'type': 'eq', 'fun': lambda sol: sol[0] + sol[3] - y},
{'type': 'ineq', 'fun': lambda sol: sol[1] - (n/z) * sol},
{'type': 'eq', 'fun': lambda sol: sol[2] - ((n ** 2)/(z ** 2)) * sol[3] + (n/z) * sol[1]})
bnd = [(0,np.inf),(0,np.inf),(0,np.inf),(0,np.inf)]
lös = minimize(lambda sol, params: -U(sol,params), x0=[25,25,25,25], method='SLSQP', args=params, constraints=cons, bounds=bnd, options={'disp': True,'ftol': 1e-10})
return lös
# Write your code here
Code: Alles auswählen
z_grid = np.linspace(1.0,3.0,100)
q_star = np.zeros(len(z_grid))
c_1 = np.zeros(len(z_grid))
c_2 = np.zeros(len(z_grid))
c_3 = np.zeros(len(z_grid))
u = np.zeros(len(z_grid))
for i, z in enumerate(z_grid):
params[1] = z
q_star[i] = V(params).x
c_1[i] = params[0] - q_star[i]
c_2[i] = q_star[i] * params[2] / params[1]
c_3[i] = ((params[2] ** 2) / (params[1] ** 2)) * q_star[i] - (params[2] / params[1]) * ((V(params).x[1] * q_star[i]))
u[i] = U(q_star,params)
c = c_1 + c_2 + c_3
Iteration limit exceeded (Exit mode 9)
Current function value: 14.262500001558012
Iterations: 101
Function evaluations: 1262
Gradient evaluations: 98
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
TypeError: only size-1 arrays can be converted to Python scalars
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
<ipython-input-196-1e981037e672> in <module>
8 for i, z in enumerate(z_grid):
9 params[1] = z
---> 10 q_star[i] = V(params).x
11 c_1[i] = params[0] - q_star[i]
12 c_2[i] = q_star[i] * params[2] / params[1]
ValueError: setting an array element with a sequence.
Code: Alles auswählen
plt.figure(figsize=(9,6))
plt.plot(z_grid,c_1,label=r'$c_1$')
plt.plot(z_grid,c_2,label=r'$c_2$')
plt.plot(z_grid,c_3,label=r'$c_3$')
plt.ylabel(r'Real consumption, c',fontsize='12')
plt.xlabel(r'Money growth rate, $z$',fontsize='12')
plt.legend(loc='best',fontsize='12')
plt.show()
Liebe Grüße,
Lanceister