Propagation: Trouver le plus court chemin dans une matrice

Bonjour à toutes et tous

Une nouvelle version de Propagation (la version 2.2 en date du 26 septembre 2024) est maintenant disponible aux téléchargements.

propagation v2 2

Elle est beaucoup plus rapide et surtout beaucoup moins gloutonne (càd que le temps de calcul par cellule augmente moins vite au fur et à mesure que les dimensions de la matrice augmentent) que la précédente.

Elle s’appuie sur une nouvelle logique qui écarte toute recherche de minima et tout tri d’où un gain de temps évident.

Elle n’utilise ni heuristique ni probabilités et l’algorithme continue d’être admissible càd fournit à coup sûr le meilleur résultat (du moins en termes de coût du chemin pour ce qui est du nombre d’étapes rien n’est prouvé).

J’espère que vous serez nombreux à venir l’essayer et me faire part de vos commentaires !

Merci

Bonsoir,

j'ai testé et je dois dire que cela fonctionne bien.

J'ai sur ma machine un code similaire fourni par h2so4, je vous l'ai fourni pour vous amuser à faire quelque tests de rapidité de l'un par rapport à l'autre. Attention ! C'est juste pour voir, mais si j'ai bien compris le votre il y a des accès "feuilles Excel" pour mettre en mémoire des données de parcours, donc cela devrait le ralentir quelque peu, non ?

Une fois de plus bienvenu dans le "petit" monde des contributeurs !

@ bientôt

LouReeD

