2016-07-13 26 views
1

Angenommen, ich möchte die folgende Einschränkung lösen: y == max(x, 0). Was ich mir vorstellen könnte, ist Folgendes zu kodieren (in der z3py-Schnittstelle): If(x > 0, y == x, y == 0). Meine Fragen waren:Kann Z3 effektiv Einschränkungen mit einer maximalen Operation lösen?

  1. Z3 intern gehen den obigen Ausdruck in zwei Einschränkungen zu übersetzen: x > 0 /\ y == x und x <= 0 /\ y == 0, und dann nimmt ein OR von ihnen und kehrt saß, wenn eine der beiden Bedingungen erfüllbar?
  2. Wenn ja, scheint die Anzahl der Einschränkungen exponentiell mit der Anzahl der max Operationen zu wachsen. Ich habe ein System mit über 100 max. Gibt es eine effiziente Lösung, entweder in Z3 oder in anderen Lösungsmethoden?

Vielen Dank!

Antwort

1

Wenn alle Ihre maximale Operation in einem Kontext des Formulars y > max(x, 0) erscheint, würde ich sie als (and (> y x) (> y 0)) (SMT-LIB), die keine Verzweigung hat codieren. Ich bin nicht sicher, was die Syntax dafür ist, die Python-Schnittstelle verwendend.

+0

Dies ist ein schöner Trick! Aber wie würdest du 'y == max (x, 0)' tun? Gibt es eine allgemeine Möglichkeit, 'max' effektiv ohne eine Verzweigung auszudrücken? – queeten

+0

Der prägnanteste Weg ist, wie Nikolaj sagte: 'If (x> y, x, y)'. Ich bezweifle, dass man allgemein sagen kann, ob der Suchraum verdoppelt wird, indem man solche Einschränkungen einführt. Es hängt vom Problem und den Interna des Solvers ab. Wenn 'x> y 'von anderswo im Problem bekannt ist, wird Z3' If (x> y, x, y)' mit nur 'x' oder 'y' ersetzen und es wird keine Verzweigung geben. Wenn 'x> y' nicht aus dem Kontext bestimmt werden kann, muss möglicherweise verzweigt werden. –

+0

In dieser Art von Situation kann das Wissen über die Löser und Algorithmen Ihnen helfen zu hypothetisieren, was die Auswirkung auf die Leistung sein wird. Die Gesamtleistung eines Solvers wie Z3 ist jedoch kompliziert und hängt von vielen Faktoren ab, die gegeneinander abgewogen werden. In der Regel müssen Sie Ihre Hypothesen mit relevanten Benchmarks testen, um festzustellen, ob sie für Ihre spezifischen Probleme von Interesse sind. –

2

Mit der Python-Schnittstelle können Sie definieren:

def mymax(x,y): 
    return If(x > y, x, y) 

Dies bedeutet nicht eine exponentielle Anzahl von Einschränkungen erzeugen.

In vielen Situationen reicht es aus, nur eine Seite der Ungleichungen zu erzwingen, die durch max. In diesen Fällen um eine frische Variable max_x_y einführen und

max_x_y >= x, max_x_y >= y 

behaupten Wenn benötigen Sie auch, dass max_x_y < = max (x, y), dann ist der Standardansatz mit Z3 mymax anstelle der Einführung von neuen Variablen zu verwenden.

+0

Mit 'mymax', wenn ich' y' ausdrücken möchte, ist das Maximum zwischen 'x' und' 0', ich könnte 'lösen (y == mymax (x, 0))', was cool ist. Aber übersetzt Z3 intern meinen Maxmax in zwei Constraints und * OR * sie zusammen und kehrt zurück, wenn beides erfüllbar ist? If so, obwohl 'If' es so aussehen lässt, als ob es nur eine Einschränkung wäre, behandelt Z3 es wie zwei Nebenbedingungen und erhöht somit die Komplexität exponentiell? – queeten

+0

@squeeten Die Laufzeit kann je nach Struktur des Problems exponentiell ansteigen oder nicht. Siehe die Kommentare zu meiner Antwort. Korrigiere mich, wenn ich hier falsch liege, Nikolaj. Interessanter Punkt in Bezug auf die Verwendung nur einer Seite der Ungleichung. –