Résoudre un labyrinthe de nombres

18

Mon fils de 8 ans s'est ennuyé à créer des labyrinthes conventionnels et a commencé à créer des variantes qui ressemblent à ceci:

Échantillon de trémie

L'idée est de partir de x et d'atteindre o via les règles normales. De plus, vous pouvez "sauter" de tout entier à tout autre entier , mais vous devez payerdollars pour le privilège. Le but est de résoudre le labyrinthe au moindre coût. Dans l'exemple ci-dessus, nous pourrions passer de x à o via x-14-18-27-28-o au coût 5, mais il est moins cher de passer x-13-11-9-8-29-28-o pour seulement 4.ab|ab|

Voici donc ma question: quelle est la meilleure solution (en termes de temps de fonctionnement asymptotique) à laquelle vous pouvez penser pour résoudre ce problème? Vous pouvez faire des hypothèses raisonnables sur le format d'entrée.

Remarque: J'utilise la balise "puzzles" ici parce que j'ai une réponse en tête, mais je ne suis pas sûr qu'elle soit optimale et j'aimerais voir si quelqu'un d'autre peut améliorer ma solution. (Ici est le nombre d'entiers dans le labyrinthe.)O(n2)n

Fixee
la source
7
Accessoires à votre enfant pour créer de tels puzzles créatifs et mathématiques!
bbejot
2
@bbejot Vous devriez voir certaines des choses qu'il me demande ... parfois je ne peux pas répondre à ses questions. Par exemple, math.stackexchange.com/questions/33094/...~~V~~singular~~3rd
Fixee
1
Je ne suis pas sûr que vos calculs de coûts soient corrects. x-14-18-27-28-o devrait coûter et x-13-11-9-8-29-28-o devrait coûter . 4+9+1=142+2+1+21+1=27
Dave Clarke
1
@Dave toutes les transitions ne sont pas des sauts. Nous pourrions écrire 'ab' pour les sauts (qui ont un coût de ) et 'a-> b' pour marcher dans le graphique de a à b (qui a un coût de ), ce qui n'est autorisé que si ils sont accessibles sans casser un mur dans le labyrinthe. Dans cette notation, nous avons x-> 14-18-> 27-28-> o et un coût de 5 et x-> 13-11-> 9-8-> 29-28-> o. Je mince Fixee n'a pas introduit cette notation car elle est redondante: il n'y a aucune raison de sauter deux fois et donc les sauts et les promenades dans le labyrinthe alterneront. |ab|0
Artem Kaznatcheev
2
C'est un excellent problème de devoirs!
Jeffε

Réponses:

15

Vous pouvez résoudre ce problème en utilisant une variante de l'algorithme de Dijkstra. Nous pouvons éviter de ne pas effectuer toutes les mises à jour de distance lorsque nous visitons un nouveau nœud. Si nous visitons un nœud , nous devons seulement mettre à jour les distances de tout ce qui peut être parcouru de à 0, et mettre à jour les distances aux deux nœuds et avec les valeurs les plus proches de inférieures et supérieures à qui ne l'ont pas été encore choisi.O(nlogn)yyyy+yy

Ces mises à jour sont suffisantes pour garder le tas renvoyant l'élément minimum car tout nœud le plus proche vers lequel vous sautez doit avoir été numériquement juste au-dessus ou juste en dessous d'un nœud déjà visité.

Chaque nœud est mis à jour à 0 au plus une fois (si nous sortons tous les nœuds à distance nulle de la file d'attente pour éviter un comportement quadratique), et chaque fois que nous ajoutons un nœud, nous ne faisons O (1) que d'autres mises à jour. Trouver les valeurs et peut être fait en temps linéaire si nous gardons également une liste ordonnée à double liaison de tous les nœuds, triée par leurs valeurs entières. La création de cette liste à double liaison prend du temps , et enfin les mises à jour et les sauts du tas prennent du temps , pour un temps d'exécution total deyy+O(nlogn)O(n)O(nlogn)O(nlogn)

Dave
la source
Cela peut probablement être un peu amélioré en utilisant le tri et les files d'attente prioritaires qui sont spécialisés pour les entiers, mais vous ne pouvez pas faire mieux que le tri des entiers, comme le montre la réduction suivante: si nous avons une liste de valeurs entières , définissez x pour être deux fois le minimum de ces derniers et o pour être deux fois le maximum. Créez une région avec des valeurs 2 x i et 2 x i + 1 pour l'autre x i . La meilleure solution passe par chaque région dans l'ordre trié par x i , et produit ainsi un tri desx1,,xnxo2xi2xi+1xixi valeurs. xi
Dave
Dave a raison, cela peut être réduit à en ne mettant à jour que y + et y - . De plus, au lieu de connecter chaque nœud d'une région à tous les autres nœuds de la région, ils doivent uniquement être connectés à 1 ou 2 autres nœuds de la région (en créant un chemin). Ainsi, chaque nœud n'a que jusqu'à 4 bords. Ensuite, l'algorithme de Dijkstra (avec une file d'attente prioritaire min) peut être appliqué en accordant le temps O ( n l g n ) . O(nlgn)y+yO(nlgn)
bbejot
@bbejot: Mais si c'est le cas, la file d'attente prioritaire intégrale de Thorup n'améliore-t-elle pas le temps d'exécution à , ou même à O ( n ) avec une technique de bucketing supplémentaire dans la situation non dirigée? O(nloglogn)O(n)
Hsien-Chih Chang 張顯 之
4

Je pense que pourrait être le meilleur que vous puissiez obtenir.O(n2)

Il semble naturel de convertir cela en un problème de chemin le plus court avec un nœud de départ spécial (x) et un nœud de fin (0). Il y aurait également un autre nœud pour chacun des nombres. Les deux x et 0 ont des bords de poids 0 à tous les nœuds numériques qui sont accessibles dans le labyrinthe. Tous les nœuds numériques sont connectés soit avec un poids 0 (si les nombres sont accessibles en labyrinthe), soit avec la différence entre les nombres (si ce n'est pas le cas avec le labyrinthe).

Le chemin le plus court dans ce graphique ne peut pas être résolu en moins de car le graphique a à peu près n 2 arêtes et, dans le pire des cas, il faudrait voir chaque cas une fois. En tant que tel, l'algorithme de Dijkstra'a pour le chemin le plus court prend du temps O ( n 2 ) et est optimal dans le pire des cas.O(n2)n2O(n2)

bbejot
la source
O(n2)O(n2lgn)
1
rO(r2)
O(nlogn)O(r2+nlogn)Ω(nlogn)
Ω(n2)