2017-11-18 6 views
0

Ich habe das gleiche Problem wie in this question, aber möchte nicht nur eine, sondern mehrere Einschränkungen zum Optimierungsproblem hinzufügen.Wie fügt man differential_evolution mehrere Einschränkungen hinzu?

Also z.B. Ich möchte x1 + 5 * x2 mit den Einschränkungen zu maximieren, dass die Summe von x1 und x2 kleiner als 5 und x2 kleiner als 3 (unnötig zu sagen, dass das eigentliche Problem viel komplizierter ist und nicht nur in scipy.optimize.minimize wie diese geworfen, sondern nur dazu dient um das Problem zu veranschaulichen ...).

ich kann zu einem hässlichen Hack wie folgt aus:

from scipy.optimize import differential_evolution 
import numpy as np 

def simple_test(x, more_constraints): 

    # check wether all constraints evaluate to True 
    if all(map(eval, more_constraints)): 

     return -1 * (x[0] + 5 * x[1]) 

    # if not all constraints evaluate to True, return a positive number 
    return 10 

bounds = [(0., 5.), (0., 5.)] 

additional_constraints = ['x[0] + x[1] <= 5.', 'x[1] <= 3'] 
result = differential_evolution(simple_test, bounds, args=(additional_constraints,), tol=1e-6) 
print(result.x, result.fun, sum(result.x)) 

Dies wird

[ 1.99999986 3.  ] -16.9999998396 4.99999985882 

drucken, wie man erwarten würde.

Gibt es eine bessere/einfachere Möglichkeit, mehrere Einschränkungen hinzuzufügen als die Verwendung der eher "gefährlichen" eval?

+1

Sie nicht eval brauchen. Folgen Sie einfach dem in scipy.optimize.minimize Beispielen verwendeten Ansatz. Erstellen Sie Funktions- oder Lambda-Funktionen und bewerten Sie alles in Ihrem Test. Wenn Sie von simple_test aufgerufen werden, haben Sie bereits Zugriff auf x, das Sie dann übergeben können. (Wichtiger wäre die zugrundeliegende Theorie von DE, wenn dieser Ansatz tatsächlich ein guter ist) – sascha

+0

@sascha: Würde es Ihnen etwas ausmachen, eine Antwort mit etwas Code unten hinzuzufügen? Mehr als glücklich, es zu verbessern, wenn es nützlich ist. – Cleb

+0

Ich sehe keine Notwendigkeit, und ich bin immer noch nicht ganz davon überzeugt, dass das allgemeine Konzept funktioniert, aber ich bin ein bisschen voreingenommen in Bezug auf all diese global-opt Heuristiken. Ich sage nur, Sie erstellen Lambdas oder Funktionen wie [hier] (https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.minimize.html#scipy.optimize. minimieren). Natürlich würden Sie in Ihrem Fall diese von Ihrem '' 'simple_test''' nennen. Der einzige Vorteil ist jedoch die eval-freie Nutzung. Beispiel: '' 'check_0 = Lambda x: x [0] + x [1] <= 5'''. – sascha

Antwort

2

Ein Beispiel ist so etwas wie dieses ::

additional_constraints = [lambda(x): x[0] + x[1] <= 5., lambda(x):x[1] <= 3] 

def simple_test(x, more_constraints): 

    # check wether all constraints evaluate to True 
    if all(constraint(x) for constraint in more_constraints): 

     return -1 * (x[0] + 5 * x[1]) 

    # if not all constraints evaluate to True, return a positive number 
    return 10 
Verwandte Themen