Hướng dẫn lagrange multiplier python - trăn lagrange nhân hệ số

Tôi có chức năng sau đây mà tôi đang cố gắng tối ưu hóa điều đó có thể bị ràng buộc:

def damage(a, e, cr, cd):
    return 100*(1+a)*(1+e)*(1+cr*cd)

def constraint(a, e, cr, cd):
    return (100/0.466)*(a+e)+(100/0.622)*(2*cr+cd)

Khi giải quyết cho Lagrangian bằng tay, tôi nhận được đầu ra này:

import numpy as np
import sympy as smp
a, e, c, d, l = smp.symbols('a e c d l')
eq1 = smp.Eq(1/(1+a), (100/46.6)*l)
eq2 = smp.Eq(1/(1+e), (100/46.6)*l)
eq3 = smp.Eq(d/(1+c*d), (100/62.2)*2*l)
eq4 = smp.Eq(c/(1+c*d), (100/62.2)*l)
eq5 = smp.Eq((100/46.6)*(a+e)+(100/62.2)*(2*c+d) - 300, 0)

solution = np.array(smp.solve([eq1, eq2, eq3, eq4, eq5], [a, e, c, d, l]))
print(solution[0]/100)
print('Constraint', '{:,.0f}'.format(constraint(*(solution/100)[0][:-1])))
print('Max damage', '{:,.0f}'.format(float(round(damage(*(solution/100)[0][:-1])))))

.

Để có thể giải quyết vấn đề này thông qua cách tiếp cận số, tôi đã sửa đổi công thức của vấn đề bằng cách nêu rõ các ràng buộc riêng lẻ (tách các ràng buộc chính thành các ràng buộc nhỏ hơn). Tôi đã nêu rõ các mối quan hệ cần thiết giữa các biến và chỉ bị ràng buộc một trong các biến, sau đó xác định trạng thái của tất cả các biến khác.

# We first convert this into a minimization problem.
from scipy import optimize
def damage_min(x):
    return -100*(1+x[0])*(1+x[1])*(1+x[2]*x[3])

# next we define the constrains (equal to 0)
def constraints(x):
    c1 = x[0] - x[1]
    c2 = 2*x[2] - x[3]
    c3 = x[0]/x[3] - 0.466/0.622
    c4 = x[3] - 0.466
    return np.array([c1, c2, c3, c4])
cons = ({'type': 'eq',
         'fun' : constraints})

# We solve the minimization problem
x_initial = np.array([34.4658405015485, 34.4658405015485, 23.6481193219279, 47.2962386438559])
solution = optimize.minimize(damage_min, x_initial, constraints=cons)
print(solution.x)
print('Constraint',  '{:,.0f}'.format(constraint(*(solution.x))))
print('Max damage', '{:,.0f}'.format(float(round(damage(*(solution.x))))))

.

Câu hỏi của tôi là như sau. Làm thế nào tôi có thể tạo lại các kết quả tối ưu ở trên bằng cách tối ưu hóa số lượng một hàm duy nhất, ví dụ: hệ số nhân Lagrangian? Khi tôi cố gắng đặt cả hai chức năng vào một chức năng duy nhất, tôi nhận được đầu ra này.

const = 300
def lagrangian(a, e, cr, cd, lam):
    return -damage(a, e, cr, cd) + lam*(round(constraint(a, e, cr, cd)) - const)

def vector_lagrangian(x):
    return lagrangian(x[0], x[1], x[2], x[3], x[4])

x_initial = np.array([32.4658405015485, 34.4658405015485, 23.6481193219279, 47.2962386438559, 1])
solution = optimize.minimize(vector_lagrangian, x_initial)

fun: -2.140132414183526e+37
 hess_inv: array([[1, 0, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 1, 0],
       [0, 0, 0, 0, 1]])
      jac: array([0., 0., 0., 0., 0.])
  message: 'Optimization terminated successfully.'
     nfev: 119
      nit: 1
     njev: 17
   status: 0
  success: True
        x: array([ 6.90178344e+08,  6.51257507e+08,  9.75839219e+08,  4.87919645e+08,
       -5.08835272e+06])
'constraint': '680,080,111,963'

Các ràng buộc, trong trường hợp này, không được giữ và nó hội tụ ở mức tối thiểu cục bộ. Tại sao điều này là trường hợp? Là vấn đề gây ra bởi người giải quyết, chức năng cụ thể đang được tối ưu hóa, hoặc có một số lý do khác?

Đăng ngày 03 tháng 2 năm 2013 lúc 09:00 sáng | Thể loại: Tối ưu hóa | Tags: | categories: optimization | tags:

