Сципи оптимизировать просто не имеет дело с границей - PullRequest
0 голосов
/ 29 февраля 2020

Я пытаюсь решить следующую проблему для многих различных значений K:

\max_{p_2\sqrt{1-x_1} + (1-p_2)\sqrt{1-x_2}\geq K} p_1 \sqrt{x_1} + (1-p1) \sqrt{x_2}

Я пытаюсь использовать scipy optimize для большей универсальности ( на каком-то этапе я хотел бы иметь возможность изменять функции).

Это мой код:

import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from scipy import optimize

n=10

p1 = 0.2
p2 = 0.3
orig = (0,0)
endw = (1,1)

def U1(x):
    return p1*(x[0])**0.5 + (1-p1)*(x[1])**0.5
def U2(x):
    return p2*(1-x[0])**0.5 + (1-p2)*(1-x[1])**0.5


itervals = np.linspace(endw, orig, n)
utvals = np.array([U2(vec) for vec in itervals])
parvals = np.zeros((2, len(utvals)))

for it in range(len(utvals)):
    def obj(x):
        return -U1(x)
    def constr(x):
        return -U2(x)+utvals[it]
    con = {'type': 'eq', 'fun': constr}
    res = optimize.minimize(obj, itervals[it], method='SLSQP', constraints=con)
    parvals[:, it] = res['x']
    print(constr(parvals[:,it]), utvals[it])

Однако, когда я проверяю, соблюдается ли ограничение, я получаю отрицательные значения constr(parvals[:,it]) в приведенном выше коде, и если я поверну ограничение на

    def constr(x):
        return U2(x)-utvals[it]

, я получу положительные значения constr(parvals[:,it]). Почему?

Я имею в виду, мое первоначальное предположение (содержащееся в itervals) всегда возвращает 0 для ограничения. Поэтому всегда можно достичь 0, почему это иногда положительно, а иногда отрицательно?

1 Ответ

0 голосов
/ 29 февраля 2020

Варьируя K, мы находим различные пары решений (x1, x2). Решая задачу максимизации с помощью множителя Лагранжа (накладывая условия первого порядка), тривиально видеть, что x2 должен быть функцией от x1, т. Е. Этот код дает требуемое соотношение:

Psi = (p1/p2*(1-p2)/(1-p1))**2
def realline(x1):
    return x1/(Psi+(1-Psi)*x1)

Это легко увидеть что, определяя ограничение с правым знаком, решение совпадает почти везде:

    def constr(x):
        return U2(x)-utvals[it]
    con = {'type': 'ineq', 'fun': constr}
...