2017-07-06 4 views
6

Ich versuche, ein grundlegendes Beispiel für die Optimierung mit loco zu tun.Wie grundlegende Optimierung mit Hilfe der Lok

Ich habe einen Kostenvektor, dessen Index dem ganzzahligen Wert einer Anzahl von Slots entspricht und möchte die Summe der Kosten für eine bestimmte Teilmenge der Slots minimieren.

Bitte sehen Sie meinen Versuch unten, der nicht funktioniert, weil es keine "Verbindung" zwischen den ausgewählten Steckplätzen und den Kosten gibt. Diese

(def costs [10 10 20 20 30 30 40 40 10 10]) 

(let [slot-vars (for [i (range 5)] ($in [:slot i] 1 10)) 
     cost-vars (for [i (range 10)] ($in [:cost i] 10 40))] 
    (solution 
    (concat 
    slot-vars 
    cost-vars 
    [($distinct (for [i (range 5)] [:slot i]))] 
    (for [i (range 5)] 
     ($= [:cost i] (get costs i)))) 
    :minimize (apply $+ (for [i (range 5)] [:slot i])))) 
+0

Dieses wie ein Knapsackproblems minimieren klingt. Sie können ein Maximieren, aber kein Minimieren. Würde sich möglicherweise direkt mit der Schoko-Bibliothek beschäftigen müssen, um dies zu tun. – Mike

Antwort

2

Erstens bin ich mir nicht ganz sicher, ob ich den Sinn dieses Problems verstehe, denn klar ist die Lösung, nur die 5 kleinsten Werte in der Liste zu nehmen. Aber wenn Sie wollen, dass die Lok es macht, stimme ich zu, dass die Rucksackbeschränkung ein praktisches Werkzeug dafür ist. Im Gegensatz zu dem, was Mike in seinem Kommentar gesagt hat, sehe ich kein Hindernis bei der Verwendung von Rucksack zur Minimierung. Lassen Sie die Gewichte alle 1 sein, und erzwingen Sie, dass die Gewichte zu 5 addieren, um 5 aus den 10 Slots auszuwählen. Ich habe die Variable [:include i] verwendet, um anzugeben, ob Slot i in die Teilmenge eingeschlossen werden soll (1 für wahr und 0 für falsch). Wir wollen das Skalarprodukt des Vektors von: include-Variablen und dem Kostenvektor minimieren.

(def costs [10 10 20 20 30 30 40 40 10 10]) 
(def weights (repeat 10 1)) 

(def include-vars (for [i (range 10)] [:include i])) 
(def include-constraints (for [i (range 10)] ($in [:include i] 0 1))) 

(def model 
    (concat 
    include-constraints 
    [($knapsack weights costs include-vars 5 :total) 
    ($in :total 0 (apply + costs))])) 

(solution model :minimize :total) 

Das Ergebnis ist:

{[:include 4] 0, [:include 6] 0, [:include 9] 1, [:include 1] 1, [:include 3] 0, [:include 8] 1, :total 60, [:include 0] 1, [:include 7] 0, [:include 2] 1, [:include 5] 0} 
+0

Danke für Ihre Antwort. Das Beispiel dient nur der Veranschaulichung. In meinem realen Anwendungsfall unterliegen die Vars zahlreichen anderen Einschränkungen. – mac

2

ist nicht die Antwort, aber ich hoffe, es könnte Punkt in einer Richtung helfen, die helfen könnten. Es klingt wie ein Rucksackproblem?

Sie können den max mit finden:

(def slots (for [i (range 10)] (keyword (str "slot-" i)))) 

(solution 
    (concat 
    (for [s slots] ($in s 0 1)) 
    [($in :total-weight 10 60) 
    ($in :total-value 5 5) 
    ($knapsack [10 10 20 20 30 30 40 40 10 10] 
       (repeat 10 1) 
       slots :total-weight :total-value)])) 

Vorausgesetzt, dass Sie nur 5 Slots haben können.

Könnte man möglicherweise eine minimierende Version schreiben, indem man sich den Quellcode ansieht und direkt mit der Choco-Bibliothek arbeitet?

Überprüfen Sie die Quelle der Lok knapsack Funktion.