J'ai récemment commencé à jouer à Flow Free Game .
Reliez les couleurs correspondantes au tuyau pour créer un flux. Associez toutes les couleurs et couvrez tout le tableau pour résoudre chaque puzzle dans Flow Free. Mais attention, les tuyaux casseront s'ils se croisent ou se chevauchent!
J'ai réalisé que c'était juste un jeu de recherche de chemin entre une paire de points donnée avec des conditions qu'aucun chemin ne se chevauchent. Je souhaitais écrire une solution pour le jeu mais je ne sais pas par où commencer. Je pensais utiliser le backtracking mais pour les très grandes tailles de cartes, la complexité temporelle sera grande.
Existe-t-il un algorithme approprié pour résoudre le jeu efficacement? L'utilisation de l'heuristique pour résoudre le problème peut-elle aider? Donnez-moi juste un indice sur le point de départ, je le prendrai à partir de là.
J'ai observé dans la plupart des conseils que d'habitude
Cette observation est-elle correcte et peut-elle être utilisée pour la résoudre efficacement?
Le problème est évidemment dans NP: Si vous devinez une carte, il est facile (temps multiple) de vérifier si le problème est résolu.
Que ce soit NP-difficile (signifiant aussi difficile que tout autre problème dans NP, par exemple SAT), n'est pas clair. Les solveurs SAT modernes ne s’inquiéteront certainement pas et ne résoudront pas les grandes instances de toute façon (je suppose jusqu’à 100x100).
Ici, je viens de copier le commentaire de Nuclearman dans le PO:
La recherche de "formulation SAT de numberlink" et "NP-complétude de numberlink" conduit à un couple de références. Sans surprise, les deux plus intéressants sont en japonais. Le premier est la preuve papier complète de NP-complétude. La seconde décrit comment résoudre NumberLink à l'aide du solveur SAT, Sugar. -
Il existe plusieurs possibilités pour encoder le problème. Je vais en donner un que je pourrais rattraper rapidement.
j_random_hacker a noté que les cycles autonomes ne sont pas autorisés. L'encodage suivant les autorise. Ce problème rend le codage SAT un peu moins attrayant. La méthode la plus simple à laquelle je pouvais penser pour interdire les boucles autoportantes introduirait O (n ^ 2) nouvelles variables, où n
est le nombre de carreaux sur le tableau (distance de comptage du prochain puits pour chaque carreau), sauf si un codage de journal est utilisé. ceci, ce qui le ramènerait à O(n*log n)
, rendrait le problème plus difficile pour le solutionneur.
Une variable par carreau, type de pièce et couleur. Exemple si une variable X-Y-T-C
est vraie, elle indique que la tuile à la position X/Y est de type T
et a la couleur C
. Vous n'avez pas besoin du type de mosaïque vide car cela ne peut pas arriver dans une solution.
Définissez les variables pour le puits/les sources et dites qu'aucune autre tuile ne peut être un puits/source.
J'ai peut-être manqué quelque chose. Mais cela devrait être facilement corrigé.
Je soupçonne qu'aucun algorithme temps polynomial n'est garanti pour résoudre chaque instance de ce problème. Mais comme l'une des conditions est que chaque carré doit être recouvert d'un tuyau, une approche similaire à ce que les personnes et les ordinateurs utilisent pour résoudre/ Sudoku devrait bien fonctionner ici:
Lorsque vous choisissez un carré sur lequel vous souhaitez créer une branche, il est généralement judicieux de choisir un carré avec le moins de couleurs autorisées.
[EDIT: Il est important d'éviter la possibilité de former des "boucles" non valides de tuyau. Une façon de le faire est de conserver, pour chaque couleur autorisée i de chaque carré x, 2 bits d’information: si le carré x est connecté par un chemin de mosaïques de couleur i définies au premier point de terminaison de couleur i, et le même chose pour le deuxième point final i-coloré. Ensuite, lors de la récurrence, ne choisissez jamais une case ayant deux voisins avec le même bit défini (ou avec aucun bit défini) pour n'importe quelle couleur autorisée.]
En réalité, vous n'avez pas du tout besoin d'utiliser de déductions logiques, mais plus vous utilisez de déductions, meilleures et plus rapides, plus le programme s'exécutera rapidement, car elles réduiront (éventuellement considérablement) la quantité de récursivité. Certaines déductions utiles comprennent:
Des déductions plus avancées basées sur la connectivité de chemin pourraient aider davantage - par exemple, si vous pouvez déterminer que chaque chemin connectant une paire de connecteurs doit passer par un carré particulier, vous pouvez immédiatement attribuer cette couleur au carré.
Cette approche simple implique une solution complète sans aucune récursion dans votre exemple 5x5: les carrés de (5, 2), (5, 3), (4, 3) et (4, 4) sont forcés d’être en orange; (4, 5) est obligé d'être vert; (5, 5) est également obligé d'être vert en raison du fait qu'aucune autre couleur ne pourrait atteindre ce carré et en revenir; maintenant le chemin orange se terminant par (4, 4) n'a nulle part où aller sauf pour compléter le chemin orange à (3, 4). Aussi (3, 1) est forcé d'être rouge; (3, 2) est forcé à être jaune, ce qui oblige à son tour (2, 1), puis (2, 2) à être rouge, ce qui force finalement le trajet jaune à terminer en (3, 3). Le tuyau rouge en (2, 2) oblige (1, 2) à être bleu, et les chemins rouge et bleu finissent par être complètement déterminés, "se forçant mutuellement" au fur et à mesure.
J'ai trouvé un article sur Inutilement complexe qui explique complètement comment utiliser SAT pour résoudre ce problème.
Le code est également open-source, vous pouvez donc le regarder (et le comprendre) en action.
Je vais vous en citer un extrait qui décrit les règles que vous devez implémenter dans SAT:
Chaque cellule se voit attribuer une seule couleur.
La couleur de chaque cellule de point de terminaison est connue et spécifiée.
Merci @Matt Zucker pour avoir créé cela!
J'aime les solutions similaires à la pensée humaine. Vous pouvez (assez facilement) obtenir la réponse d'un Sudoku par la force brute, mais il est plus utile d'obtenir un chemin que vous auriez pu suivre pour résoudre le casse-tête.
J'ai observé dans la plupart des planches que 1.Pour les points les plus éloignés, vous devez suivre le chemin le long de Edge. 2.Pour les points les plus proches les uns des autres, suivez le chemin direct s'il en existe un. Cette observation est-elle correcte et peut-elle être utilisée pour la résoudre efficacement?
Ce sont vrais "la plupart du temps", mais pas toujours.
Je remplacerais votre première règle par celle-ci: si les deux éviers sont le long de Edge, vous devez suivre le chemin le long de Edge. (Vous pouvez construire un contre-exemple, mais c'est vrai la plupart du temps). Une fois que vous avez créé un chemin le long de l’Edge, les blocs situés le long de l’Edge doivent être considérés comme faisant partie de l’Edge. Votre algorithme essaiera donc de suivre le nouvel Edge créé par le canal précédent. J'espère que cette phrase a du sens ...
Bien sûr, avant d’utiliser ces règles "la plupart du temps", vous devez suivre des règles absolues (voir les deux déductions du message de j_random_hacker).
Une autre chose est d'essayer d'éliminer les conseils qui ne peuvent pas aboutir à une solution. Appelons un tuyau non fini (celui qui part d'un évier mais n'atteint pas encore l'autre évier) un serpent et le dernier carré du tuyau non fini s'appellera la tête du serpent. Si vous ne pouvez pas trouver un chemin de carrés vides entre les deux têtes de même couleur, cela signifie que votre tableau ne peut pas mener à une solution et doit être jeté (ou vous devez revenir en arrière, en fonction de votre implémentation).
Le jeu en flux libre (et d’autres jeux similaires) accepte comme solution valable un plateau où se trouvent deux lignes de la même couleur côte à côte, mais je crois qu’il existe toujours une solution sans lignes côte à côte. Cela signifierait que tout carré qui n'est pas un évier aurait exactement deux voisins de la même couleur et qu'un évier en aurait exactement un. Si la règle s'avère toujours vraie (je crois que c'est le cas, mais ne peut pas le prouver), ce serait une contrainte supplémentaire pour réduire votre nombre de possibilités. J'ai résolu certains des casse-tête de Free Flow en utilisant des lignes côte à côte, mais la plupart du temps, je trouvais une autre solution sans elles. Je n'ai pas vu de lignes côte à côte sur le site Web des solutions de Free Flow.
Quelques règles conduisant à une sorte d'algorithme permettant de résoudre les niveaux en flux, basées sur les IOS colonnes de Big Duck Games, cette société semble produire les versions canoniques. Le reste de cette réponse ne suppose aucun mur, pont ou déformation.
Même si vous êtes étrangement bons, les énormes planches carrées de 15x18 sont un bon exemple de la façon dont vous semblez vous y prendre de manière à vous coincer juste avant la fin et à devoir recommencer pratiquement à zéro. Ceci est probablement dû à la complexité temporelle exponentielle déjà mentionnée dans le cas général. Mais cela ne signifie pas qu’une simple stratégie n’est pas extrêmement efficace pour la plupart des conseils.
Les blocs ne sont jamais laissés vides. Par conséquent, les blocs orphelins signifient que vous avez mal agi.
Les cellules voisines de même couleur doivent être connectées. Ceci élimine 2x2 blocs de la même couleur et sur les triangles de la grille hexagonale de 3 cellules voisines.
Vous pouvez souvent faire des progrès permanents en établissant qu'une couleur va ou est exclue d'un certain carré.
En raison des points 1 et 2, sur la grille hexagonale des planches de forme hexagonale, un tuyau longeant un bord est généralement coincé le long de la sortie, ce qui déplace efficacement le bord extérieur et rend le panneau plus petit le processus peut être répété. Il est prévisible que les types de conditions environnantes garantissent et quels types peuvent rompre ce cycle pour les deux types de réseau.
La plupart, sinon toutes les variantes tierces que j'ai trouvées manquent de 1 à 4, mais étant donné ces contraintes, il peut être difficile de générer des conseils valides.
Réponse:
Le point 3 suggère qu'une valeur soit stockée pour chaque cellule pouvant être soit une couleur, soit un ensemble de valeurs fausses/indéterminées, une pour chaque couleur.
Un solveur pourrait utiliser à plusieurs reprises les points 1 et 2 avec les données stockées pour le point 3 sur de petits voisinages de chemins autour des extrémités de tuyaux pour définir de plus en plus les couleurs ou définir les valeurs indéterminées sur false.