Solve argmin_x || Ax - b ||_2 for x>=0.
如果我寻求,可以采用哪种替代方法
严格非零解(即x> 0)?
这是我使用Scipy的NNLS的LP代码:
import numpy as npfrom numpy import arrayfrom scipy.optimize import nnlsdef by_nnls(A=None,B=None): """ linear programming by NNLS """ #print "NOF row = ",A.shape[0] A = np.nan_to_num(A) B = np.nan_to_num(B) x,rnorm = nnls(A,B) x = x / x.sum() # print repr(x) return xB1 = array([ 22.133,197.087,84.344,1.466,3.974,0.435,8.291,45.059,5.755,0.519,0.,30.272,24.92,10.095])A1 = array([[ 46.35,80.58,48.8,80.31,489.01,40.98,29.98,44.3,5882.96],[ 2540.73,49.53,26.78,30.49,48.51,20.88,19.92,21.05,19.39],[ 30.95,1482.24,100.48,35.98,35.1,38.65,31.57,87.38,33.39],[ 15.99,223.27,655.79,1978.2,18.21,20.51,19.,16.19,15.91],[ 16.49,20.56,19.08,18.65,4568.97,20.7,17.4,17.62,25.51],[ 33.84,26.58,18.69,40.88,19.17,5247.84,29.39,25.55,18.9 ],[ 42.66,83.59,99.58,52.11,46.84,64.93,43.8,7610.12,47.13],[ 41.63,204.32,4170.37,86.95,49.92,87.15,51.88,45.38,42.89],[ 81.34,60.16,357.92,43.48,36.92,39.13,1772.07,68.43,38.07]])
用法:
In [9]: by_nnls(A=A1,B=B1)Out[9]:array([ 0.70089761,0.06481495,0.14325696,0.01218972,0.02125942,0.01906576,0.03851557]
注意上面的零解决方案.
解决方法 您应该质疑是否真的需要x> 0而不是x> = 0.通常后一个约束用于稀疏结果,并且x中的零是理想的.除此之外,约束实际上是等同的.如果约束x严格大于零,那么0将变为非常小的正数.如果可以通过更大的值来改善溶液,那么您也可以使用原始约束来获得这些值.
让我们通过定义以下优化来证明这一点:解决argmin_x || Ax – b || _2 for x> = eps.而eps> 0这也满足x> 0.查看不同eps的结果x,我们得到:
你看到的是,对于商城eps,目标函数几乎没有任何差异,x [1](原始解决方案中的0之一)越来越接近0.
因此,从x> 0到x> = 0的无穷小步骤几乎不改变溶液中的任何东西.出于实际目的,它们完全相似.但是,x> = 0的优势在于,您可以获得实际的0而不是1.234e-20,这有助于简化解决方案.
以下是上图的代码:
from scipy.optimize import fmin_cobylaimport matplotlib.pyplot as pltdef by_minimize(A,B,eps=1e-6): A = np.nan_to_num(A) B = np.nan_to_num(B) def objective(x,A=A,B=B): return np.sum((np.dot(A,x) - B)**2) x0 = np.zeros(A.shape[1]) x = fmin_cobyla(objective,x0,lambda x: x-eps) return x / np.sum(x),objective(x)results = []obj = []e = []for eps in np.logspace(-1,-6,100): x,o = by_minimize(A=A1,B=B1,eps=eps) e.append(eps) results.append(x[1]) obj.append(o)h1 = plt.semilogx(e,results,'b')plt.ylabel('x[1]',color='b')plt.xlabel('eps')plt.twinx()h2 = plt.semilogx(e,obj,'r')plt.ylabel('objective',color='r')plt.yticks([])
附:我试图实现x>在我的代码中使用lambda x的0约束:[1如果i> 0,则为x中的i为-1,但是它无法收敛.
总结以上是内存溢出为你收集整理的为Python的Scipy线性编程找到严格大于零的解决方案的方法全部内容,希望文章能够帮你解决为Python的Scipy线性编程找到严格大于零的解决方案的方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)