2015-06-28 5 views
2

Я хочу решить некоторую систему в виде матриц, используя linalg, но полученные решения должны суммировать до 1. Например, предположим, что существует 3 неизвестных, x, y, z. После решения системы их значения должны суммироваться до 1, например .3, .5, .2. Может кто-нибудь, пожалуйста, скажите мне, как я могу это сделать?Решение системы с использованием linalg с ограничениями

В настоящее время я использую что-то вроде result = linalg.solve(A, B), где A и B являются матрицами. Но это не возвращает решения в диапазоне [0, 1].

+3

В документах 'linalg.solve' используется для вычисления« точного »решения' x', из четко определенного, то есть полного ранга, линейного матричного уравнения 'ax = b'. Будучи линейным, может быть не более одного решения. Если найденное решение не суммируется до 1, то добавление дополнительного ограничения не даст никакого решения. – unutbu

+0

Спасибо, я понял, но нет ли альтернативы для linalg, которая может считать такое ограничение? – Dania

ответ

3

Per the docs,

linalg.solve используется для вычисления "точного" решения, x, из хорошо определенных, то есть, полного ранга, линейного матричного уравнения ax = b.

Будучи линейным, может быть не более одного решения. Если найденное решение не составляет , сумма до 1, то добавление дополнительного ограничения не даст никакого решения.

Однако, вы можете использовать scipy.optimize.minimize , чтобы найти точку на ограничении плоскости, минимизирует количество ||Ax-b||^2:

def f(x): 
    y = np.dot(A, x) - b 
    return np.dot(y, y) 

cons = ({'type': 'eq', 'fun': lambda x: x.sum() - 1}) 
res = optimize.minimize(f, [0, 0, 0], method='SLSQP', constraints=cons, 
         options={'disp': False}) 

Например, если эта система уравнений

import numpy as np 
import numpy.linalg as LA 
import scipy.optimize as optimize 

A = np.array([[1, 3, 4], [5, 6, 9], [1, 2, 3]]) 
b = np.array([1, 2, 1]) 
x = LA.solve(A, b) 

решение не добавлять до 1:

print(x) 
# [-0.5 -1.5 1.5] 

Но вы могли бы попытаться минимизировать f:

def f(x): 
    y = np.dot(A, x) - b 
    return np.dot(y, y) 

при ограничении cons:

cons = ({'type': 'eq', 'fun': lambda x: x.sum() - 1}) 
res = optimize.minimize(f, [0, 0, 0], method='SLSQP', constraints=cons, 
         options={'disp': False}) 
xbest = res['x'] 
# array([ 0.30000717, 1.89998823, -1.1999954 ]) 

xbest суммы до 1:

print(xbest.sum()) 
1 

Разницы A·xbest - b является:

print(np.dot(A, xbest) - b) 
# [ 0.19999026 0.10000663 -0.50000257] 

и сумма квадратов разности, (также вычислимым, как f(xbest)) является:

print(res['fun']) 
0.30000000014542572 

Ни одно другого значения й не уменьшает эту величины больше, при удовлетворении ограничение.

0

Можно добавить строку, состоящую из единиц А и добавьте к B. После этого использования результат = linalg.lstsq (A, B) [0]

Или вы можете заменить одну из строк, которое по строка, состоящая из единиц, также заменяет значение в B на один в той же строке. Затем используйте result = linalg.Решение (A, B)