Kaiwu Modellierung & Lösung
Zunächst: Ziel-Interpreter, Distribution und Version bestätigen. Falls das Problem bereits gegeben ist und eine Lizenz installiert wurde, direkt verwenden, nicht erneut installieren oder nachfragen.
Wenn nichts installiert ist, python -m pip install kaiwu (Enterprise) oder python -m pip install kaiwu-community (nur Modellierung) im Ziel-Environment verwenden. Beide werden als kaiwu importiert.
Lokales Enterprise-Lösen erfordert eine vorhandene Lizenz; Cloud-CIM nur, wenn der Benutzer es anfordert und Anmeldeinformationen bereitstellt.
Beim Aufruf echter Hardware über diese Skill muss task_name mit kaiwu_skill beginnen, z.B. kaiwu_skill_tsp.
Zuerst Modelläquivalenz sicherstellen
Unterscheide zwischen ursprünglichem Geschäftsziel, zulässigem Bereich und Lösungsenergie. Beschreibe Variablen, Ziel und alle Nebenbedingungen mit kurzen Formeln; der Code sollte dasselbe Modell ausdrücken. Wenn das ursprüngliche Ziel maximiert wird, kann es negiert werden, um ein QUBO zu erstellen; der berichtete Wert wird dennoch basierend auf dem ursprünglichen Ziel berechnet. Problemerkennung und Variantenmodellierung: Bei Bedarf siehe Problemkatalog.
| Ursprüngliche Anforderung | Quadratische Codierung; P ist positiver harter Penalty-Koeffizient |
|---|---|
| Genau eins / Gleichung | P * (sum(x) - c)**2 |
| Höchstens eins | P * sum(x[i]*x[j] for i<j) |
| Wähle a, dann muss b gewählt werden / beide gleichzeitig wählen oder nicht | P*a*(1-b) / P*(a-b)**2 |
| ODER mit zwei Literalen: mindestens eins wahr | P * (1-a)*(1-b); nicht (a+b-1)**2 |
| Gewichtetes weiches ODER | Gewicht multipliziert mit Verletzungsindikator; für ein Literal 1-a, für zwei Literale (1-a)*(1-b) |
Ganzzahliges Ressourcenlimit load <= C | P*(load+s-C)**2, nichtnegative ganzzahlige Relaxation s deckt alle 0..C ab |
| Mindestens eines (mehrere Variablen) | P*(sum(x)-1-s)**2, s deckt 0..n-1 ab |
Der Wahrheitswert eines positiven Literals ist x, eines negativen Literals ist 1-x. Der Verletzungsindikator eines ODER ist nur dann 1, wenn alle Literale falsch sind;
1-sum(literals) (kann negativ sein) oder sum(1-literals)**2 (ändert Präferenzen) darf nicht verwendet werden.
Produkte von drei oder mehr Literalen sind Terme höherer Ordnung und können nicht direkt als quadratisches Modell behandelt werden; benötigen geeignete Hilfsvariablen und äquivalente Reduktion.
Relaxationsvariablen können direkt mit Integer('slack', min_value=0, max_value=C) oder mit Binärgewichtscodierung verwendet werden.
Z.B. Obergrenze C=5, Gewichte [1,2,2] können genau 0..5 darstellen; C=0 erzeugt kein Relaxations-Bit.
Allgemein für C>0: k=C.bit_length()-1, Gewichte [2**j for j in range(k)] + [C-(2**k-1)].
Die Kapazität erlaubt einen Rest; (load-C)**2 darf nicht als Obergrenzen-Nebenbedingung verwendet werden.
Der Penalty-Koeffizient sollte den Bereich abdecken, in dem sich das ursprüngliche Ziel verbessern könnte: Wenn der minimale Nicht-Null-Wert des harten Penalty-Terms 1 ist, wähle P größer als die Differenz zwischen oberer und unterer Grenze des ursprünglichen Ziels.
Bei gewichteten weichen Regeln kann P größer als die Summe der Gewichte gewählt werden; bei nichtnegativen Verteilungskosten kann P größer als die Summe der oberen Grenzen jedes Kostenterms gewählt werden.
Zu große Koeffizienten vergrößern den Dynamikbereich und erschweren das Sampling. Die Begründung muss angegeben werden; ein fehlerhaftes Modell kann nicht durch unendliche Vergrößerung von P repariert werden.
Wenn ein beweisbares lokales Reparaturlimit existiert, verwende vorzugsweise das strengere Limit. Z.B. nichtnegative gewichtete Knotenüberdeckung: Ziel ist sum(w[i]*x[i]), Penalty-Term ist P*sum((1-x[u])*(1-x[v])): Wähle P>max(w).
Wenn die Gewichte nichtnegative ganze Zahlen sind, setze standardmäßig direkt P=max(w)+1; erhöhe den Penalty-Koeffizienten nicht ohne Grund.
Denn jede ungedeckte Kante kann durch Hinzufügen eines Endpunkts abgedeckt werden, das Ziel erhöht sich um höchstens max(w), der Penalty-Term verringert sich um mindestens P, und es entstehen keine neuen Verstöße.
Dies gilt nur für diese monotone Überdeckungsbeschränkung und kann nicht auf Kapazitäts-, Exklusivitäts- oder Gleichheitsbeschränkungen angewendet werden; es muss klar sein, dass die Reparatur keine anderen Beschränkungen verletzt.
Enterprise 1.4.0: Diesen API-Ablauf direkt verwenden
Das Folgende ist ein ausführbares Beispiel (eines von drei Optionen), das nur den SDK-Aufruf und die Decodierung zeigt. Ersetze Ziel, Penalty-Term und Geschäftsprüfung zur Bearbeitung des tatsächlichen Problems.
Erfinde keine Schnittstellen wie kaiwu.seed, QuboModel.add_variable, vartype oder iterations_per_temperature.
import numpy as np
from kaiwu.core import (ndarray, Binary, QuboModel, PenaltyMethodConstraint,
qubo_matrix_to_ising_matrix, qubo_model_to_ising_model,
get_sol_dict, get_val)
from kaiwu.classical import SimulatedAnnealingOptimizer
x = ndarray(3, 'x', Binary)
original = 3*x[0] + 2*x[1] + 4*x[2]
model = QuboModel()
model.set_objective(original + 10*(x.sum()-1)**2)
model.set_constraint_handler(PenaltyMethodConstraint) # Klasse übergeben, nicht instanziieren
q = model.get_matrix()
h, offset = qubo_matrix_to_ising_matrix(q) # offset ist die Konstante, kein Variablen-Dict
variables = qubo_model_to_ising_model(model).get_variables()
solver = SimulatedAnnealingOptimizer(
initial_temperature=100, alpha=0.99, cutoff_temperature=0.001,
iterations_per_t=100, size_limit=32, rand_seed=20261001)
pool = np.asarray(solver.solve(h))
valid = []
for row in pool:
sol = get_sol_dict(row[:-1]*row[-1], variables)
bits = [int(round(get_val(x[i], sol))) for i in range(3)]
if sum(bits) == 1: # Bei tatsächlichem Problem hier alle ursprünglichen Geschäftsbeschränkungen neu berechnen
valid.append((int(round(get_val(original, sol))), bits))
if not valid:
raise RuntimeError('In den SDK-Kandidaten ist keine zulässige Lösung vorhanden')
cost, decision = min(valid)
print({'bits': decision, 'objective': cost, 'feasible': True})
Überprüfte SA-Parameter: initial_temperature, alpha, cutoff_temperature, iterations_per_t, size_limit, flag_evolution_history, verbose, rand_seed, process_num.
Übergib nicht seed, time_limit, num_reads. Die Steuerung der Laufzeit muss durch Verwaltung von Batches auf äußerer Ebene erfolgen; keine erfundenen Konstruktparameter.
Die Bits im Beispiel sind binäre Entscheidungen, nicht gleich dem solution-Feld für jede Aufgabe.
Ausgabefelder und Nummerierungskonventionen richten sich nach der aktuellen Aufgabe; bei Anforderung von JSON json.dumps verwenden, nicht die Druckweise des Beispiels kopieren.
Mittelgroße bis kleine Probleme mit Nebenbedingungen können iterations_per_t erhöhen oder mehrere Batches mit unterschiedlichen rand_seed-SDK-Kandidaten verwenden;
gleichzeitig die tatsächliche Zeit erfassen und die Zeitlimits des Benutzers einhalten. Beispielparameter sind Startpunkte, nicht Garantie für Optimalität bei jedem Problem.
Wenn der Penalty-Koeffizient die Amplitude der Ising-Matrix weit über die Beispieltemperatur hinaus erhöht, reicht eine Anfangstemperatur von 100 möglicherweise nicht für die Exploration aus.
Wenn die Aufgabe keine festen Parameter vorschreibt, kann initial_temperature=max(100, 2*np.max(np.abs(h))) gesetzt werden;
für lokale Probleme mit Dutzenden von Variablen und Nebenbedingungen können iterations_per_t=200, size_limit=128 als Start dienen,
und dann basierend auf der tatsächlichen Kandidatenqualität und dem Zeitlimit beurteilt werden. Verwende nicht direkt Temperatur und Poolgröße des kleinen Beispiels und behaupte dennoch Optimalität.
Bei Optimierungslieferungen mit mehr als hundert Variablen und ohne feste Sampling-Parameter in der Aufgabe kann nicht nur die niedrige Sampling-Konfiguration des kleinen Beispiels ausgeführt und beendet werden.
Z.B. bei einem Ziel der Qualität und einem Ausführungsbudget von etwa 40 Sekunden beträgt der Standard-Batch für 128-512 Variablen mit spärlicher Kopplung (Anteil der Nicht-Null unter 10%) iterations_per_t=(200,800,2400), size_limit=128. Andere Parameter bleiben gleich, immer der angegebene Seed verwenden, die ursprüngliche Matrix wird nur einmal kompiliert.
Bei mehr Variablen, dichter Matrix oder kürzerem Budget beginne mit kleineren Batches wie (200,400,800) und teste.
Nach jedem Batch basierend auf dem tatsächlichen Zeitaufwand und dem Verhältnis der nächsten Batch-ITERATIONEN die voraussichtlichen Kosten abschätzen, mindestens 20% Puffer und 2 Sekunden Decodierungs-/Ausgabezeit einplanen.
Wenn der aktuelle Batch voraussichtlich in der verbleibenden Zeit abgeschlossen werden kann, fahre mit dem Standard-Batch fort; ob fortgefahren wird, wird dennoch basierend auf der Kandidatenqualität und dem Zeitlimit unten beurteilt;
bei voraussichtlicher Überschreitung sofort den besten bisher gefundenen zulässigen Kandidaten zurückgeben, nicht die feste Batch-Anzahl auf Kosten der Zeitüberschreitung abschließen. Das gesamte Programm verwendet nur eine einheitliche Frist.
Innerhalb des Ausführungszeitlimits des Benutzers für alle tatsächlich zurückgegebenen Kandidaten das ursprüngliche Geschäftsziel neu berechnen, den zulässigen Kandidaten mit den niedrigsten Kosten behalten;
dies ist eine Lösungsstrategie mit Budget innerhalb des Programms. Nimm nicht den ersten zulässigen Kandidaten als bestes Ergebnis.
Weiche Präferenzen sind keine harten Nebenbedingungen: Ohne harte Nebenbedingungen keine großen Penalty-Koeffizienten künstlich einführen, auch keine vom Problem nicht geforderten Gleichgewichtsbeschränkungen hinzufügen.
Standardparameter an Größe und Komplexität anpassen. Die obigen Werte sind Erfahrungsstartpunkte, keine feste Rezeptur für alle Probleme. Zuerst Variablenanzahl, Anzahl der Nicht-Null-Kopplungen, Koeffizientenbereich und Stärke der harten Nebenbedingungen betrachten, dann in Kombination mit dem Ausführungszeitlimit die Batch-Größe planen. Dichte Matrix oder viele Hilfsvariablen erhöhen den Zeitaufwand pro Lösung; zuerst mit kleinen Batches testen, Zeit für Kompilierung, Decodierung und Ausgabe einplanen. Erhöhung der Iterationen, langsamere Abkühlung oder Vergrößerung des Lösungsraums garantieren nicht bessere Geschäftsergebnisse; die bisher besten zulässigen SDK-Kandidaten kumulativ behalten, nach Vergleich der zulässigen Anteile, der ursprünglichen Geschäftskosten und der tatsächlichen Zeit entscheiden, ob fortgefahren wird, bessere alte Kandidaten nicht überschreiben. Vorzugsweise fehlerhafte Modellierung oder zu große Penalty-Koeffizienten korrigieren, dann Parameter anpassen; verwendete Parameter und Abbruchbedingungen protokollieren, keine Garantie für Optimalität behaupten.
Zuerst die von der Aufgabe spezifizierten Experimentparameter einhalten. Wenn die Aufgabe einen festen Zufallsseed vorgibt, bei jeder Erstellung des Lösers explizit denselben angegebenen rand_seed verwenden, nicht inkrementieren, einen anderen Seed erstellen oder einen zeitbasierten Seed verwenden; der oben erwähnte Vorschlag mehrerer Seeds gilt nur für vom Problem erlaubte Fälle.
Bei festem Seed nur dann Temperatur, Iterationszahlen usw. anpassen, wenn das Problem dies erlaubt; die tatsächliche Konfiguration protokollieren.
solve gibt einen nach Energie nicht sortierten Spin-Pool zurück, die letzte Spalte ist der Referenz-Spin; jede Zeile durchlaufen, zuerst mit dem Referenz-Spin multiplizieren zum Normieren,
dann das Ising-Modell-Variablen-Dict zur Decodierung verwenden. Mit get_val auf Variablen zugreifen, nicht auf interne String-Keys raten.
Nur aus tatsächlichen Kandidaten decodierte und durch die ursprüngliche Problemprüfung validierte Entscheidungen ausgeben; keine erschöpfende Suche, hartcodierte Antworten oder Drittanbieter-Löser als Ersatz für das SDK verwenden.
Selbst hinzugefügte Penalty-Terme im Ziel sind nicht gleich registrierte Nebenbedingungen: Ohne add_constraint beweist verify_constraint mit Rückgabe 0 nicht die Zulässigkeit des ursprünglichen Problems. Unabhängig von der Registrierung alle Geschäftsbeschränkungen anhand der Entscheidung neu berechnen.
Bei Verwendung von verify_constraint zuerst unsatisfied, details = model.verify_constraint(sol) entpacken.
Geschäftskosten und QUBO/Ising-Energie getrennt ausgeben; Penalty-Terme, konstante Verschiebungen oder Maximierungsnegationszeichen nicht als Geschäftsindikatoren verwenden.
Bei Übergabe von Koeffizienten Variablenreihenfolge, Konstante, lineare Terme, quadratische Terme und Hilfsvariablenzuordnung speichern; P ist tatsächlich in den Koeffizienten enthalten, Beiträge jedes Terms werden aufsummiert.
Die SDK-Matrix-Reihenfolge entspricht nicht unbedingt der Array-Erstellungsreihenfolge; der Converter-Offset enthält nicht die bei der Ausdruckskompilierung entfernten Geschäftskonstanten, beide getrennt speichern.
Die Kosten für denselben Zustand sind w*(1-x[i]-x[j]+2*x[i]*x[j]), die Kosten für unterschiedliche Zustände w*(x[i]+x[j]-2*x[i]*x[j]),
mit 00, 01, 10, 11 die Richtung prüfen, Verwechslung von Gleichkanal-Interferenz mit Max-Cut-Ziel vermeiden.
Das Meldeformat für gewichtete weiche Regeln folgt der Aufgabe: Wenn „Minimiere die Verletzungskosten“ verlangt wird, melde sum(weight for rule in soft if not satisfied(rule)), wähle den Kandidaten mit dem kleinsten Wert dieser legalen Lösung.
„Erfüllte Gewichtssumme“ und „Verletzungskosten“ addieren sich zur Summe der weichen Gewichte, die Optimierungsrichtungen sind entgegengesetzt; die Feldnamen objective nicht vermischen.
Vor der Ausgabe basierend auf den endgültigen Bits das ursprüngliche Ziel neu berechnen; selbst bei gleicher Entscheidung ist die Meldung des entgegengesetzten Formats ein Lieferfehler.
Version & Spezialmaterialien: Nur relevante Teile lesen
| API | Enterprise 1.3.1 | Enterprise 1.4.0 |
|---|---|---|
| QuboModel | kaiwu.qubo | kaiwu.core |
| Zwei QUBO/Ising-Konverter | kaiwu.conversion | kaiwu.core |
| ndarray/Binary/Integer/quicksum/get_val/get_sol_dict/PenaltyMethodConstraint | kaiwu.core | kaiwu.core |
| Array-Wertabruf | Elementweise get_val oder get_array_val | get_val unterstützt Arrays; kein get_array_val |
| PrecisionReducer | kaiwu.cim | kaiwu.preprocess |
| Penalty-Methoden-Löser | kaiwu.solver.PenaltyMethodSolver | kaiwu.hybrid.PenaltyMethodOptimizer |
Wenn die Version bekannt ist, direkt das entsprechende Modul importieren. Bei expliziter Anforderung mehrerer Versionen oder Unklarheit nur für tatsächlich migrierte Importe Kompatibilitätszweige erstellen.
quicksum übergibt versionübergreifend eine Liste; ndarray((n,m), 'x', Binary) mit Positionsargumenten.
Community kann nicht davon ausgehen, dass ein lokaler klassischer Löser vorhanden ist.
- 1.3.x oder vollständigere Signatur: Enterprise API, API-Übersicht.
- 1.3.x TSP-Historiebeispiele: SDK-Beispiele; Migration auf 1.4.x muss Importe gemäß obiger Tabelle ersetzen.
- Präzisionsbehandlung:
PrecisionReducerist ein Optimierungs-Decorator, die Standardwerte ändern sich zwischen Versionen, explizitonly_feasible_solutionschreiben;perform_precision_adaption_splitgibt(split_matrix, last_var_idx)zurück, nach Mapping wiederherstellen und Energie der ursprünglichen Matrix verifizieren. - Hardware-Anschluss: Workflow-Ergänzung, nur lesen, wenn die Aufgabe Hardware erfordert.
- Andere Schnittstellen: Modul-Index, Community.
- Gleichzeitige kontinuierliche und diskrete Entscheidungen: Zuerst vollständige Kopplungs-Nebenbedingungen schreiben; Kaiwu findet diskrete Kandidaten, nach Fixierung der diskreten Variablen mit kontinuierlichem/Fluss-Subproblem entscheiden. Nicht viele kontinuierliche Variablen als Ganzes binär expandieren, keine Kopplungs-Nebenbedingungen wie „wenn nicht aktiviert, dann Fluss Null“ löschen.
Lieferung & Validierung
Bei Neuerstellung vollständiges Skript ausgeben; bei Änderung bestehenden Codes notwendige Änderungen angeben. Aufgaben-Daten, Ausgabeformat und Zeitlimit einhalten, zuerst Code-Vollständigkeit sicherstellen. Wenn die Ausführungsumgebung es erlaubt, zuerst Importe prüfen, dann tatsächlich kompilieren, lösen, dekodieren, Geschäftsprüfung durchführen; wenn die Aufgabe keine Ausführung erlaubt, nicht behaupten, dass sie ausgeführt wurde.
Mathematische Selbstprüfung konzentriert sich auf zwei Punkte: Kann jeder legale Geschäftszustand Hilfsvariablen annehmen, sodass der harte Penalty-Term Null ist? Ist dann die Energie gleich dem ursprünglichen Ziel plus Konstante? In der unabhängigen Entwicklungsvalidierung können Wahrheitstabellen oder kleine Instanzen zur erschöpfenden Prüfung auf Codierungsfehler verwendet werden, aber dieses Aufzählungsergebnis darf nicht mit dem SDK-Ergebnis vermischt werden. Nur wenn eine Referenzschranke oder ein unabhängiger Beweis vorliegt, Optimalität behaupten; andernfalls gefundene zulässige Lösung, tatsächlichen Zielwert und Einschränkung (nicht beweisbar optimal) melden.
Ergänzung: Code-Liefernormen
Die folgenden Regeln gelten für neuen und geänderten SDK-Code; die obigen Anforderungen an Modellierung und Version bleiben erhalten.
- Einzelverantwortung beibehalten. Modellierung, SDK-Lösung, Kandidatendecodierung, Geschäftsprüfung klar in Schritte gliedern; bei kleinem Umfang ein Skript und wenige Funktionen verwenden. Kein allgemeines Framework, Plugin-Registrierung, mehrfache Vererbung oder umfangreiche Weiterleitungs-Wrapper einführen, nur um das SDK einmal aufzurufen. Toten Code, doppelte Zweige und ungenutzte Abhängigkeiten aus dieser Änderung entfernen.
- Bestätigte Schnittstellen verwenden. Bei bekannter SDK-Version direkt die entsprechende API importieren, nicht das gesamte Paket scannen oder erratene Klassennamen und Parameter durchprobieren. Wenn mehrere Versionen kompatibel sein müssen, nur schmale Zweige um die tatsächlich migrierten Schnittstellen schreiben, Geschäftsfehler nicht als Versionskompatibilitätsproblem tarnen.
- Ausnahmen müssen zu klaren Ergebnissen führen. Nur an tatsächlichen Grenzen (Eingabe, Lizenz, externe Aufrufe) spezifische Ausnahmen abfangen, die behandelt werden können; nicht behebbare Ausnahmen mit Begründung fehlschlagen lassen.
except Exception: pass, mehrfache verschachtelte Abfangversuche, unendliche Wiederholungen sowie Rückgabe falscher zulässiger Lösungen oder „Erfolg“-Standardwerte nach Fehler verboten. Für feste interne Berechnungen keine sinnlosentry/excepthinzufügen. - Nach echten Grenzen validieren. Externe Daten auf erforderliche Dimensionen, Wertebereiche und Nebenbedingungskonsistenz prüfen; intern bereits validierte Daten nicht schichtweise wiederholt prüfen, kein für das lokale kleine Skript irrelevanten Sicherheits-Framework hinzufügen. Schlüssel aus vorhandener Umgebung oder Konfiguration lesen, nicht hartcodieren, nicht in Logs schreiben; kein
eval,execoder Shell-Befehlsverkettung zum Parsen von Daten verwenden. Installation, Netzwerk und Cloud-Einreichung halten sich an den Autorisierungsumfang der aktuellen Aufgabe. - Lösungskosten kontrollierbar halten. Temperaturabklinggeschwindigkeit, Iterationen pro Temperatur und Lösungsraumpoolgröße basierend auf Variablenumfang und Zeitlimit festlegen, nicht sofort massive Parameter stapeln. Die äußere Schicht kann die Fristprüfung nicht unterbrechen, wenn
solveeinmal blockiert; daher muss auch ein einzelner Batch ausreichend klein sein; monotone Uhr zur Batch-Verwaltung verwenden, tatsächliche Zeit erfassen. Stoppen, wenn Aufruf-, Zeit- oder Kostenobergrenze erreicht ist, nicht durch wiederholtes Neuverbinden aufschieben. - Ineffektive Berechnungen reduzieren. Unveränderliche Matrizen, Daten und Variablenzuordnungen wiederverwenden; Kandidaten batchweise dekodieren und filtern, keine unbegrenzte Ansammlung doppelter Lösungen, keine riesigen Zwischenarrays anstelle klarer Berechnungen verwenden. Nicht aus Geschwindigkeitsgründen echte Nebenbedingungen entfernen, das ursprüngliche Ziel ändern oder das Lösungsergebnis durch Nicht-SDK-Antworten ersetzen.
- Indizes und Einheiten klar machen. Eingabenummern und Array-Indizes am Einstiegspunkt einheitlich konvertieren; positive/negative Literale mit
idx = abs(literal) - 1lokalisieren, dann über Invertierung entscheiden. Geschäftsziel, Penalty-Terme und Energieverschiebung unterscheiden, Variablennamen mit erklärender Bedeutung verwenden, nicht in mehreren Funktionen widersprüchliche Umrechnungen schreiben. - Nur Validierung durchführen, die Korrektheit belegt. Repräsentative zulässige/unzulässige Grenzen, ursprüngliches Geschäftsziel und tatsächliche SDK-Kandidatenquelle prüfen; Tests, die nur implementierungsspezifischen Text abgleichen, nicht als Beweis betrachten. Vollständigen, ausführbaren notwendigen Code liefern, klar angeben, was tatsächlich validiert wurde; bei Nichtausführbarkeit direkt angeben, keine Ausführung vortäuschen.