Supposons que je suis un programmeur et que j'ai un problème NP-complet dont j'ai besoin pour le résoudre. Quelles méthodes sont disponibles pour traiter les problèmes des PNJ? Existe-t-il une enquête ou quelque chose de similaire sur ce sujet?
43
Réponses:
Il existe un certain nombre de stratégies bien étudiées; Ce qui convient le mieux à votre application dépend des circonstances.
Améliorer le pire temps d'exécutionO ( cn) pour la couverture de sommet avecc < 1,3 [1]; C'est une énorme amélioration par rapport au naïfΩ ( 2n) et pourrait rendre les tailles d'instance pertinentes pour vous.
En utilisant des informations spécifiques à un problème, vous pouvez souvent améliorer l'algorithme naïf. Par exemple, il existe desalgorithmes
Améliorez le temps d'exécution attendu
À l'aide de méthodes heuristiques, vous pouvez souvent concevoir des algorithmes rapides sur de nombreuses instances. Si ceux-ci incluent le plus que vous rencontrez dans la pratique, vous êtes en or. Des exemples sont SAT pour lesquels des solveurs assez impliqués existent, et l'algorithme Simplex (qui résout un problème polynomial, mais quand même). Une technique de base souvent utile est la ramification et la liaison .
Limitez le problème
Si vous pouvez faire plus de suppositions sur vos entrées, le problème peut devenir facile.
Vos entrées peuvent avoir des propriétés qui simplifient la résolution du problème, par exemple la planéité, le bipartiti ou l'absence d'un mineur pour les graphiques. Voir ici quelques exemples de classes de graphes pour lesquels CLIQUE est facile.
Une autre chose à considérer est la complexité paramétrée . certains problèmes peuvent être résolus dans le temps pour k un paramètre d'instance (degré maximum du nœud, poids maximal du bord, ...) et m constant. Si vous pouvez lier k par une fonction polylogarithmique en n dans votre paramètre, vous obtenez des algorithmes polynomiaux. Saeed Amiri donne des détails dans sa réponse .
De plus, certains problèmes admettent des algorithmes fonctionnant en temps pseudo-polynomial , c'est-à-dire que leur exécution est liée à une fonction polynomiale dans un nombre faisant partie de l'entrée; la vérification de primalité naïve est un exemple. Cela signifie que si les quantités encodées dans vos instances ont une taille raisonnable, vous pouvez utiliser des algorithmes simples qui se comportent bien pour vous.
Affaiblir le résultat
Cela signifie que vous tolérez des résultats erronés ou incomplets. Il y a deux saveurs principales:
Vous n'obtenez que le résultat correct avec une certaine probabilité. Il existe certaines variantes, notamment les algorithmes les plus connus de Monte-Carlo et Las Vegas . Un exemple célèbre est le test de primalité de Miller-Rabin .
Vous ne recherchez plus des solutions optimales mais presque optimales. Certains algorithmes admettent des limites relatives ("pas pire que le double de l'optimum"), d'autres des limites absolues ("pas pire que et l'optimum") sur l'erreur. Pour de nombreux problèmes, il est difficile de savoir dans quelle mesure ils peuvent être approchés. Il y en a qui peuvent être approximés arbitrairement bien en temps polynomial, alors que d'autres sont connus pour ne pas le permettre; vérifier la théorie des schémas d'approximation en temps polynomial .
Reportez-vous à la section Algorithmics for Hard Problems de Hromkovič pour un traitement approfondi.
la source
D'autres réponses ont abordé cette question d'un point de vue plus théorique. Voici une approche plus pratique.
Pour les problèmes de décision NP-complets "typiques" ( "existe-t-il un objet qui satisfasse à toutes ces contraintes?" ), Voici ce que j'essaierais toujours en premier:
Ecrivez un programme simple qui code votre instance problématique en tant qu’instance SAT .
Ensuite, prenez un bon solveur SAT , lancez-le (en utilisant l'ordinateur multi-cœur le plus rapide que vous possédez) et voyez ce qui se passe.
Essayez d’abord avec les plus petites instances pour avoir une idée du temps que cela pourrait prendre.
Étonnamment souvent, cette approche est bien meilleure que d'essayer de mettre en œuvre votre propre solutionneur spécifiquement pour votre problème actuel:
Les solveurs SAT sont très intelligents et bien optimisés. Ils surperforment facilement votre propre implémentation de la recherche arrière (peu importe le temps que vous perdez à optimiser votre code). Ils surpassent également facilement de nombreuses alternatives originales telles que les solveurs de programmation linéaire entier.
Cela nécessite très peu de programmation. L'étape 1 est relativement simple et n'est pas critique en termes de performances; vous pouvez utiliser des langages de script tels que Python. Quelqu'un d'autre s'est déjà chargé de mettre en œuvre tout ce dont vous avez besoin pour l'étape 2.
Pour les problèmes d’ optimisation NP-hard typiques ( "trouver la plus petite chose qui réponde à toutes ces contraintes" ), cette approche peut ne pas fonctionner.
Si vous pouvez facilement en faire un problème de décision ( "existe-t-il un objet de taille 4 qui réponde à toutes ces contraintes?" , "Et la taille 3?" ), Bien, suivez la même approche que ci-dessus pour les problèmes de décision.
Sinon, vous voudrez peut-être recourir à un résolveur heuristique qui tente de trouver une petite solution (pas nécessairement la plus petite solution). Par exemple:
Encodez votre problème en tant qu'instance MAX-SAT (pondérée) .
Utilisez les solveurs heuristiques du package UBCSAT . Les solveurs heuristiques parallélisent trivialement; essayez de trouver un cluster avec des centaines d’ordinateurs. Vous pouvez exécuter les solveurs aussi longtemps que vous le souhaitez, puis adopter la meilleure solution que vous avez trouvée jusqu'à présent.
la source
Complexité paramétrée
Une façon d’attaquer l’intractabilité consiste à réfléchir au problème dans le contexte de complexité paramétrée.
Voici quelques exemples dans différentes classes de la hiérarchie W:
Il existe un autre niveau de complexité pour classer les problèmes de NP de manière plus précise. Si vous en voulez davantage, vous pouvez vous pencher sur la complexité des circuits paramétrés et la hiérarchie W de Downey et al (1998).
Et si vous voulez encore plus, c'est bien de lire la théorie de la complexité paramétrée de Flum and Grohe .
Et enfin:
Complexité paramétrée versus algorithmes d'approximation:
On sait que si le problème a FPTAS ( schéma d'approximation entièrement polynomiale ), il l'est également (FPT) (ce qui est évident) La relation entre PTAS et la hiérarchie W n’est pas très étroite (du moins je ne le sais pas pour le moment).
Dans certains cas, nous pouvons également fixer différents paramètres, par exemple: la longueur du plus long chemin du graphe est liée et la taille de la solution est délimitée (par exemple, dans le jeu de sommets de retour), ...
Exemples d'utilisations pratiques:
Certaines personnes peuvent penser que la complexité paramétrée est inutile dans la pratique. Mais c'est faux. De nombreux algorithmes paramétrés sont découverts dans des applications du monde réel. Lorsque vous pouvez corriger certains paramètres, voici un exemple:
L'un des algorithmes heuristiques les plus rapides et les plus précis pour TSP est le suivant: Fusion de tours et décomposition de branches , qui utilise le paramétrage du problème (pas directement, mais la décomposition de branches et l'approche de programmation dynamique utilisée reposent sur de bonnes hypothèses).
la source
L'exhaustivité des NP concerne la pire intolérance. En fonction du problème sur lequel vous travaillez, de nombreuses classes d'instances peuvent être résolues dans un délai raisonnable (bien que vous ayez peut-être besoin d'un algorithme plus spécialisé pour obtenir les bonnes durées d'exécution).
Envisagez de vérifier s'il existe une solution efficace de votre problème à un problème avec de bons résolveurs disponibles, tels que la satisfaction booléenne ou la programmation linéaire en nombres entiers.
la source
la source
Bien que brièvement évoqué dans certaines des réponses, je tiens à souligner que, dans la pratique, les problèmes NP-complets sont résolus (ou approximés) à tout moment. La principale raison pour laquelle vous pouvez résoudre des problèmes NP-complets dans la pratique est:
Une autre raison de la différence est:
En pratique, vous utilisez des algorithmes heuristiques pour résoudre vos problèmes NP-complets et vous espérez que tout ira bien. Les résultats sont souvent stupéfiants.
Un autre problème abordé dans d'autres réponses est le suivant:
Cela dépend bien sûr du problème. Lorsque le Big Data est impliqué, nous avons la maxime opposée:
Je crains que la foule ici ne soit plutôt encline à la théorie. Vous obtiendrez peut-être de meilleures réponses sur le site stackexchange principal.
la source