Angenommen, ich bin ein Programmierer und habe ein NP-vollständiges Problem, das ich lösen muss. Welche Methoden stehen zur Verfügung, um mit NPC-Problemen umzugehen? Gibt es eine Umfrage oder ähnliches zu diesem Thema?
Angenommen, ich bin ein Programmierer und habe ein NP-vollständiges Problem, das ich lösen muss. Welche Methoden stehen zur Verfügung, um mit NPC-Problemen umzugehen? Gibt es eine Umfrage oder ähnliches zu diesem Thema?
Antworten:
Es gibt eine Reihe von gut untersuchten Strategien; Welche für Ihre Anwendung am besten geeignet ist, hängt von den Umständen ab.
Verbessern der Worst-Case-Laufzeit
Mit problemspezifischen Erkenntnissen können Sie häufig den naiven Algorithmus verbessern. Zum Beispiel gibt es -Algorithmen für Vertex Cover mit c < 1,3 [1]; Dies ist eine enorme Verbesserung gegenüber dem naiven Ω ( 2 n ) und könnte die für Sie relevanten Instanzgrößen handhabbar machen.
Verbessern der erwarteten Laufzeit
Mithilfe von Heuristiken können Sie häufig Algorithmen entwickeln, die in vielen Fällen schnell sind. Wenn diese die meisten beinhalten, die Sie in der Praxis treffen, sind Sie golden. Beispiele sind SAT, für die es ziemlich komplizierte Löser gibt, und der Simplex-Algorithmus (der ein Polynomproblem löst, aber immer noch). Eine grundlegende Technik, die oft hilfreich ist, ist das Verzweigen und Binden .
Einschränken des Problems
Wenn Sie bei Ihren Eingaben weitere Annahmen treffen können, kann das Problem leicht auftreten.
Schwächen Sie das Ergebnis.
Dies bedeutet, dass Sie fehlerhafte oder unvollständige Ergebnisse tolerieren. Es gibt zwei Hauptgeschmacksrichtungen:
Eine ausführliche Beschreibung finden Sie in Algorithmics for Hard Problems von Hromkovič.
Andere Antworten haben dies aus einer theoretischeren Perspektive angesprochen. Hier ist ein praktischerer Ansatz.
Bei "typischen" NP-vollständigen Entscheidungsproblemen ( "Gibt es ein Ding, das all diese Einschränkungen erfüllt?" ) Würde ich immer zuerst Folgendes versuchen:
Schreiben Sie ein einfaches Programm, das Ihre Probleminstanz als SAT-Instanz codiert .
Nehmen Sie dann einen guten SAT-Solver , führen Sie ihn aus (mit dem schnellsten Multi-Core-Computer, den Sie haben) und sehen Sie, was passiert.
Versuchen Sie es zunächst mit kleineren Instanzen, um eine Vorstellung davon zu bekommen, wie lange dies dauern könnte.
Überraschenderweise ist dieser Ansatz viel besser als der Versuch, einen eigenen Löser speziell für Ihr aktuelles Problem zu implementieren:
SAT-Löser sind sehr clever und gut optimiert. Sie übertreffen problemlos Ihre eigene Implementierung der Rückverfolgungssuche (unabhängig davon, wie viel Zeit Sie für die Optimierung Ihres Codes aufwenden). Sie übertreffen auch leicht viele selbstständige Alternativen, wie z. B. ganzzahlige lineare Programmierlöser.
Dies erfordert sehr wenig Programmierung. Schritt 1 ist relativ unkompliziert und nicht leistungskritisch. Sie können Skriptsprachen wie Python verwenden. Jemand anderes hat bereits dafür gesorgt, dass alles implementiert wird, was Sie für Schritt 2 benötigen.
Für typische NP-harte Optimierungsprobleme ( "Finde das kleinste Ding, das all diese Einschränkungen erfüllt" ) kann dieser Ansatz funktionieren oder auch nicht.
Wenn Sie es leicht in ein Entscheidungsproblem verwandeln können ( "Gibt es ein Ding der Größe 4, das alle diese Einschränkungen erfüllt?" , "Was ist mit Größe 3?" ), Folgen Sie dem gleichen Ansatz wie oben bei Entscheidungsproblemen.
Andernfalls möchten Sie möglicherweise auf einen heuristischen Löser zurückgreifen, der versucht, eine kleine Lösung zu finden (nicht unbedingt die kleinste Lösung). Zum Beispiel:
Codieren Sie Ihr Problem als (gewichtete) MAX-SAT-Instanz .
Verwenden Sie die heuristischen Löser aus dem UBCSAT- Paket. Heuristische Löser parallelisieren trivial. Versuchen Sie, einen Computercluster mit Hunderten von Computern zu finden. Sie können die Solver so lange ausführen, wie Sie möchten, und dann die beste Lösung auswählen, die Sie bisher gefunden haben.
Eine Möglichkeit, die Unlösbarkeit anzugreifen, besteht darin, über das Problem im parametrisierten Komplexitätskontext nachzudenken.
Dies sind einige Beispiele in verschiedenen Klassen der W-Hierarchie:
Dies ist eine weitere Ebene von Komplexitäten, um NP-Probleme genauer zu klassifizieren. Wenn Sie mehr wollen, können Sie sich die Komplexität parametrisierter Schaltkreise und die W-Hierarchie von Downey et al. (1998) ansehen .
Und wenn Sie noch mehr wollen, lesen Sie die parametrisierte Komplexitätstheorie von Flum und Grohe .
Und schlussendlich:
Es ist bekannt, dass, wenn das Problem FPTAS (vollständig polynomiales Zeitnäherungsschema ) hat, es auch FPT ist (was offensichtlich ist). In umgekehrter Richtung ist jedoch nichts bekannt, und es gibt auch einige Arbeiten zum Verhältnis von PTAS und XP Die Beziehung zwischen PTAS und W-Hierarchie ist nicht sehr eng (zumindest weiß ich es im Moment nicht).
In einigen Fällen können auch andere Parameter festgelegt werden, z. B .: Die Länge eines längsten Pfads im Diagramm ist begrenzt und die Größe einer Lösung ist begrenzt (z. B. im Feedback-Vertex-Satz).
Möglicherweise glauben einige Leute, dass parametrisierte Komplexität in der Praxis nutzlos ist. Das ist aber falsch. Viele der parametrisierten Algorithmen werden in realen Anwendungen entdeckt. Hier ein Beispiel, wenn Sie einige Parameter korrigieren können:
Einer der schnellsten und genauesten heuristischen Algorithmen für TSP ist: Tour-Zusammenführung und Verzweigungszerlegung , bei der die Parametrisierung des Problems verwendet wird (nicht direkt, aber die Verzweigungszerlegung und der von ihnen verwendete dynamische Programmieransatz basieren auf einigen guten Annahmen).
Bei der NP-Vollständigkeit handelt es sich um den schlimmsten Fall der Unlösbarkeit. Abhängig davon, an welchem Problem Sie arbeiten, können viele Klassen von Instanzen in der Praxis in angemessener Zeit gelöst werden (obwohl Sie möglicherweise einen spezialisierteren Algorithmus benötigen, um die guten Laufzeiten zu erhalten).
Überlegen Sie, ob es eine effiziente Reduzierung von Ihrem Problem auf ein Problem mit guten verfügbaren Lösern gibt, wie z. B. Boolean Satisfiability oder Integer Linear Programming.
Lassen Sie mich in einigen Antworten kurz darauf eingehen, dass NP-vollständige Probleme in der Praxis immer wieder gelöst (oder angenähert) werden. Der Hauptgrund, warum Sie NP-vollständige Probleme in der Praxis lösen können, ist:
In der Praxis vorkommende Fälle sind nicht "worst case".
Ein weiterer Grund für die Diskrepanz ist:
Es ist schwierig, heuristische Algorithmen formal zu analysieren.
In der Praxis verwenden Sie heuristische Algorithmen, um Ihre NP-vollständigen Probleme zu lösen und hoffen auf das Beste. Die Ergebnisse sind oft umwerfend.
Ein weiteres Thema, das in anderen Antworten angesprochen wird, ist:
Manchmal sind exponentielle Algorithmen schnell genug.
Das hängt natürlich vom Problem ab. Wenn es um Big Data geht, haben wir die entgegengesetzte Maxime:
Manchmal sind nur quasilineare Algorithmen möglich.
Ich fürchte, die Menge hier ist eher theoretisch veranlagt. Sie erhalten möglicherweise bessere Antworten auf der Haupt-Stackexchange-Site.