2016-12-25 4 views
0

Ich habe mit dem folgenden Setup zu kämpfen.Constrained Lineare Optimierung Setup

Meine Daten sind wie folgt:

Group ID Wt  Coeff  Coeff*Wt 
------ --- ------ ------- ------- 
Group1 A 10.00% 1.00000  0.100 
Group1 B 10.00% 1.00000  0.100 
Group1 C 10.00% 3.00005  0.300 
Group2 D 10.00% 1.00000  0.100 
Group2 E 10.00% 1.00000  0.100 
Group2 F 10.00% 1.00000  0.100 
Group2 G 10.00% 7.80016  0.780 
Group3 H 10.00% 7.80485  0.780 
Group3 I 10.00% 1.00000  0.100 
Group3 J 10.00% 0.39529  0.040 



Objective function: Fmin = mimimize(sum of weights * coeff) 

ich folgende Einschränkungen implementieren müssen:

Sum of Weights*Coeff of Group1 = 20% of total minimized fmin 
Sum of Weights*Coeff of Group1 = 45% of total minimized fmin 
Sum of Weights*Coeff of Group1 = 35% of total minimized fmin 

und die folgenden Begrenzungsbedingungen:

Weights <=10% and Weights > 0.30% 

Und

Sum of weights = 100% 

Ich versuche, dies mit dem folgenden Code zu acomplish.

Ich weiß nicht, warum das nicht funktioniert ist:

from scipy.optimize import linprog 

c = [ 1.0000 ,1.0000 ,3.0001 ,1.0000 ,1.0000 ,1.0000 ,7.8002 ,7.8049 ,1.0000 ,0.3953 ] 

groupPerID = ['Group1','Group1','Group1','Group2','Group2','Group2','Group2','Group3','Group3','Group3'] 

groupList = ['Group1','Group2','Group3'] 

groupUpperBound = [0.20,0.45,0.40] 

A_eq_list = [] 
A_eq_list.append([1]*len(c)) 

b_eq_list = [1] 

for idx,currentGroup in enumerate(groupList): 

    matches = [i for i in range(len(groupPerID)) if groupPerID[i] == currentGroup] 

    currentGroupUB = groupUpperBound[idx] 

    x_list = [float(-1*currentGroupUB*coeff) for coeff in c] 

    for idx in matches: 
     x_list[idx] = float((1-currentGroupUB)*c[idx]) 

    A_eq_list.append(x_list) 

b_eq_list.extend([0]*len(groupUpperBound)) 
res = linprog(c, A_eq=A_eq_list, b_eq=b_eq_list,bounds =(0.003,0.1),options={'tol':0.05}) 
print(res) 

Kann jemand bitte darauf hinweisen, was Fehler, den ich machen werde?

+0

Wenn ich richtig verstehe, versuchen Sie, die Gewichte zu optimieren, zu korrigieren? Ihre Daten mit jedem Gewicht von 10% sind also nur ein Beispiel? – tBuLi

+0

Ja das ist richtig. Die Lösung ist im Excel-Solver optimiert. Ich möchte die Excel-Solver-Constraints in einen Python-Linprog umwandeln. – DrBug

+0

Es gibt ein zusätzliches Komma in '[0.20,0.45,0,40]' anstelle eines Punktes. Aber im Allgemeinen würde ich A_eq und b_eq drucken und überlegen, wo sie sich von den Ungleichungen unterscheiden, die Sie erwarten. – FTP

Antwort

1

Also implementierte ich es in meiner scipy Wrapper symfit, die sich um alle Kesselplatte Code kümmert. Es funktioniert jetzt, abgesehen von der Tatsache, dass ich Ihre Grenzen noch nicht auf die Gewichte umgesetzt habe. Ich denke jedoch, dass diese falsch sind, wie in Ihrer Frage angegeben, weil die einzige Möglichkeit, die Beschränkung zu erfüllen, dass das Gewicht 1 zusammenfassen sollte, ist, sie alle auf die obere Grenze von 0,1 zu setzen. Other than that, hier ist mein Versuch:

from symfit import parameters, Minimize, Variable, Eq 
import numpy as np 

# Make 10 weight parameters w_i to optimize 
weights = parameters(','.join('w_{}'.format(i) for i in range(1, 11))) 
c = np.array([1.0000, 1.0000, 3.0001, 1.0000, 1.0000, 1.0000, 7.8002, 7.8049, 1.0000, 0.3953]) 
f = Variable() 

for w_i in weights: 
    w_i.min = 0.003 
    w_i.max = 1.0 
    w_i.value = 0.1 

sum_of_group_1 = sum(c_i * w_i for c_i, w_i in zip(c, weights)[0:3]) 
sum_of_group_2 = sum(c_i * w_i for c_i, w_i in zip(c, weights)[3:7]) 
sum_of_group_3 = sum(c_i * w_i for c_i, w_i in zip(c, weights)[7:10]) 
# Function to minimize 
model = {f: sum_of_group_1 + sum_of_group_2 + sum_of_group_3} 

constraints = [ 
    Eq(0.20 * sum_of_group_1, 0.45 * sum_of_group_2), 
    Eq(0.20 * sum_of_group_1, 0.35 * sum_of_group_3), 
    Eq(sum(weights), 1) 
] 

fit = Minimize(model, constraints=constraints) 
fit.eval_jacobian = None # Workaround needed because f is just a scalar, not an array 
fit_result = fit.execute() 

print(fit_result) 
print(sum(fit_result.value(w) for w in weights)) # >>> 1.0 

Sie können here mehr in der Dokumentation lesen.

+0

Dank tBuli. Ich kämpfe jetzt, um zu überprüfen, ob das Optimierungsproblem, das ich zu lösen versuche, überhaupt machbar ist oder nicht. Ich werde zurückkommen und meine Erkenntnisse aktualisieren und auch Ihre Hilfe als endgültige Antwort akzeptieren. – DrBug

+0

Ich bin froh, dass ich helfen konnte! Ja, ohne zu viel darüber nachzudenken, würde ich denken, dass das System unterbestimmt ist und daher sind die Lösungen, wenn überhaupt, nicht einzigartig. Viel Glück! – tBuLi