np.linalg.lstsq
如果ax> = b,那么
scipy.optimize.nnls
(= ax -b)的所有元素应为正(或0)。相反,我得到的是,差异的某些元素是负面的。有任何功能可用于强制AX> = B约束? (为何必须强加这种约束的背景是A编码5种不同食物(列)中的维生素/矿物质/大量营养素(行),而B是必须消耗的每种营养素的总量避免营养缺乏。)
i我描述了它在casadi
中解决了问题,但似乎是不可行的。
import numpy as np
import scipy
v1 = np.array([0.00000961,0.0000011,0.0000011,0.000015,0.00000884,0.00000286,0,0.00000006,0,0.000196,0,0.0000071,0.000000023,0.000131,0.00038,0,0,0.00000161,0,0,0.0000069,0.00027,0.000005,0,0,0.00054,0.00475,0.000000002,0.00036,0.0000032,0,0,0.033,0.0015,0.02,0.00052,0.207]).T
v2 = np.array([0,0.0000064,0.00000135,0.000121,0.0000177,0.00000348,0,0.00000006,0,0,0,0.0000833,0,0.000525,0.00062,0,0,0.0000114,0,0,0.0000458,0.00168,0.0000193,0,0,0.00376,0.00705,0.000000072,0.00018,0.0000327,0,0,0.085,0.492,0.258,0.0628,0.161]).T
v3 = np.array([0,0.000009,0.00000193,0.0000196,0.00000899,0,0,0.00000444,0,0,0,0.0000021,0.000000056,0.000664,0.00123,0,0,0.00000841,0,0,0.0000502,0.00171,0.0000106,0,0,0.00352,0.0148,0.000000032,0.00005,0.0000365,0,0,0.155,0.0142,0.216,0.00366,0.624]).T
v4 = np.array([0,0.00000763,0.00000139,0.00000961,0.0000135,0.00000119,0,0.00000056,0,0,0,0,0,0,0.00054,0,0,0.00000626,0,0,0.0000472,0.00177,0.0000492,0,0,0.00523,0.00429,0,0.00002,0.0000397,0,0,0.106,0.069,0.169,0.0122,0.663]).T
v5 = np.array([0.00000241,0.00000113,0.00000347,0.0000118,0.0000037,0.00000147,0,0.00000062,0,0.000934,0,0,0,0.000005,0.00254,0,0,0.00000053,0,0,0.000016,0.00033,0.0000092,0,0,0.00055,0.00348,0,0.00053,0.0000039,0,0,0.041,0.0149,0.0292,0.00178,0.0442]).T
b = np.array([0.00657,0.00876,0.00949,0.1168,0.0365,0.01241,0.000219,0.00292,0,0.657,0.000146,0.1095,0.000876,4.015,8.76,16.79,0.0002555,0.00657,0.0292,0.001095,0.0584,3.066,0.01679,0.0003285,0,5.11,24.82,0.0004015,10.95,0.0803,0,0.00219,204.4,569.4,365,146,2007.5]).T
A = np.column_stack((v1,v2,v3,v4,v5))
result = scipy.optimize.nnls(A,b)
x = result[0][:,None] # Force to be column array; the A @ x step doesn't seem to work if I don't do this
# https://stackoverflow.com/questions/64869851/converting-numpy-array-to-a-column-vector
lsq = A @ x # result is a column vector
diff = lsq.T - b # b is still technically a row vector, so lsq has to be converted back to a row vector for dimensions to match
print(diff)
报告
diff
当我拿出a @ x> = b约束时,我会在您的问题中获得与代码相同的解决方案。
import casadi as cas
opti = cas.Opti()
x = opti.variable(5)
opti.minimize(cas.sumsqr(A @ x - b))
opti.subject_to(A @ x >= b)
opti.subject_to(x >= 0)
opti.solver('ipopt')
sol = opti.solve()
x_sol = np.array(sol.value(x))
print(np.round(x_sol, 6))
替换为EXIT: Converged to a point of local infeasibility. Problem may be infeasible.
然后找到解决方案。
您可能需要重新审视您的约束,并确认它们是否正确并有意义。