Ich möchte eine Anzahl von (numpy-) Arrays gewichtet miteinander addieren und dadurch möglichst "nahe" an gegebene Zielwerte kommen.
Also mal als kleines Beispiel:
A1 * [0, 1, 1, 1] + A2 * [0, 0, 0, 4] + A3 * [0, 0, 2, 5] === [0, 1, 4, 4]
Die Faktoren A1, A2 und A3 dürfen nur Werte zwischen 0 und 1 annehmen. Ferner wird die Güte der Anpassung durch die Summe der Beträge der Differenzen an allen Punkten bestimmt.
An diesem Problem sitze ich nun schon wirklich lange und würde mich wirklich über Anregungen freuen-
Hier meine bisherigen Ansätze:
ILP-Problem mit pulp:
Code: Alles auswählen
ySoll = np.array([0., 1., 4., 4.])
yValues = np.array([[0, 1, 1, 1],
[0, 0, 0, 4],
[0, 0, 2, 5]
], float)
num = yValues.shape[0]
numYValues = yValues.shape[1]
A = []
for i in range(num):
A.append(LpVariable("A%s"%i, lowBound = 0, upBound = 1, cat= LpContinuous)) # amplitude variables
prob = LpProblem("combination", LpMinimize)
prob += lpSum([ySoll[j] - lpSum(A[i]*yValues[i][j] for i in range(num)) for j in range(numYValues)] )
for j in range(numYValues):
prob += lpSum(A[i]*yValues[i][j] for i in range(num)) == ySoll[j], "Equal_%s"%j
prob.writeLP("combinate.lp")
prob.solve()
print "Anpassung ", value(prob.objective)
resY = sum(A[i].varValue * yValues[i] for i in range(num))
print "Ziel: ", ySoll
print "Erreicht: ", resY
Dann habe ich scipy.optimize.minimize versucht.
Code: Alles auswählen
def peval(p, X):
return np.dot(X, p)
def objective(p, y, X):
return np.sum( np.fabs(y - peval(p, X)) )
#return np.sum( (y - peval(p, X)) ** 2 )
yValues = np.array([[0, 1, 4, 4],
[1, 0, 0, 4],
[4, 1, 1, 4],
[4, 1, 1, 4]
], float)
ySoll = np.array([0, 1, 4, 4])
p0 = np.zeros(4)
cons = {
'type': 'eq',
'fun': np.sum,
}
bnds = ((0, None), (0, None), (0, None), (0, None))
res = optimize.minimize(
objective, p0, args=(ySoll, yValues),
method='SLSQP', constraints=cons)
Herzlichen Dank!