Cập nhật ngày 27 tháng 2 năm 2013 lúc 02:43 chiều

Bài đăng Matlab (chuyển thể từ http://en.wikipedia.org/wiki/lagrange_multipliers.)

Giả sử chúng ta tìm cách tối đa hóa hàm \ (f (x, y) = x + y \) theo ràng buộc rằng \ (x^2 + y^2 = 1 \). Hàm chúng ta tìm cách tối đa hóa là một mặt phẳng không giới hạn, trong khi ràng buộc là một vòng tròn đơn vị. Chúng tôi muốn giá trị tối đa của vòng tròn, trên mặt phẳng. Chúng tôi vẽ hai chức năng này ở đây.

import numpy as np

x = np.linspace(-1.5, 1.5)

[X, Y] = np.meshgrid(x, x)

import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca(projection='3d')

ax.plot_surface(X, Y, X + Y)

theta = np.linspace(0,2*np.pi);
R = 1.0
x1 = R * np.cos(theta)
y1 = R * np.sin(theta)

ax.plot(x1, y1, x1 + y1, 'r-')
plt.savefig('images/lagrange-1.png')

Hướng dẫn lagrange multiplier python - trăn lagrange nhân hệ số

1 Xây dựng chức năng tăng cường hệ số nhân Lagrange Construct the Lagrange multiplier augmented function

Để tìm mức tối đa, chúng tôi xây dựng hàm sau: \ (\ lambda (x, y; \ lambda) = f (x, y)+\ lambda g (x, y) \) trong đó \ (g (x, y) = x^2 + y^2 - 1 = 0 \), đó là hàm ràng buộc. Vì \ (g (x, y) = 0 \), chúng tôi không thực sự thay đổi chức năng ban đầu, với điều kiện là ràng buộc được đáp ứng!

import numpy as np

def func(X):
    x = X[0]
    y = X[1]
    L = X[2] # this is the multiplier. lambda is a reserved keyword in python
    return x + y + L * (x**2 + y**2 - 1)

2 Tìm các dẫn xuất một phần Finding the partial derivatives

Timea/cực đại của hàm tăng được đặt ở nơi tất cả các dẫn xuất một phần của hàm tăng cường bằng 0, tức là \ ( y = 0 \) và \ (\ partial \ lambda/\ partial \ lambda = 0 \). Quá trình giải quyết điều này thường là để phân tích các dẫn xuất một phần, và sau đó giải các phương trình kết quả không bị ràng buộc, có thể là phi tuyến.

Thay vì thực hiện sự khác biệt phân tích, ở đây chúng tôi phát triển một cách để xấp xỉ bằng số các dẫn xuất từng phần.

def dfunc(X):
    dLambda = np.zeros(len(X))
    h = 1e-3 # this is the step size used in the finite difference.
    for i in range(len(X)):
        dX = np.zeros(len(X))
        dX[i] = h
        dLambda[i] = (func(X+dX)-func(X-dX))/(2*h);
    return dLambda

3 Bây giờ chúng tôi giải quyết các số không trong các dẫn xuất một phần Now we solve for the zeros in the partial derivatives

Hàm chúng tôi xác định ở trên (DFUNC) sẽ bằng 0 ở mức tối đa hoặc tối thiểu.Hóa ra có hai giải pháp cho vấn đề này, nhưng chỉ một trong số chúng là giá trị tối đa.Giải pháp nào bạn nhận được phụ thuộc vào dự đoán ban đầu được cung cấp cho người giải quyết.Ở đây chúng ta phải sử dụng một số phán đoán để xác định mức tối đa.

from scipy.optimize import fsolve

# this is the max
X1 = fsolve(dfunc, [1, 1, 0])
print X1, func(X1)

# this is the min
X2 = fsolve(dfunc, [-1, -1, 0])
print X2, func(X2)

>>> ... >>> [ 0.70710678  0.70710678 -0.70710678] 1.41421356237
>>> ... >>> [-0.70710678 -0.70710678  0.70710678] -1.41421356237

4 Tóm tắt Summary

Các sơ đồ ba chiều trong matplotlib khó khăn hơn một chút so với trong MATLAB (trong đó mã gần giống như các ô 2D, chỉ là các lệnh khác nhau, ví dụ: Plot Vs Plot3).Trong matplotlib, bạn phải nhập các mô -đun bổ sung theo đúng thứ tự và sử dụng phương pháp định hướng đối tượng để vẽ đồ thị như được hiển thị ở đây.

Bản quyền (c) 2013 của John Kitchin.Xem giấy phép để biết thông tin về sao chép.

Nguồn chế độ org