Bonjour LouReeD et merci beaucoup pour tes retours. Je commence seulement à chercher à comprendre (j'étais trop absorbé par la finalisation de la version 2 de Propagation) le code de Hero Quest que tu m'as envoyé en MP et vu mon petit niveau en VBA cela risque de me prendre un peu de temps. Ton jeu me semble très prometteur je suis impatient de l'essayer, bravo pour le soin apporté à la présentation ! Et merci de ne m'avoir envoyé que le code qui m'intéresse le plus. Une fois que j'aurai assimilé le code de h2so4 je mènerai un banc d'essai Chrono sur des plateaux de grandes dimensions.

Effectivement le fait d'utiliser des feuilles Excel pour stocker des données n'est peut-être pas le plus judicieux en termes de temps de calcul. Si le code de h2so4 est significativement plus rapide j'essaierai de trouver un autre procédé plutôt que d'utiliser ces feuilles.

A bientôt pour un compte-rendu du comparatif

Bonsoir,

aviez vous vu ce sujet ?

@ bientôt

LouReeD

Merci beaucoup pour ce nouveau Post. Non je ne connaissais pas ce sujet très riche. Je commence à peine à me familiariser avec le code que tu m'as envoyé et avec ce nouveau sujet je sens que je n'ai pas fini de m'amuser… Merci aussi de m'avoir sensibilisé au problème du temps des accès feuille je pense qu'il ne devrait pas être trop difficile de procéder autrement; à voir les résultats en termes de temps de calcul.

Donc très reconnaissant à vous monsieur LouReeD

Bonsoir,

Alors ces temps de calculs, c'en est où ?

@ bientôt

LouReeD

Bonsoir,

Ca avance modestement disons que la matrice que j'avais prise pour exemple et qui était solvée en 8 minutes tout rond l'est maintenant en 24,31 secondes !

Tu sais que tu m'auras donné beaucoup de boulot avec ton foutu lien sur le Post précédent ! Cela aura pour avantage que je pourrai fournir une page d'aide plus documentée mais j'ambitionne maintenant de programmer un estimateur de durée réaliste.

Propagation v2.1 te devras beaucoup

Bonjour ,

Ce Post est en lien avec un autre déposé sur maths-forum.com. Il est destiné principalement aux matheux venant de ce forum. Il contient les fichiers qu'il est impossible de déposer dans les Posts de maths-forum.

En plus de ces fichiers je vais tenter d'expliquer un peu mieux le principe de Propagation:

La matrice Excel est convertie en Cubes. Une périphérie isolante (Cubes.Matrix = -1) s'ajoute aux Cubes de la matrice. Ainsi pour une matrice NbX x Nby x NbZ cellules il y a (NbX+2) x (NbY+2) x (NbZ+2) Cubes

Les Cubes sont des Arrays à trois dimensions : Cube(X, Y, Z) et ont trois propriétés définies par un type personnalisé :

  • .Matrix correspond aux valeurs de résistance telles qu'on les retrouve dans la feuille : "Matrice"
  • .Cumulation est la somme résistive du Cube par rapport au point de départ. Une fois que celui-ci a été calculé une première fois on ne revient plus dessus. C'est ce qui permet à l'algorithme d'avancer.
  • .Path stocke les adresses du chemin et ne sert à rien d'autre qu'à permettre à Excel de tracer le chemin en vert, c'est pour cela que je ne l'ai même pas présenté dans le logigramme

L'Array : "UnderStudy" comporte tous les Cubes en cours d'étude. Le premier élément confié à UnderStudy est le point de départ et il est solutionné niveau Cumulation. Viendront s'y ajouter ensuite et en premier lieu les Cubes immédiatement adjacents ou périphériques à ce point. Ces derniers sont dès lors solutionnés niveau Cumulation.

Une fois tous les Cubes autour du point de départ calculés celui-ci est exclu de UnderStudy. Le Cube appartenant à UnderStudy et de résistance minimale au niveau Cumulation devient alors le centre du même calcul que pour le point de départ.

Le calcul prend fin lorsque le Cube d'arrivée a été atteint. S'il ne l'est pas c'est qu'il ne peut pas l'être et le calcul prend fin une fois tous les Cubes de la matrice calculables calculés, le résultat est alors : "Sans solution"

Merci à tous ceux qui auront pris la peine de lire ce Post et un remerciement beaucoup plus appuyé à celui qui saura ou m'aidera à trouver l'équation juste pour l'estimateur de durées. Il figurera avec LouReeD de ce forum dans les remerciements de cette app !

Bonjour le forum,

Voici en avant-première la dernière version de mon Pathfinder. La mauvaise nouvelle c’est qu’il ne sait plus traiter que des entiers. Les bonnes nouvelles c’est que :

  • Il traite maintenant une grille de 16384x16384 (mon ordinateur est doté de 32Go de RAM) avec points de départ et d’arrivée aux deux coins opposés en seulement 5 minutes et 6 secondes*
  • Son code est devenu plus conventionnel, fini les variables à nom à rallonge et les rappels de type de données partout dans le code (type &, %) qui je le pensais amélioreraient la lisibilité du code mais c’était une erreur de ma part.
  • Son code est abondamment commenté.
  • Son code est plus court.

Pour info la plus grosse matrice adjacente que j’avais testé avec Propagation v2.1 était une 10000x10000 adja et elle avait réclamé plus de 21 heures de calcul ! Et avec un random à priori plus favorable.

Propagation v2.2 reste un algorithme admissible (càd qu’il fournit à coup sûr le meilleur chemin) ; il n’utilise aucune heuristique et aucune probabilité. Son gain de temps s’explique par le fait que j’ai pu supprimer tout tri et même toute recherche de minima si coûteuses en temps…

J’espère que vous serez curieux de l’essayer et avoir vos retours !

* Avec mon PC Icore5, en mode adjacent et avec un random =ENT(ALEA()*51) et hors temps de lecture de la feuille qui avoisine les 22 minutes.

Voici le code du module de Pathfinding :

' sfPathFinder2D v2.2.1   libre de droits, dernière révision : 05 oct 2024
'                         par Stéphane Fillon

' Ce module comporte toutes les procédures nécessaires à la lecture de la Worksheet et au Pathfinding. Vous pourrez l'utiliser seul dans vos applications
' L'intégralité des paramètres à ajuster à votre application est suivi d'un commentaire commençant par '# , facilitant leur recherche...
' La procédure VotreCode est un exemple de procédure minimaliste permettant d'utiliser les autres procédures de ce module.
Option Explicit
Option Private Module

Private Type Node
    IC As Integer       ' IC: Individual Cost; coût individuel du Node(= valeurs de la Worksheet)
    TC As Long          ' TC: Total Cost; addition des IC depuis le point de départ en passant par le plus court-chemin
    path As Byte        ' Info de parcours d'où on peut extraire un x et un y qui peuvent prendre les valeurs -1, 0 ou 1
    Calc As Boolean     ' Indique si le Node a été atteint
 End Type

Private Type Point2D
    x As Integer
    y As Long
End Type

Private Type lp        ' lp comme Liste de Points
    p2d() As Point2D
    b As Boolean
End Type

Private Const Ocol As Byte = 1  '# Numéro de colonne de l'origine (cellule supérieure gauche) de la matrice, (ex: 5 pour colonne "E")
Private Const Orow As Byte = 2  '# Numéro de Ligne de l'origine...

' Private WsMatrix As Worksheet '# Décommenter cette ligne
Private Nodes() As Node     ' Nodes(X, Y) est un Array 2D contenant tous les points de la matrice

' La procédure suivante est un exemple de code exécutable faisant appel aux trois procédures suivantes:
' - Sub Swallow         -> Lecture des valeurs de la WorkSheet pour les intégrer en tableau de type Node
' - Function fPath(     -> La fonction de Pathfinding renvoyant les adresses du chemin sous forme de String ex: "A3,B3,C3,C4,D4,...".
' - Function fRange(   ->  Retourne l'objet Range correspondant à la chaine retournée par fPath.
Public Sub VotreCode()
    Dim StartAddress$, ArrivalAddress$, path$
    Dim NbCol%, NbRow&
    Dim rngPath As Range
    Dim SommeChemin&, NbEtapes&

    On Error GoTo ErrorHandler

    StartAddress = "D3"     '# Adresse cellule de départ
    ArrivalAddress = "M12"  '# Adresse cellule d'arrivée
    NbCol = 10              '# Nombre de colonnes de la matrice
    NbRow = 10              '# Nombre de lignes de la matrice
    Set WsMatrix = Feuil1   '# Le nom de la feuille (ici par son codename)

    WsMatrix.Cells.Interior.Pattern = xlNone
    WsMatrix.Range(StartAddress).Interior.Color = vbRed
    WsMatrix.Range(ArrivalAddress).Interior.Color = 192

    Call Swallow(NbCol, NbRow) ' Ingurgitation données WorkSheet dans objets de type Node

    ' Calcul du + court-chemin renvoyé sous forme de String contenant les adresses ex: "E5,E6,F6,G6,..., L21"
    path = fPath(StartAddress, ArrivalAddress, PeripheralMode:=False)

    ' Gestion des cas particuliers : sans solution et départ et arrivée accolés
    If path = "WithoutSolution" Then MsgBox "Sans Solution !": Exit Sub
    If path = "" Then MsgBox "Arrivée et départ sont accolés !": Exit Sub

    Set rngPath = fRange(path)    ' fRange(Path) équivaut à Range(Path) sans la limitation à 255 caractères de l'argument Path

    ' Ce qui suit est un exemple d'exploitation de Path et rngPath
    rngPath.Interior.Color = vbGreen    ' 1ère exploitation du Range: rngPath, Tracé du chemin en vert
    SommeChemin = Application.WorksheetFunction.Sum(rngPath)    ' 2ème exploitation: calcul de la somme des coûts rencontrés
    NbEtapes = rngPath.Count     ' 3ème  exploitation: calcul du nombre d'étapes

    ' Affichage du MsgBox récapitulatif
    MsgBox "Coût total= " & SommeChemin & vbCr & _
           "Nombre d'étapes= " & NbEtapes

    Erase Nodes

Exit Sub
ErrorHandler:
    Erase Nodes
    MsgBox "VotreCode() Erreur lors de l'exécution de cette procédure", vbExclamation, "Erreur"
End Sub

' Intégration des données WorkSheet en variable tableau Nodes(X, Y).
Public Sub Swallow(ByVal NbCol%, ByVal NbRow&, Optional ByVal Lecture As Boolean = True)
    Dim x%, y&
    If Lecture Then ' Lecture de la feuille
        ReDim Nodes(NbCol + 1, NbRow + 1)
        ' On parcourt l'intégralité de la matrice
        For y = 1 To NbRow        ' De ligne à ligne
            For x = 1 To NbCol    ' Et de colonne à colonne à l'interieur d'une ligne
                With Nodes(x, y)
                    .IC = WsMatrix.Cells(y + Orow - 1, x + Ocol - 1)
                    If .IC >= 0 Then .TC = -1  ' TC = -1 signifie à ce stade que le Node n'a pas un coût infini et pourra être intégré à US
                End With
        Next x, y
    Else    ' Si la matrice n'a pas été modifiée il n'est pas nécessaire de relire la feuille
        For y = 1 To NbRow
            For x = 1 To NbCol
                With Nodes(x, y)
                    If .IC >= 0 Then .TC = -1
                    .Calc = False
                End With
        Next x, y
    End If
End Sub

' fPath assure le Pathfinding et renvoie une chaine de caractère composée des adresses des cellules entrant dans le plus court chemin.
Public Function fPath$(ByVal StartAddress$, ByVal ArrivalAddress$, Optional ByVal PeripheralMode As Boolean = False)

    Dim US() As lp      ' US comme UnderStudy = les cellules atteintes lors de la première sous-boucle mais dont on a pas encore calculé le voisinage.
    Dim VZ  As lp       ' VZ comme : Valeurs Zéro
    Dim cnd As Point2D  ' cnd comme : Current NoDe
    Dim p2dn As Point2D ' p2dn comme : Point2D Neighbour

    Dim TC& ' TC comme Total Cost soit le cumul des coûts individuels en passant par le plus court-chemin.
    Dim a&, i&, m&, uba&, TCmin&, TCmax&
    Dim x%
    Dim Xn%         ' Xn = x du Neighbour
    Dim Xsp%, Xap%  ' Xsp = x du Start Point: Xap = x de Arrival Point.
    Dim y&, Yn&, Ysp&, Yap& ' Mêmes principes pour y que pour x.
    Dim o As Byte   ' Valeur de décalage dont on pourra extraire le x et le y.
    Dim ubo As Byte ' ubo comme : UBound Offsets.
    Dim w As Byte
    Dim Offsets()   ' Les valeurs de décalage en x et y codées pour être stockées sous forme de byte.

    On Error GoTo ErrorHandler

    ' Détermination du point de départ
    Xsp = WsMatrix.Range(StartAddress).Column - Ocol + 1
    Ysp = WsMatrix.Range(StartAddress).Row - Orow + 1
    ' Détermination du point d'arrivée
    Xap = WsMatrix.Range(ArrivalAddress).Column - Ocol + 1
    Yap = WsMatrix.Range(ArrivalAddress).Row - Orow + 1
    ' Si le point d'arrivée se trouve sur une case infiniment chère fPath retourne : "WithoutSolution" et s'interrompt.
    If Nodes(Xap, Yap).IC < 0 Then fPath = "WithoutSolution": Exit Function

    ReDim US(0)         ' initialisation US.
    ReDim US(0).p2d(0)
    ' le premier élément d'US est le point de départ.
    US(0).p2d(0).x = Xsp
    US(0).p2d(0).y = Ysp
    US(0).b = True  'US(0) contient des points

    Nodes(Xsp, Ysp).TC = 0 ' Le TC du point de départ est égal à zéro

    If PeripheralMode Then ' 8 Nodes autour du Node principal
        Offsets = Array(1, 3, 5, 7, 0, 2, 6, 8)
    Else ' 4 Nodes partageant une face avec le Node central (Adjacent)
        Offsets = Array(1, 3, 5, 7)
    End If
    ubo = UBound(Offsets)

    ' BOUCLE PRINCIPALE                                                        '
    Do
        a = 0
        VZ.b = False    ' Il n'y a pas de valeurs zéro
        uba = UBound(US(TCmin).p2d)
        Do
            cnd = US(TCmin).p2d(a) ' Déclaration du noeud courant

            ' Parcours de toutes les cellules au voisinage immédiat du Current Node (cnd).
            For w = 0 To ubo
                o = Offsets(w)  ' Lecture de l'Offset
                Xn = cnd.x + Int(o Mod 3) - 1  ' Int(o Mod 3) - 1 peut prendre 3 valeurs : -1, 0 ou 1
                Yn = cnd.y + Int(o / 3) - 1    ' Int(o / 3) - 1 peut prendre 3 valeurs : -1, 0 ou 1

                p2dn.x = Xn: p2dn.y = Yn ' Création du Point2D Neighbour

                With Nodes(Xn, Yn) ' Un des Nodes voisins de cnd.
                    ' Le TC est < à 0 pour tous les Nodes ne présentant pas un coût infini...
                    '... voir procédure Swallow.
                    If .TC < 0 Then
                        ' le TC du Node voisin de cnd est égal à son coût individuel IC ajouté au...
                        ' ... Total Cost de ce MainNode.
                        TC = Nodes(cnd.x, cnd.y).TC + .IC ' le TC du voisin est égal à son IC ajouté au TC du Current Node
                        .TC = TC
                        .path = o       ' path stocke l'offset tel quel. On l'inversera en fin de procédure...
                                        '... dans le label PathFound ce qui permettra de remonter le chemin.
                        .Calc = True    ' Calc indique que le Node à été atteint.

                        If .IC = 0 Then     ' si l'Individual Cost du voisin est égal à zéro
                            If VZ.b Then    ' si il y a déjà des valeurs zéro
                                m = UBound(VZ.p2d) + 1
                                ' ajouter ce point à la liste de points Valeur Zéro
                                ReDim Preserve VZ.p2d(m)
                                VZ.p2d(m) = p2dn    ' Ajout du Neighbour à la liste de points de VZ
                            Else
                                ' Créer le premier point de Valeur Zéro
                                ReDim VZ.p2d(0)
                                VZ.p2d(0) = p2dn    ' Le premier point de VZ est le Neighbour
                                VZ.b = True ' Il y a des Valeurs Zero
                            End If
                        Else    ' Si l'Individual Cost du voisin est > à 0
                            ' si le TC du Neighbour est supérieur au TC maxi déjà connu redimmensionner US à ce nouveau TC
                            If TC > TCmax Then TCmax = TC: ReDim Preserve US(TC)
                            ' Ajout du Neighbour à la liste de points de US(TC)
                            If US(TC).b Then
                                i = UBound(US(TC).p2d) + 1
                                ReDim Preserve US(TC).p2d(i)
                                US(TC).p2d(i) = p2dn
                            Else
                                ReDim US(TC).p2d(0)
                                US(TC).p2d(0) = p2dn
                                US(TC).b = True
                            End If
                        End If
' Cells(Orow + Yn - 1, Ocol + Xn - 1).Interior.Color = vbMagenta ' Pour visualisation des Nodes atteints
                    End If
                End With
            Next w  ' on peut passer au prochain point voisin
            If Nodes(Xap, Yap).Calc Then GoTo PathFound ' SORTIE AVEC SOLUTION
' Cells(Orow + cnd.y - 1, Ocol + cnd.x - 1).Interior.Color = vbYellow ' Pour visualisation des Nodes finis de calculer
            a = a + 1   ' on peut passer au Current Node suivant.
        Loop Until a > uba

        If VZ.b Then ' Si l'on a atteint des valeurs zéro dans la sous-boucle Do Loop précédente...
            ' US(TCmin) récupère la liste de points de VZ
            ReDim US(TCmin).p2d(UBound(VZ.p2d))
            US(TCmin).p2d = VZ.p2d
        Else
            Erase US(TCmin).p2d ' Sinon on efface la liste de points de US(TCmin)
            ' et l'on recherche le prochain US non vide de points
            For i = TCmin + 1 To TCmax ' Nota : TCmax = Ubound(US)
                If US(i).b Then TCmin = i: Exit For    ' si US(i) contient des points
            Next i
            If i > TCmax Then fPath = "WithoutSolution": Exit Function ' SORTIE SANS SOLUTION
        End If

    Loop  ' Fin de la boucle principale.

PathFound:
    Dim adr$, path$
    x = Xap: y = Yap
    ' On remonte du point d'arrivée jusqu'au point de départ en utilisant l'inverse de l'offset des Nodes
    Do Until x = Xsp And y = Ysp
        adr = Cells(1, Ocol + x - 1).Address(False, False)
        path = Left$(adr, Len(adr) - 1) & Orow + y - 1 & "," & path
        o = 8 - Nodes(x, y).path     ' récupération de l'offset inversé
        x = x + Int(o Mod 3) - 1       ' extraction de la composante x
        y = y + Int(o / 3) - 1         ' extraction de la composante y
    Loop
    If path <> "" Then path = Left$(path, Len(path) - 1)   ' Suppression de la virgule finale
    fPath = path
Exit Function

ErrorHandler:
    MsgBox "Une erreur s'est produite lors de l'exécution de cette macro", vbExclamation, "sfPathFinder2D.fPath()"
Exit Function

End Function

' fRange renvoie un objet Range l'argument RefCel$ pouvant excéder 255 caractères ce
' qui justifie cette fonction. Cette fonction est loin d'être optimale !
Public Function fRange(ByVal RefCel$) As Range
    If RefCel = "" Then Exit Function
    ' Si "RefCel" fait moins de 256 caractères inutile de s'engager dans de long calculs...
    If Len(RefCel) < 256 Then Set fRange = WsMatrix.Range(RefCel): Exit Function

    Dim y As Byte, cpt%, v(), rng As Range

    Do While RefCel <> ""
       y = InStrRev(Left(RefCel, 244), ",")
       cpt = cpt + 1: ReDim Preserve v(cpt)

       If y = 0 Then
           v(cpt) = RefCel
           RefCel = ""
           Exit Do
       Else
           v(cpt) = Left$(RefCel, y - 1)
           RefCel = Mid$(RefCel, y + 1)
       End If
    Loop

    If RefCel <> "" Then v(cpt) = v(cpt) & "," & RefCel

    Set rng = WsMatrix.Range(v(1))
    For cpt = 2 To UBound(v)
        Set rng = Union(rng, WsMatrix.Range(v(cpt)))
    Next
    Set fRange = rng

End Function

Bonjour Stéphane1972 !

Deux choses : Lors de l'utilisation du USF en augmentant la taille de la matrice, les colonnes au-dessus de 10, n'ont pas la même largeur !
la deuxième : un très grand merci pour la référence de mon Pseudo ! Cela me fait plaisir ! Si je vous dis que je ne pense pas que ce soit nécessaire vous me répondrez que si ! Alors j'en prend la joie de le voir ! Merci encore.

Bon je ne comprend pas tout dans le code. Sinon comment fait-on pour créer des obstacle sur le chemin afin de forcer un détour ? J'ai réussi en mettant des 999 dans certaines cellules... Peut-être n'ai-je pas vu "l'option".

Bon et beau travail et cette distribution Free !

@ bientôt

LouReeD

Bonjour LouReed,

Je suis heureux que nos chemins se recroisent !

Oui ça Bugge un peu sur la largeur des colonnes je vais devoir me repencher un peu sur la procédure NewMatrix pour l’instant il y a quelque chose qui m’échappe…

C’est vous que je remercie encore pour les raisons que j’ai évoqué dans la page d’aide.

Pour créer des obstacles il faut rentrer un entier négatif par exemple -1

Sinon la page d’aide n’est pas à jour le mode de calcul en arrivée flottante a été supprimé et il faut impérativement spécifier un point d’arrivée sinon bug.

Bonne journée et @+

Stéphane

Juste un petit ColumnWidth avec une valeur de 20 et un RowHeight avec une valeur de 13.

Mais il est vrai qu'il y a sur ma machine un petit temps avant de voir les cellules se mettre en place... Pourtant au niveau de la feuille il n'y a que le masquage de colonnes et lignes non ?

@ bientôt

LouReeD

Oui la procédure NewMatrix est assez décevante je vais essayer de revoir ma copie ! Avez-vous testé de grosses matrices et si oui que pensez-vous des performances du Pathfinder à proprement parler ?

@+

Bonsoir,

je n'ai pas fait de gros tests encore... désolé.

Je pourrais essayer de la comparer au code h2so4

Je vous tiens au courant, restez sur la fréquence !

@ bientôt

LouReeD

Bonsoir et merci d'avance,

Je reste sur la fréquence

Bonjour,

Je tiens d’abord à remercier (bien tardivement…) Sébastien pour le gros travail qu’il a effectué pour l’amélioration de la mise à jour de ma description longue.

Obligé de relativiser sur les performances de mon Pathfinder qui ne sont bonnes qu’à condition que les valeurs dans la grille soient basses (ordre d’idée : étagées de 0 à 250). L’intérêt de ce Pathfinder reste :

  • D’être rapide si l’on respecte à peu près cette condition.
  • De ne pas « bloquer » quand la taille de la grille augmente.
  • De savoir résoudre efficacement les systèmes 3D.

Dans les précédentes versions de Propagation on recherchait par une boucle la case présentant le Coût Cumulé minimal et l’on pouvait alors calculer le coût cumulé de ses cases voisines et établir le lien de parenté. Le nombre de cases grappillées augmentant vite cette boucle se retrouvait en inflation plus ou moins rapide selon le mode Adjacent/Périphérique et 2D/3D. Ceci a pour effet de limiter la taille des grilles calculables dans un temps raisonnable.

Avec la version actuellement en ligne on ne recherche plus de coût cumulé minimal mais on enregistre ces coûts en tant qu’index dans une variable tableau de type liste de points :

Private Type Point2D
    X As Integer
    Y As Integer
End Type

Private Type lp     ' lp comme : Liste de Points
    p2d() As Point2D
    cp As Boolean    ' cp comme : Contient des Points
End Type

Après calcul du voisinage des nœuds courants on progresse dans le coût cumulé jusqu’à atteindre un booléen cp à True et on peut alors entamer une nouvelle itération de la boucle principale avec le nouveau coût cumulé incrémenté. Plus aucune boucle en inflation dans ce système donc un temps de calcul par cellule relativement stable quelles-que soient les dimensions de la grille.

Le fichier suivant (qui ne gère plus les obstacles et que les Bytes) offre la possibilité de tester des grilles de dimensions nettement supérieures à celles prises en charge par une feuille Excel classique.

Rechercher des sujets similaires à "propagation trouver court chemin matrice"