Nie sądzę, że można użyć nnls
bezpośrednio jako Fortran code to wywołania nie pozwalają na dodatkowe ograniczenia. Jednakże ograniczeniem, że środki równanie można wprowadzać jako trzeciego równania więc przykładowy system ma postać,
60 x1 + 90 x2 + 120 x3 = 67.5
30 x1 + 120 x2 + 90 x3 = 60
x1 + x2 + x3 = 1
Jak to jest układ równań liniowych, dokładne rozwiązanie może być uzyskane od x=np.dot(np.linalg.inv(A),b)
, dzięki czemu x=[0.6875, 0.3750, -0.0625]
. Wymaga to, aby było ujemne. Dlatego nie ma dokładnego rozwiązania, gdy x
jest pozytywny dla tego problemu.
wynoszący około rozwiązania, w którym x
jest ograniczony jest pozytywny, to można uzyskać stosując
import numpy as np
from scipy.optimize import nnls
#Define minimisation function
def fn(x, A, b):
return np.sum(A*x,1) - b
#Define problem
A = np.array([[60., 90., 120.],
[30., 120., 90.],
[1., 1., 1. ]])
b = np.array([67.5, 60., 1.])
x, rnorm = nnls(A,b)
print(x,x.sum(),fn(x,A,b))
, zawierające x=[0.60003332, 0.34998889, 0.]
z x.sum()=0.95
.
Myślę, że jeśli chciał bardziej ogólne rozwiązanie w tym ograniczeń Podsumowując, trzeba by użyć minimalizacji z ograniczeniami/wyraźnych granic w następującej formie,
import numpy as np
from scipy.optimize import minimize
from scipy.optimize import nnls
#Define problem
A = np.array([[60, 90, 120],
[30, 120, 90]])
b = np.array([67.5, 60])
#Use nnls to get initial guess
x0, rnorm = nnls(A,b)
#Define minimisation function
def fn(x, A, b):
return np.linalg.norm(A.dot(x) - b)
#Define constraints and bounds
cons = {'type': 'eq', 'fun': lambda x: np.sum(x)-1}
bounds = [[0., None],[0., None],[0., None]]
#Call minimisation subject to these values
minout = minimize(fn, x0, args=(A, b), method='SLSQP',bounds=bounds,constraints=cons)
x = minout.x
print(x,x.sum(),fn(x,A,b))
co daje x=[0.674999366, 0.325000634, 0.]
i x.sum()=1
. Od minimalizacji suma jest poprawna, ale wartość x
nie jest całkiem odpowiednia z np.dot(A,x)=[ 69.75001902, 59.25005706]
.
W twoim pierwszym bloku kodu 'print (x, x.sum(), fn (x, A, b))' skąd pochodzi 'fn'? – neversaint
Niestety, powinno być fn z drugiego przykładu (Ax-b). Poprawiłem. –
Dzięki. Staram się spojrzeć na moje inne powiązane [pytanie] (http://stackoverflow.com/questions/33404908/best-way-to-scale-the-matrix-variables-in-scipy-linear-programming-scheme)? – neversaint