Optimierung mit diskreten Parametern in Matlab
Habe ich 12 Sätze von Vektoren (etwa 10-20 Vektoren) und ich will ein pick-Vektor, der jeden Satz so, dass eine Funktion f, der die Summe dieser Vektoren als argument wird maximiert. Darüber hinaus habe ich Einschränkungen für einige Komponenten dieser Summe.
Beispiel:
a_1 = [3 2 0 5], a_2 = [3 0 0 2], a_3 = [6 0 1 1], ... , a_20 = [2 12 4 3]
b_1 = [4 0 4 -2], b_2 = [0 0 1 0], b_3 = [2 0 0 4], ... , b_16 = [0 9 2 3]
...
l_1 = [4 0 2 0], l_2 = [0 1 -2 0], l_3 = [4 4 0 1], ... , l_19 = [3 0 9 0]
s = [s_1 s_2 s_3 s_4] = a_x + b_y + ... + l_z
Einschränkungen:
s_1 > 40
s_2 < 100
s_4 > -20
Ziel: Wähle x, y, ... , z zur Maximierung von f(s):
f(s) -> max
Wobei f eine nichtlineare Funktion, die den Vektor s und liefert einen Skalar.
Bruteforcing dauert zu lange, weil es über 5.9 Billion Kombinationen, und da Brauch ich die maximale (oder noch besser die top 10 Kombinationen) kann ich nicht verwenden Sie eine der greedy-algorithmen, die mir in den Sinn kam.
Vektoren sind Recht spärlich, etwa 70-90% sind Nullen. Wenn das hilft irgendwie ...?
Der Matlab-Optimization toolbox nicht helfen, da es nicht viel Unterstützung für diskrete Optimierung.
- können Sie etwas über die nicht-lineare Funktion
f(s)
? was wissen Sie über ihn? was können Sie übernehmen? - Wenn Sie uns ein vollständig reproduzierbares Beispiel (mit den Einschränkungen, und der obj Funktion detailliert aus) können wir nur empfehlen, Wege zu gehen, über das problem zu lösen.
- Mit den Einschränkungen, die Suche nach Raum ist nicht so groß.
- verwenden
fminsearch
oderbintprog
und minimieren 1/f(s)... - wie
bintprog
helfen wird? die Objektive Funktion derbintprog
wird angenommen, lineare - Ich schrieb auch "oder fminsearch", da mehr Daten würde ich wahrscheinlich einen besseren Kommentar...
- Über die Funktion f(s): ich muss verschiedene Funktionen und ich bin nicht 100% sicher sind, wie Sie Aussehen, aber hier sind einige Beispiele: f(s) = s_1 * (s_2 * s_3 - s_2 + 2) oder f(s) = s_1 * s_2 * 0.5 / (1.5 * s_3). Einschränkungen sind wie in meinem Beispiel, nur größer/kleiner.
- tut
a_x
bedeutet, x eine Zahl von 1 bis 20, im Zusammenhang mit a_1...a_20 ? Was bedeutets1=
bedeutet ? nur einer von vier Vektoren, die abgetastet wird, aus dem Satza_i ... l_j
? - Sie haben die global optimization toolbox?
1/f(s)
ist problematisch, mit Methoden, die Derivate einsetzen (und andere Dinge), in der Regel, einfach-f(s)
ist die bessere Wahl.- Woher weißt du das? Angenommen, 75% aller Kombinationen wäre ja Weg von den Zwängen. Das lässt
(20^12)/4
oder zum 1 Billiarde - Kombinationen. Auf eine Milliarde Kombinationen pro Sekunde, das heißt fast 12 Tage Zahlenverarbeitung...scheint nicht sehr effizient zu mir. - Nur um zu überprüfen: 1) sind Ihre Vektoren tatsächlich Ganzzahlen? Wenn ja, welche Art (int8, uint64, etc.)? Was ist Ihre wahre Größe, in Ihrem realen Programm ich meine?
- Die Vektoren sind eigentlich Schwimmer, aber Sie enthalten nur ganze zahlen, so dass die Rundung zu Ihnen zu int8 ist in Ordnung. Sie haben 24 Elemente.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Im Grunde ist dies ein lock-picking-problem, wobei die lock pins haben 20 unterschiedliche Positionen, und es sind 12 pins. Auch:
...interessant!
Basierend auf Rasman-Ansatz und Phpdna Kommentar, und der Annahme, dass Sie mit
int8
als Daten-Typ, unter den gegebenen Einschränkungen gibt esmöglichen Vektoren
s
(geben oder nehmen ein paar, nicht etwa gedacht haben, +1 etc.). ~740 Millionen Bewertungen Ihrer relativ einfachenf(s)
sollte nicht mehr als 2 Sekunden, und gefunden zu haben alles
dass maximierenf(s)
, Sie sind mit dem problem des Findens von linearen Kombinationen in der Vektor-set, die bis zu hinzufügen eine dieser Lösungens
.Natürlich das finden der Kombinationen ist kein Kinderspiel, und die ganze Methode bricht sowieso, wenn Sie den Umgang mit
So, ich werde diskutieren einer direkteren und allgemeineren Ansatz.
Da sprechen wir ganze zahlen und eine ziemlich große Suchraum, ich würde vorschlagen, mit einem branch-and-bound-Algorithmus. Aber im Gegensatz zu den
bintprog
Algorithmus, müssten Sie verwenden verschiedene branching-Strategien, und natürlich, diese sollte auf der Grundlage einer nicht-linearen Zielfunktion.Leider, es gibt nichts wie dies in der optimization toolbox (oder die Datei Exchange soweit ich finden konnte).
fmincon
ist ein no-go, da es verwendet die Gradienten und Hesse-Informationen (die werden in der Regel alle-zero für ganze zahlen), undfminsearch
ist ein no-go, da Sie brauchen werden, eine wirklich gute erste Schätzung, und die rate der Konvergenz ist (in etwa)O(N)
, das heißt, für diese 20-dimensionalen problem, müssen Sie warten ganz lange, bevor die Konvergenz ohne die Garantie für das finden des globalen Lösung.Einer Intervall-Methode könnte eine Möglichkeit sein, aber ich persönlich habe sehr wenig Erfahrung mit dieser. Es gibt keine native Intervall-bezogene Dinge in MATLAB oder einer Ihrer Schubladen, aber es gibt den frei verfügbaren INTLAB.
Also, wenn Sie nicht das Gefühl, wie die Umsetzung Ihrer eigenen, nicht-linear, Binär-integer-programming-Algorithmus, oder sind nicht in der Stimmung für ein Abenteuer mit INTLAB, es gibt wirklich nur eine Sache Links: heuristische Methoden. In dieser link es ist eine ähnliche situation, mit einer Gliederung der Lösung: Nutzung des genetischen Algorithmus (
ga
) von der Global Optimization toolbox.Ich würde implementieren das problem in etwa so:
Beachten Sie, dass, obwohl Ihre Einschränkungen sind im wesentlichen lineare, die Art und Weise, durch die Sie müssen berechnen Sie den Wert für Ihr
s
erfordert die Verwendung von ein benutzerdefiniertes constraint-Funktion (nonlcon
).Besonders beachten Sie, dass dies derzeit (wahrscheinlich) eine sub-optimale Möglichkeit zur Nutzung
ga
- ich weiß nicht, die Besonderheiten Ihres Ziel-Funktion, so dass viel mehr möglich sein kann. Zum Beispiel, ich verwende derzeit eine einfachround()
zum konvertieren der Eingangs -X
Ganzzahlen, aber mit'PopulationType', 'custom'
(mit einer benutzerdefinierten'CreationFcn'
,'MutationFcn'
etc.) könnte zu besseren Ergebnissen führen. Auch'Vectorized'
wird wahrscheinlich die Dinge beschleunigen, eine Menge, aber ich weiß nicht, ob Ihre Funktion ist leicht vektorisiert.Und ja, ich benutze verschachtelte Funktionen (ich Liebe diese Dinge!); es verhindert, dass diese riesig, in der Regel identische Listen von input-Argumente wenn Sie die Nutzung von sub-Funktionen oder stand-alone-Funktionen, und Sie können wirklich ein performance-Schub, weil es wenig kopieren von Daten. Aber, ich merke, dass Ihre scoping-Regeln machen Sie etwas ähnlich
goto
Konstrukte, und so sind Sie -ahum- "not everyone' s cup of tea"...möchten Sie vielleicht, um Sie zu konvertieren sub-Funktionen zur Vermeidung von langen und nutzlosen Diskussionen mit Ihren Arbeitskollegen 🙂Sowieso, sollte dies ein guter Ort, um zu starten. Lassen Sie mich wissen, ob dies überhaupt nützlich sind.
Es sei denn, Sie definieren Intelligenz auf, wie die vector-sets organisiert sind, wird es kein intelligenter Weg, um Ihr problem zu lösen, dann werden Sie anderen reinen brute-force.
Sagen, Sie finden s en.t. f(s) ist max gegebenen Randbedingungen von s, die Sie noch brauchen, um herauszufinden, wie bauen s mit zwölf 4-element-Vektoren (einer überdeterminierten system, wenn es überhaupt einer war), wo jeder Vektor hat 20 mögliche Werte. Sparsity helfen kann, obwohl ich nicht sicher bin, wie es möglich ist, ein Vektor mit vier Elementen sein
70-90%
null, und sparsity würde nur nützlich sein, wenn es einige noch nicht beschriebene Methodik an, wie der Vektor organisiert sindSo, ich sage nicht, Sie kann das problem nicht lösen, ich sage Sie brauchen, um zu überdenken, wie das problem ist set-up.
s
sollte eine lineare Kombination von Vektoren (mit der all-Einheit Koeffizienten) ist in der Tat die härteste Einschränkung in diesem problem. Man könnte sogar sagen, dass das ist das problem; das minimum vonf(s)
nur zweitrangig.Ich weiß, diese Antwort erreicht Sie wirklich
late
.Leider, das problem ist, zeigen nicht viele Muster genutzt werden, neben der brute-force -Branch&Gebunden, Master& Slave, etc.- Sie versuchen eine Master-Slave-Ansatz-d.h. die Lösung erst die Funktion kontinuierliche nichtlineare problem als master, und die Lösung der diskreten Auswahl als slave könnte helfen, aber mit so vielen Kombinationen, und ohne weitere Informationen über die Vektoren, es ist nicht allzu viel Platz zum arbeiten.
Aber auf der Grundlage der gegebenen kontinuierlichen fast überall-Funktionen, basierend auf der Kombination von Summenbildung und Multiplikation von Operatoren und deren inversen, die sparsity ist ein klarer Punkt, ausgebeutet zu werden hier. Wenn 70-90% der Vektoren null sind, fast ein guter Teil der solution space in der Nähe von null oder nahe
infinite
. Daher ist eine 80-20 pseudo-Lösung verworfen werden würde einfach die "null" - Kombinationen und verwenden Sie nur das "unendliche" ersetzt.Diese Weise, die brute-force-geleitet werden können.