• La distance la plus courte entre deux points. Savez-vous pourquoi il est plus en ligne droite qu'en arc de cercle ? Détermination de la distance entre deux lignes qui se croisent

    01.02.2022

    Après avoir tracé deux points au tableau noir à la craie, le professeur propose au jeune élève une tâche : tracer le chemin le plus court entre les deux points.

    L'étudiant, après réflexion, trace avec diligence une ligne sinueuse entre eux.

    - C'est le chemin le plus court ! le professeur est surpris. - Qui t'a appris ça ?

    - Mon père. Il est un chauffeur de taxi.

    Le dessin d'un écolier naïf est, bien sûr, anecdotique, mais ne souririez-vous pas si on vous disait que l'arc en pointillé de la fig. 1 est le chemin le plus court du Cap de Bonne-Espérance à la pointe sud de l'Australie !

    Encore plus frappante est la déclaration suivante : illustrée à la Fig. 2 aller-retour du Japon au canal de Panama est plus court que la ligne droite tracée entre eux sur la même carte !

    Riz. 1. Sur une carte marine, la route la plus courte du cap de Bonne-Espérance à la pointe sud de l'Australie n'est pas indiquée par une ligne droite (« loxodrome »), mais par une courbe (« orthodromie »)


    Tout cela ressemble à une blague, mais en attendant devant vous se trouvent des vérités indiscutables, bien connues des cartographes.




    Riz. 2. Il semble incroyable que le chemin courbe reliant Yokohama sur la carte marine au canal de Panama soit plus court qu'une ligne droite tracée entre les mêmes points


    Pour clarifier la question, il faudra dire quelques mots sur les cartes en général et sur les cartes marines en particulier. Représenter des parties de la surface terrestre sur papier n'est pas une tâche facile, même en principe, car la Terre est une sphère, et on sait qu'aucune partie de la surface sphérique ne peut être déployée sur un plan sans plis ni cassures. Involontairement, il faut s'accommoder des déformations inévitables des cartes. De nombreuses façons de dessiner des cartes ont été inventées, mais toutes les cartes ne sont pas exemptes de défauts : certaines présentent des distorsions d'un certain type, d'autres d'un autre type, mais il n'existe pas de cartes sans distorsions du tout.

    Les marins utilisent des cartes dessinées selon la méthode d'un ancien cartographe et mathématicien hollandais du XVIe siècle. Mercator. Cette méthode s'appelle la projection de Mercator. Il est facile de reconnaître une carte marine à sa grille rectangulaire : les méridiens y sont représentés par une série de droites parallèles ; cercles de latitude - également en lignes droites perpendiculaires au premier (voir Fig. 5).

    Imaginez maintenant que vous vouliez trouver le chemin le plus court d'un port océanique à un autre sur le même parallèle. Sur l'océan, tous les chemins sont possibles, et il est toujours possible de s'y rendre par le chemin le plus court si l'on sait où il se trouve. Dans notre cas, il est naturel de penser que le chemin le plus court passe par le parallèle sur lequel se trouvent les deux ports : après tout, sur la carte, c'est une ligne droite, et quoi de plus court qu'un chemin droit ! Mais on se trompe : le chemin le long du parallèle n'est pas du tout le plus court.

    En effet : à la surface d'une sphère, la distance la plus courte entre deux points est l'arc de grand cercle qui les relie. Mais le cercle de parallèle petit un cercle. L'arc d'un grand cercle est moins courbé que l'arc de n'importe quel petit cercle passant par les deux mêmes points : un rayon plus grand correspond à une courbure plus petite. Tirez le fil sur le globe entre nos deux pointes (cf. Fig. 3) ; vous vous assurerez qu'il ne se trouve pas du tout le long du parallèle. Un fil tendu est un indicateur incontestable du chemin le plus court, et s'il ne coïncide pas avec un parallèle sur un globe, alors sur une carte marine, le chemin le plus court n'est pas indiqué par une ligne droite: rappelez-vous que des cercles de parallèles sont représentés sur de tels une carte par des lignes droites, toute ligne qui ne coïncide pas avec une ligne droite, il y a courbe .



    Riz. 3. Un moyen simple de trouver le chemin vraiment le plus court entre deux points : il faut tirer un fil sur le globe entre ces points


    Après ce qui a été dit, il devient clair pourquoi le chemin le plus court sur la carte marine n'est pas représenté comme une ligne droite, mais comme une ligne courbe.

    Ils disent que lors du choix de la direction du chemin de fer Nikolaev (aujourd'hui Oktyabrskaya), il y avait des disputes sans fin sur la manière de le poser. Les différends ont pris fin grâce à l'intervention du tsar Nicolas Ier, qui a résolu le problème littéralement « simplement » : il a relié Saint-Pétersbourg à Moscou le long de la ligne. Si cela avait été fait sur une carte Mercator, cela aurait été une surprise gênante : au lieu d'une ligne droite, la route se serait avérée être une courbe.

    Quiconque n'évite pas les calculs peut être convaincu par un simple calcul que le chemin qui nous semble courbe sur la carte est en réalité plus court que celui que nous sommes prêts à considérer droit. Que nos deux ports soient situés sur le 60e parallèle et soient séparés par une distance de 60°. (Que ces deux ports existent réellement est, bien sûr, sans importance pour le calcul.)



    Riz. 4. Au calcul des distances entre les points A et B de la balle le long de l'arc de parallèle et le long de l'arc de grand cercle


    Sur la fig. 4 points O- centre du globe, UN B - l'arc du cercle de latitude sur lequel se trouvent les ports A et B; dans ses 60°. Le centre du cercle de latitude est en un point DE Imaginez que depuis le centre O du globe est tracé par les mêmes ports en arc de grand cercle : son rayon OB = OA = R ; il passera près de l'arc tracé UN B, mais ça ne correspond pas.

    Calculons la longueur de chaque arc. Depuis les pointes MAIS et À se trouvent à une latitude de 60°, puis les rayons OA et VO se maquiller avec SE(l'axe du globe) un angle de 30°. Dans un triangle rectangle ASO jambe CA (=r), faisant face à un angle de 30° est égal à la moitié de l'hypoténuse JSC ;

    moyens, r=R/2 Longueur de l'arc UN B est le sixième de la longueur du cercle de latitude, et puisque ce cercle a la moitié de la longueur du grand cercle (correspondant à la moitié du rayon), alors la longueur de l'arc du petit cercle



    Pour déterminer maintenant la longueur de l'arc d'un grand cercle tracé entre les mêmes points (c'est-à-dire le chemin le plus court entre eux), nous devons connaître la grandeur de l'angle AOW. Accord COMME, en soustrayant l'arc à 60° (petit cercle), est le côté d'un hexagone régulier inscrit dans le même petit cercle ; c'est pourquoi AB \u003d r \u003d R / 2

    Tracer une ligne droite od, centre de liaison O le globe avec le milieu accords UN B, obtenir un triangle rectangle APD, où est l'angle RÉ- droit:

    DA= 1/2 AB et OA=R.

    sinAOD=AD : AO=R/4 :R=0,25

    De là on trouve (selon les tableaux) :

    =14°28",5

    et donc

    = 28°57".

    Maintenant, il n'est pas difficile de trouver la longueur souhaitée du chemin le plus court en kilomètres. Le calcul peut être simplifié si l'on se souvient que la longueur d'une minute d'un grand cercle du globe est

    On apprend que le trajet le long du cercle de latitude, matérialisé sur la carte marine par une ligne droite, est de 3333 km, et le trajet le long du grand cercle - le long de la courbe sur la carte - de 3213 km, soit 120 km plus court.

    Armé d'un fil et d'un globe à portée de main, vous pouvez facilement vérifier l'exactitude de nos dessins et vous assurer que les arcs des grands cercles se trouvent vraiment comme indiqué sur les dessins. Montré sur la fig. 1 comme si la route maritime "droite" de l'Afrique à l'Australie était de 6020 miles, et la "courbe" - ​​5450 miles, c'est-à-dire plus courte de 570 miles, ou 1050 km. La route aérienne "directe" sur la carte maritime de Londres à Shanghai traverse la mer Caspienne, tandis que la route vraiment la plus courte se trouve au nord de Saint-Pétersbourg. Il est clair quel rôle ces problèmes jouent dans l'économie de temps et de carburant.

    Si à l'ère de la navigation à voile, le temps n'était pas toujours valorisé - alors le "temps" n'était pas encore considéré comme de l'"argent", alors avec l'avènement des bateaux à vapeur, il faut payer pour chaque tonne supplémentaire de charbon consommée. C'est pourquoi, de nos jours, les navires naviguent le long du chemin le plus court, en utilisant souvent des cartes réalisées non pas dans le Mercator, mais dans la projection dite "centrale": sur ces cartes, les arcs de grands cercles sont représentés par des lignes droites.

    Pourquoi, alors, les anciens navigateurs utilisaient-ils des cartes aussi trompeuses et choisissaient-ils des chemins défavorables ? C'est une erreur de penser qu'autrefois ils ne connaissaient pas la caractéristique désormais indiquée des cartes marines. La question s'explique, bien sûr, non pas par cela, mais par le fait que les cartes dessinées selon la méthode Mercator, ainsi que les inconvénients, présentent des avantages très précieux pour les marins. Une telle carte, premièrement, représente de petites parties séparées de la surface terrestre sans distorsion, en préservant les coins du contour. Ceci n'est pas contredit par le fait qu'à distance de l'équateur, tous les contours sont sensiblement étirés. Aux hautes latitudes, l'étirement est si important qu'une carte marine inspire à une personne peu familière avec ses particularités une idée complètement fausse de la taille réelle des continents : le Groenland semble avoir la même taille que l'Afrique, l'Alaska est plus grand que l'Australie, bien que le Groenland soit 15 fois plus petit que l'Afrique, et l'Alaska avec le Groenland la moitié de la taille de l'Australie. Mais un marin qui connaît bien ces caractéristiques de la carte ne peut s'y tromper. Il les supporte, d'autant plus que, sur de petites surfaces, une carte marine donne une image exacte de la nature (fig. 5).

    D'autre part, la carte marine facilite grandement la solution des tâches de pratique de la navigation. C'est le seul type de carte sur laquelle la trajectoire d'un navire sur une route constante est représentée par une ligne droite. Suivre une « route constante », c'est garder invariablement une direction, une « rhume » déterminée, c'est-à-dire aller de manière à traverser tous les méridiens selon un angle égal. Mais ce chemin ("loxodrome") ne peut être représenté comme une ligne droite que sur une carte sur laquelle tous les méridiens sont des lignes droites parallèles les unes aux autres. Et puisque sur le globe les cercles de latitude se coupent à angle droit avec les méridiens, alors sur une telle carte les cercles de latitude devraient être des lignes droites perpendiculaires aux lignes des méridiens. Bref, on arrive précisément à la grille de coordonnées qui constitue un trait caractéristique de la carte marine.




    Riz. 5. Carte nautique ou Mercator du globe. Sur de telles cartes, les dimensions des contours éloignés de l'équateur sont fortement exagérées. Lequel, par exemple, est le plus grand : le Groenland ou l'Australie ? (réponse dans le texte)


    La prédilection des marins pour les cartes Mercator est désormais compréhensible. Voulant déterminer le cap à suivre en se rendant au port désigné, le navigateur applique une règle aux extrémités du chemin et mesure l'angle qu'il fait avec les méridiens. Restant en pleine mer tout le temps dans cette direction, le navigateur amènera avec précision le navire à la cible. Vous voyez que le "loxodrome" est, certes pas le plus court et pas le plus économique, mais à certains égards un moyen très commode pour un marin. Pour atteindre, par exemple, du cap de Bonne-Espérance à la pointe sud de l'Australie (voir Fig. 1), il faut toujours garder le même cap S 87°, 50". En attendant, afin d'amener le navire au même point final du chemin le plus court (le long du " "), il faut, comme on peut le voir sur la figure, changer continuellement le cap du navire: partir du cap S 42 °, 50 "et terminer par le cap N 53°. 50" (dans ce cas, le chemin le plus court n'est même pas praticable - il repose sur le mur de glace de l'Antarctique).

    Les deux chemins - le long du "loxodrome" et le long de "l'orthodromie" - ne coïncident que lorsque le chemin le long du grand cercle est représenté sur la carte marine comme une ligne droite : lors du déplacement le long de l'équateur ou le long du méridien. Dans tous les autres cas, ces chemins sont différents.

    (Géométrie descriptive)
  • CD (CXDX, C2D2) affiché sous forme de point C5 = D5 A5B5équivaut à...
    (Géométrie descriptive)
  • Détermination de la distance entre deux plans parallèles
    Détermination de la distance entre deux plans parallèles en position générale 01| X il convient de le réduire au problème de la détermination de la distance entre les deux mêmes plans, transformés en la position des saillants. Dans ce cas, la distance entre les plans est définie comme la perpendiculaire entre les lignes, ...
    (Géométrie descriptive)
  • Détermination de la distance entre deux lignes qui se croisent
    Si vous voulez déterminer la distance la plus courte entre deux lignes qui se croisent, vous devez changer deux fois les systèmes de plans de projection. Lors de la résolution de ce problème, le direct CD (CXDX, C2D2) affiché sous forme de point C5 = D5(Fig. 198). Distance de ce point à la projection A5B5équivaut à...
    (Géométrie descriptive)
  • Angle entre deux droites qui se croisent
    Il s'agit de l'angle entre deux lignes qui se croisent parallèlement aux données. Ainsi, cette tâche est similaire à la précédente. Pour le résoudre, vous devez prendre un point arbitraire et tracer deux lignes droites à travers celui-ci, parallèles aux lignes droites obliques données, et en utilisant des transformations de projection, déterminer l'angle souhaité....
    (Fondements de la géométrie descriptive. Un petit cours et une collection de problèmes.)
  • Détermination de la distance entre deux lignes parallèles
    Le problème est résolu par la méthode du double remplacement des plans de projection. Au stade final, l'un des plans de projection doit être perpendiculaire à l'une des lignes d'intersection. Ensuite, la distance la plus courte entre eux est déterminée par la valeur du segment de la perpendiculaire à l'autre ligne oblique (Fig. 199)....
    (Géométrie descriptive)
  • Le chemin le long de la ligne pointillée dans l'image est plus court que le chemin le long de la ligne continue. Et maintenant un peu plus en détail sur l'exemple des routes maritimes :

    Si vous naviguez dans un cap constant, alors la trajectoire du navire à la surface de la terre sera une courbe, appelée en mathématiques logarithmiquespirale.

    En navigation, cette ligne complexe à double courbure est appelée loxodromie, qui signifie en grec "course oblique".

    Cependant, la distance la plus courte entre deux points du globe se mesure le long d'un arc de grand cercle.

    L'arc de grand cercle s'obtient comme une trace à partir de l'intersection de la surface terrestre avec un plan passant par le centre de la terre, pris comme une boule.

    En navigation, l'arc de grand cercle s'appelle grand cercle, qui signifie "tout droit". La deuxième caractéristique du grand cercle est qu'il croise les méridiens à des angles différents (Fig. 29).

    La différence de distances entre deux points à la surface de la terre le long du loxodrome et de l'orthodrome n'a d'importance pratique que pour les grandes traversées océaniques.

    Dans des conditions normales, cette différence est négligée et la navigation s'effectue sur un cap constant, c'est-à-dire par loxodromie.

    Pour dériver l'équation, on prend des loxodromies (Fig. 30, un) deux points MAIS et À, la distance entre eux est tout simplement petite. En dessinant des méridiens et un parallèle à travers eux, nous obtenons un triangle sphérique rectangle élémentaire ABC. Dans ce triangle, l'angle formé par l'intersection du méridien et du parallèle est droit, et l'angle PnUN Bégal au cap du navire K. Katet CA représente un segment d'arc méridien et peut être exprimé

    R - rayon de la Terre pris comme une sphère ;

    Δφ - incrément élémentaire de latitude (différence de latitudes).

    jambe SW représente un segment d'arc parallèle

    où r - rayon du parallèle ;

    Δλ - différence élémentaire de longitudes.

    Du triangle OO 1 C on peut trouver que

    Puis dans la forme finale la jambe SW peut s'exprimer ainsi :

    En supposant un triangle sphérique élémentaire abc pour plat, écrivez

    Après réduction R et en remplaçant les petits incréments élémentaires de coordonnées par des infinitésimaux, on a

    Nous intégrons l'expression résultante dans la gamme de φ 1, λ 1 à φ 2, λ 2 considérant la valeur de tgK comme une valeur constante :

    Sur le côté droit, nous avons une intégrale tabulaire. Après substitution de sa valeur, on obtient l'équation loxodromique sur la boule

    L'analyse de cette équation nous permet de tirer les conclusions suivantes :

    Aux parcours de 0 et 180 °, la loxodrome se transforme en un arc de grand cercle - un méridien;

    Aux caps de 90 et 270°, la loxodrome coïncide avec la parallèle ;

    La loxodrome ne franchit chaque parallèle qu'une seule fois, et chaque méridien un nombre incalculable de fois. ceux. s'approchant en spirale du pôle, il ne l'atteint pas.

    La navigation à cap constant, c'est-à-dire le long de la loxodrome, bien que ce ne soit pas la distance la plus courte entre deux points sur Terre, représente un confort considérable pour le navigateur.

    Les exigences d'une carte de navigation maritime peuvent être formulées en fonction de l'avantage de la navigation le long du loxodrome et des résultats de l'analyse de son équation comme suit.

    1. Loxodrome, traversant les méridiens à angle constant, doit être représenté par une ligne droite.

    2. La projection cartographique utilisée pour la construction des cartes doit être conforme afin que les caps, les relèvements et les angles qui s'y rapportent correspondent à leur valeur au sol.

    3. Les méridiens et les parallèles, comme les lignes de parcours 0, 90, 180° et 270°, doivent être des lignes droites mutuellement perpendiculaires.

    La distance la plus courte entre deux points donnés de la surface de la Terre, pris comme une sphère, est le plus petit des arcs de grand cercle passant par ces points. Sauf dans le cas d'un navire suivant un méridien ou l'équateur, le grand cercle croise les méridiens à des angles différents. Par conséquent, un navire suivant une telle courbe doit constamment changer de cap. Il est pratiquement plus pratique de suivre un parcours faisant un angle constant avec les méridiens et représenté sur la carte dans la projection de Mercator par une ligne droite - loxodrome. Cependant, à de grandes distances, la différence de longueur de l'orthodrome et du loxodrome atteint une valeur significative. Par conséquent, dans de tels cas, l'orthodrome est calculé et des points intermédiaires y sont marqués, entre lesquels ils nagent le long du loxodrome.

    Une projection cartographique qui répond aux exigences ci-dessus a été proposée par le cartographe néerlandais Gerard Cramer (Mercator) en 1569. En l'honneur de son créateur, la projection a été nommée Mercator.

    Et qui veut apprendre des informations encore plus intéressantes en savoir plus L'article original est sur le site InfoGlaz.rf Lien vers l'article à partir duquel cette copie est réalisée -

    DISTANCE, distances, cf. 1. Un espace séparant deux points, un espace entre quelque chose. La distance la plus courte entre deux points en ligne droite. Vit de nous à une distance de deux kilomètres. "Le commandant les a laissés entrer à la distance la plus proche ... Dictionnaire explicatif d'Ouchakov

    distance- nom, s., usage. souvent Morphologie : (non) quoi ? distance pour quoi ? distance, (voir) quoi? distance que? distance, quoi ? sur la distance ; PL. quelle? distance, (non) quoi ? distances, pourquoi ? distances, (voir) quoi? distance que? distances... Dictionnaire de Dmitriev

    distance- JE; cf. L'espace séparant deux points, deux objets, etc., l'écart entre quelqu'un, que l. Le fleuve le plus court entre deux points. R. de la maison à l'école. Retraite dans une rivière voisine. A un mètre de distance, bras tendus. Savoir quelque chose, ressentir quelque chose. sur le… … Dictionnaire encyclopédique

    distance- JE; cf. voir également distance a) L'espace séparant deux points, deux objets, etc., l'écart entre quelqu'un, que l. La distance la plus courte entre deux points. Distance de la maison à l'école. Retraite à une distance proche / nie ... Dictionnaire de nombreuses expressions

    GÉOMÉTRIE- une branche des mathématiques qui étudie les propriétés de diverses formes (points, lignes, angles, objets bidimensionnels et tridimensionnels), leur taille et leur position relative. Pour la commodité de l'enseignement, la géométrie est divisée en planimétrie et en géométrie solide. À… … Encyclopédie Collier

    La navigation*

    La navigation- département de la navigation (voir), concluant une présentation des moyens de déterminer la place d'un navire en mer, à l'aide d'une boussole et d'un loch (voir). Déterminer l'emplacement du navire en mer signifie mettre sur la carte le point où se trouve actuellement le navire. ... ... Dictionnaire encyclopédique F.A. Brockhaus et I.A. Efron

    COGEN- (Cohen) Hermann (1842 1918) Philosophe allemand, fondateur et éminent représentant de l'école marbourgeoise du néo-kantisme. Œuvres majeures : 'La théorie de l'expérience de Kant' (1885), 'La justification de l'éthique de Kant' (1877), 'La justification de l'esthétique de Kant' (1889), 'La logique… ...

    Kant Emmanuel- Parcours de vie et écrits de Kant Immanuel Kant est né à Königsberg (aujourd'hui Kaliningrad) en Prusse Orientale en 1724. Son père était sellier, et sa mère était femme au foyer, six de leurs enfants n'ont pas atteint l'âge adulte. Kant s'est toujours souvenu de ses parents avec ... ... La philosophie occidentale des origines à nos jours

    LA PHILOSOPHIE CRITIQUE DE KANT : LA DOCTRINE DES CAPACITÉS- (La philosophie critique de Kant : Doctrines des facultés, 1963) par Deleuze. Décrivant la méthode transcendantale dans l'introduction, Deleuze note que Kant comprend la philosophie comme la science de la relation de toute connaissance à des buts essentiels... ... Histoire de la philosophie : Encyclopédie

    principe de la ferme- le principe de base de l'optique géométrique (Voir Optique géométrique). La forme la plus simple de F. p. est l'affirmation qu'un rayon de lumière se propage toujours dans l'espace entre deux points le long du chemin le long desquels le temps de son passage est inférieur à ... Grande Encyclopédie soviétique

    L'algorithme de Dijkstra est un algorithme de graphe inventé par le scientifique néerlandais Edsger Dijkstra en 1959. Trouve les chemins les plus courts d'un des sommets du graphe à tous les autres. L'algorithme fonctionne uniquement pour les graphes sans arêtes de poids négatif.

    Considérons l'exécution de l'algorithme sur l'exemple du graphique représenté sur la figure.

    Soit demandé de trouver les distances les plus courtes du 1er sommet à tous les autres.

    Les cercles indiquent les sommets, les lignes indiquent les chemins entre eux (les arêtes du graphe). Les numéros des sommets sont indiqués dans les cercles, leur "prix" - la longueur du chemin - est indiqué au-dessus des arêtes. À côté de chaque sommet, une étiquette rouge est marquée - la longueur du chemin le plus court vers ce sommet à partir du sommet 1.

    Premier pas. Considérons une étape dans l'algorithme de Dijkstra pour notre exemple. Le sommet 1 a l'étiquette minimale, les sommets 2, 3 et 6 sont ses voisins.

    Le premier voisin du sommet 1 est à son tour le sommet 2, car la longueur du chemin qui y mène est minimale. La longueur du chemin qui y mène par le sommet 1 est égale à la somme de la valeur de l'étiquette du sommet 1 et de la longueur de l'arête allant du 1er au 2e, c'est-à-dire 0 + 7 = 7. C'est moins que le étiquette actuelle du sommet 2, infini, donc la nouvelle étiquette du 2e sommet est 7.

    Nous effectuons une opération similaire avec deux autres voisins du 1er sommet - le 3ème et le 6ème.

    Tous les voisins du nœud 1 sont vérifiés. La distance minimale actuelle au pic 1 est considérée comme définitive et n'est pas sujette à révision (le fait que ce soit effectivement le cas a été prouvé pour la première fois par E. Dijkstra). Rayez-le du graphique pour marquer que ce sommet a été visité.

    Deuxième étape. L'étape de l'algorithme est répétée. Encore une fois, nous trouvons le "plus proche" des sommets non visités. C'est le sommet 2 étiqueté 7.

    Encore une fois, nous essayons de réduire les étiquettes des voisins du sommet sélectionné, en essayant de les traverser par le 2e sommet. Les voisins du sommet 2 sont les sommets 1, 3 et 4.

    Le premier voisin (dans l'ordre) du sommet 2 est le sommet 1. Mais il a déjà été visité, donc nous ne faisons rien avec le 1er sommet.

    Le prochain voisin du sommet 2 est le sommet 3, car il a l'étiquette minimale des sommets marqués comme non visités. Si vous y allez par 2, la longueur d'un tel chemin sera égale à 17 (7 + 10 = 17). Mais l'étiquette actuelle du troisième sommet est 9, ce qui est inférieur à 17, donc l'étiquette ne change pas.

    Un autre voisin du sommet 2 est le sommet 4. Si vous y allez par le 2e, la longueur d'un tel chemin sera égale à la somme de la distance la plus courte au 2e sommet et de la distance entre les sommets 2 et 4, c'est-à-dire , 22 (7 + 15 = 22) . Depuis 22<, устанавливаем метку вершины 4 равной 22.

    Tous les voisins du sommet 2 ont été visualisés, nous figeons la distance jusqu'à lui et le marquons comme visité.

    Troisième étape. Nous répétons l'étape de l'algorithme en sélectionnant le sommet 3. Après son « traitement », nous obtenons les résultats suivants :

    Prochaines étapes. Nous répétons l'étape de l'algorithme pour les sommets restants. Ce seront les sommets 6, 4 et 5, respectivement.

    Achèvement de l'exécution de l'algorithme. L'algorithme se termine lorsque plus aucun sommet ne peut être traité. Dans cet exemple, tous les sommets sont barrés, mais c'est une erreur de supposer que ce sera le cas dans n'importe quel exemple - certains sommets peuvent rester non barrés s'ils ne peuvent pas être atteints, c'est-à-dire si le graphe est déconnecté. Le résultat de l'algorithme est visible sur la dernière figure : le chemin le plus court du sommet 1 au sommet 2 est 7, au sommet 3 est égal à 9, à 4 est égal à 20, à 5 est égal à 20, à 6 est égal à 11.

    Implémentation de l'algorithme dans différents langages de programmation :

    C++

    #include "stdafx.h" #include en utilisant l'espace de noms std ; const int V=6 ; // Algorithme de Dijkstra void Dijkstra(int GR[V][V], int st) ( int distance[V], count, index, i, u, m=st+1; bool visit[V]; for (i= 0 je "< "<> "; cin>>start; Dijkstra(GR, start-1); system("pause>>void"); )

    Pascal

    programme DijkstraAlgorithme ; utilisecrt ; constV=6 ; inf=100000 ; type vecteur=tableau d'entiers ; var début : entier ; const GR : tableau d'entiers=((0, 1, 4, 0, 2, 0), (0, 0, 0, 9, 0, 0), (4, 0, 0, 7, 0, 0), (0, 9, 7, 0, 0, 2), (0, 0, 0, 0, 0, 8), (0, 0, 0, 0, 0, 0)); (algorithme de Dijkstra) procédure Dijkstra(GR : tableau d'entiers ; st : entier) ; var nombre, index, i, u, m, min : nombre entier ; vecteur de distance; visité : tableau de booléens ; début:=st; pour i:=1 à V do begin distance[i]:=inf ; visité[i] :=faux ; fin; distance :=0 ; for count:=1 to V-1 do begin min:=inf; pour i:=1 à V faire si (non visité[i]) et (distance[i]<=min) then begin min:=distance[i]; index:=i; end; u:=index; visited[u]:=true; for i:=1 to V do if (not visited[i]) and (GR<>0) et (distance[u]<>inf) et (distance[u]+GR inf then writeln(m," > ", i," = ", distance[i]) else writeln(m," > ", i," = ", "route indisponible"); fin; (bloc de programme principal) begin clrscr ; write("Nœud de départ >> "); lire (démarrer); Dijkstra(GR, départ); fin.

    Java

    importer java.io.BufferedReader ; import java.io.IOException ; importer java.io.InputStreamReader ; importer java.io.PrintWriter ; importer java.util.ArrayList ; importer java.util.Arrays ; importer java.util.StringTokenizer ; public class Solution ( private static int INF = Integer.MAX_VALUE / 2; private int n; //nombre de sommets dans le digraphe private int m; //nombre d'arcs dans le digraphe private ArrayList adj. //liste de contiguïté private ArrayList lester; // poids du bord dans le digraphe booléen privé utilisé ; // tableau pour stocker des informations sur les pics passés et non passés private int dist ; //tableau pour stocker la distance depuis le sommet de départ //un tableau d'ancêtres nécessaires pour restaurer le chemin le plus court depuis le sommet de départ private int pred; début entier ; // sommet de départ, à partir duquel la distance à tous les autres est recherchée private BufferedReader cin; compte PrintWriter privé ; générateur de jetons StringTokenizer privé ; //procédure pour démarrer l'algorithme de Dijkstra à partir du sommet de départ private void dejkstra(int s) ( dist[s] = 0; //la distance la plus courte au sommet de départ est 0 pour (int iter = 0; iter< n; ++iter) { int v = -1; int distV = INF; //выбираем вершину, кратчайшее расстояние до которого еще не найдено for (int i = 0; i < n; ++i) { if (used[i]) { continue; } if (distV < dist[i]) { continue; } v = i; distV = dist[i]; } //рассматриваем все дуги, исходящие из найденной вершины for (int i = 0; i < adj[v].size(); ++i) { int u = adj[v].get(i); int weightU = weight[v].get(i); //релаксация вершины if (dist[v] + weightU < dist[u]) { dist[u] = dist[v] + weightU; pred[u] = v; } } //помечаем вершину v просмотренной, до нее найдено кратчайшее расстояние used[v] = true; } } //процедура считывания входных данных с консоли private void readData() throws IOException { cin = new BufferedReader(new InputStreamReader(System.in)); cout = new PrintWriter(System.out); tokenizer = new StringTokenizer(cin.readLine()); n = Integer.parseInt(tokenizer.nextToken()); //считываем количество вершин графа m = Integer.parseInt(tokenizer.nextToken()); //считываем количество ребер графа start = Integer.parseInt(tokenizer.nextToken()) - 1; //инициализируем списка смежности графа размерности n adj = new ArrayList[n]; for (int i = 0; i < n; ++i) { adj[i] = new ArrayList(); ) //initialisation de la liste qui stocke les poids des arêtes weight = new ArrayList[n]; pour (int je = 0; je< n; ++i) { weight[i] = new ArrayList(); ) // lit le graphe donné par la liste des arêtes pour (int i = 0; i< m; ++i) { tokenizer = new StringTokenizer(cin.readLine()); int u = Integer.parseInt(tokenizer.nextToken()); int v = Integer.parseInt(tokenizer.nextToken()); int w = Integer.parseInt(tokenizer.nextToken()); u--; v--; adj[u].add(v); weight[u].add(w); } used = new boolean[n]; Arrays.fill(used, false); pred = new int[n]; Arrays.fill(pred, -1); dist = new int[n]; Arrays.fill(dist, INF); } //процедура восстановления кратчайшего пути по массиву предком void printWay(int v) { if (v == -1) { return; } printWay(pred[v]); cout.print((v + 1) + " "); } //процедура вывода данных в консоль private void printData() throws IOException { for (int v = 0; v < n; ++v) { if (dist[v] != INF) { cout.print(dist[v] + " "); } else { cout.print("-1 "); } } cout.println(); for (int v = 0; v < n; ++v) { cout.print((v + 1) + ": "); if (dist[v] != INF) { printWay(v); } cout.println(); } cin.close(); cout.close(); } private void run() throws IOException { readData(); dejkstra(start); printData(); cin.close(); cout.close(); } public static void main(String args) throws IOException { Solution solution = new Solution(); solution.run(); } }

    Une autre option:

    Importer java.io.* ; importer java.util.* ; public class Dijkstra ( private static final Graph.Edge GRAPH = ( new Graph.Edge("a", "b", 7), new Graph.Edge("a", "c", 9), new Graph.Edge( "a", "f", 14), nouveau Graph.Edge("b", "c", 10), nouveau Graph.Edge("b", "d", 15), nouveau Graph.Edge("c ", "d", 11), nouveau Graph.Edge("c", "f", 2), nouveau Graph.Edge("d", "e", 6), nouveau Graph.Edge("e", "f", 9), ); chaîne finale statique privée START = "a" ; chaîne finale statique privée FIN = "e" ; public static void main(String args) ( Graph g = new Graph(GRAPH); g.dijkstra (START); g.printPath(END); //g.printAllPaths(); ) ) class Graph ( carte finale privée graphique; // mappage des noms de sommets aux objets Vertex, construits à partir d'un ensemble d'arêtes /** Une arête du graphe (uniquement utilisée par le constructeur Graph) */ public static class Edge ( public final String v1, v2; public final int dist; public Edge(String v1, String v2, int dist) ( this.v1 = v1; this.v2 = v2; this.dist = dist; ) ) /** Un sommet du graphe, avec mappages sur les sommets voisins */ classe statique publique Vertex implémente Comparable ( public final String name; public int dist = Integer.MAX_VALUE; // MAX_VALUE supposé être infini public Vertex previous = null; public final Map voisins = nouveau HashMap<>(); public Vertex(String name) ( this.name = name; ) private void printPath() ( if (this == this.previous) ( System.out.printf("%s", this.name); ) else if ( this.previous == null) ( System.out.printf("%s(unreached)", this.name); ) else ( this.previous.printPath(); System.out.printf(" -> %s( %d)", this.name, this.dist); ) ) public int compareTo(Vertex other) ( return Integer.compare(dist, other.dist); ) ) /** Construit un graphe à partir d'un ensemble d'arêtes * / public Graph(Edge edge) ( graph = new HashMap<>(bords.longueur); //une passe pour trouver tous les sommets pour (Edge e: edge) ( if (!graph.containsKey(e.v1)) graph.put(e.v1, new Vertex(e.v1)); if (!graph. containsKey(e.v2)) graph.put(e.v2, new Vertex(e.v2)); ) //une autre passe pour définir les sommets voisins pour (Edge e: edge) ( graph.get(e.v1). voisins.put(graph.get(e.v2), e.dist); //graph.get(e.v2).voisins.put(graph.get(e.v1), e.dist); // aussi faites ceci pour un graphe non orienté ) ) /** Exécute dijkstra en utilisant un sommet source spécifié */ public void dijkstra(String startName) ( if (!graph.containsKey(startName)) ( System.err.printf("Graph doesn't contient le sommet de début \"%s\"\n", startName); return; ) final Vertex source = graph.get(startName); NavigableSet q = nouveau TreeSet<>(); // configuration des sommets pour (Vertex v : graph.values()) ( v.previous = v == source ? source : null ; v.dist = v == source ? 0 : Integer.MAX_VALUE ; q.add( v); ) dijkstra(q); ) /** Implémentation de l'algorithme de dijkstra à l'aide d'un tas binaire. */ private void dijkstra(final NavigableSet q) ( Vertex u, v; while (!q.isEmpty()) ( u = q.pollFirst(); // sommet avec la distance la plus courte (la première itération renverra la source) if (u.dist == Integer.MAX_VALUE) break ; // nous pouvons ignorer u (et tous les autres sommets restants) car ils sont inaccessibles // regardez les distances à chaque voisin pour (Map.Entry a: u.voisins.entrySet()) ( v = a.getKey(); //le voisin dans cette itération final int alternateDist = u.dist + a.getValue(); if (alternateDist< v.dist) { // shorter path to neighbour found q.remove(v); v.dist = alternateDist; v.previous = u; q.add(v); } } } } /** Prints a path from the source to the specified vertex */ public void printPath(String endName) { if (!graph.containsKey(endName)) { System.err.printf("Graph doesn"t contain end vertex \"%s\"\n", endName); return; } graph.get(endName).printPath(); System.out.println(); } /** Prints the path from the source to every vertex (output order is not guaranteed) */ public void printAllPaths() { for (Vertex v: graph.values()) { v.printPath(); System.out.println(); } } }

    C

    #comprendre #comprendre #comprendre //#define BIG_EXAMPLE typedef struct node_t node_t, *heap_t; typedef struct edge_t edge_t; struct edge_t ( node_t *nd; /* target of this edge */ edge_t *sibling;/* for singlely linked list */ int len; /* edge cost */ ); struct node_t ( edge_t *edge; /* liste d'arêtes à liens simples */ node_t *via; /* où le nœud précédent est dans le chemin le plus court */ double dist; /* distance du nœud d'origine */ char name; /* the, er , name */ int heap_idx; /* lien vers la position du tas pour mettre à jour la distance */ ); /* --- gestion des bords --- */ #ifdef EXEMPLE_GROS # définir BLOCK_SIZE (1024 * 32 - 1) #else # définir BLOCK_SIZE 15 #endif edge_t *edge_root = 0, *e_next = 0; /* Ne vous occupez pas des trucs de gestion de la mémoire, ils sont hors de propos. Pretend e_next = malloc(sizeof(edge_t)) */ void add_edge(node_t *a, node_t *b, double d) ( if (e_next == edge_root ) ( edge_root = malloc(sizeof(edge_t) * (BLOCK_SIZE + 1)); edge_root.sibling = e_next; e_next = edge_root + BLOCK_SIZE; ) --e_next; e_next->nd = b; e_next->len = d; e_next ->sibling = a->edge; a->edge = e_next; ) void free_edges() ( for (; edge_root; edge_root = e_next) ( e_next = edge_root.sibling; free(edge_root); ) ) /* --- file d'attente prioritaire --- */ heap_t *heap; int heap_len; void set_dist(node_t *nd, node_t *via, double d) ( int i, j; /* connaissait déjà un meilleur chemin */ if (nd->via && d >= nd->dist) return ; /* trouve une entrée de tas existante ou en crée une nouvelle */ nd->dist = d ; nd->via = via ; i = nd->heap_idx ; if (!i) i = ++heap_len; /* upheap */ for (; i > 1 && nd->dist< heap->dist; je = j) (tas[i] = tas[j])->tas_idx = je ; tas[i] = nd ; nd->heap_idx = i ; ) node_t * pop_queue() ( node_t *nd, *tmp; int i, j; if (!heap_len) return 0; /* supprime l'élément de tête, tire l'élément de queue ici et vers le bas */ nd = tas; tmp = tas; pour (je = 1 ; je< heap_len && (j = i * 2) <= heap_len; i = j) { if (j < heap_len && heap[j]->dist > tas->dist) j++; if (heap[j]->dist >= tmp->dist) pause ; (tas[i] = tas[j]) -> tas_idx = je ; ) tas[i] = tmp ; tmp->heap_idx = je ; retour sd ; ) /* --- trucs de Dijkstra ; les nœuds inaccessibles ne feront jamais partie de la file d'attente --- */ void calc_all(node_t *start) ( node_t *lead; edge_t *e; set_dist(start, start, 0); while ((lead = pop_queue())) for ( e = lead->edge; e; e = e->frère) set_dist(e->nd, lead, lead->dist + e->len); ) void show_path(node_t *nd) ( if (nd-> via == nd) printf("%s", nd->name); else if (!nd->via) printf("%s(unreached)", nd->name); else ( show_path(nd-> via); printf("-> %s(%g) ", nd->name, nd->dist); ) ) int main(void) ( #ifndef BIG_EXAMPLE int i; # define N_NODES ("f" - " a" + 1) node_t *nodes = calloc(sizeof(node_t), N_NODES); for (i = 0; i< N_NODES; i++) sprintf(nodes[i].name, "%c", "a" + i); # define E(a, b, c) add_edge(nodes + (a - "a"), nodes + (b - "a"), c) E("a", "b", 7); E("a", "c", 9); E("a", "f", 14); E("b", "c", 10);E("b", "d", 15);E("c", "d", 11); E("c", "f", 2); E("d", "e", 6); E("e", "f", 9); # undef E #else /* BIG_EXAMPLE */ int i, j, c; # define N_NODES 4000 node_t *nodes = calloc(sizeof(node_t), N_NODES); for (i = 0; i < N_NODES; i++) sprintf(nodes[i].name, "%d", i + 1); /* given any pair of nodes, there"s about 50% chance they are not connected; if connected, the cost is randomly chosen between 0 and 49 (inclusive! see output for consequences) */ for (i = 0; i < N_NODES; i++) { for (j = 0; j < N_NODES; j++) { /* majority of runtime is actually spent here */ if (i == j) continue; c = rand() % 100; if (c < 50) continue; add_edge(nodes + i, nodes + j, c - 50); } } #endif heap = calloc(sizeof(heap_t), N_NODES + 1); heap_len = 0; calc_all(nodes); for (i = 0; i < N_NODES; i++) { show_path(nodes + i); putchar("\n"); } #if 0 /* real programmers don"t free memories (they use Fortran) */ free_edges(); free(heap); free(nodes); #endif return 0; }

    PHP

    $bord, "coût" => $bord); $voisins[$bord] = array("end" => $bord, "coût" => $bord); ) $vertices = array_unique($vertices); foreach ($vertices as $vertex) ( $dist[$vertex] = INF; $previous[$vertex] = NULL; ) $dist[$source] = 0; $Q = $sommets ; while (count($Q) > 0) ( // TODO - Trouver un moyen plus rapide d'obtenir le minimum $min = INF ; foreach ($Q as $vertex)( if ($dist[$vertex]< $min) { $min = $dist[$vertex]; $u = $vertex; } } $Q = array_diff($Q, array($u)); if ($dist[$u] == INF or $u == $target) { break; } if (isset($neighbours[$u])) { foreach ($neighbours[$u] as $arr) { $alt = $dist[$u] + $arr["cost"]; if ($alt < $dist[$arr["end"]]) { $dist[$arr["end"]] = $alt; $previous[$arr["end"]] = $u; } } } } $path = array(); $u = $target; while (isset($previous[$u])) { array_unshift($path, $u); $u = $previous[$u]; } array_unshift($path, $u); return $path; } $graph_array = array(array("a", "b", 7), array("a", "c", 9), array("a", "f", 14), array("b", "c", 10), array("b", "d", 15), array("c", "d", 11), array("c", "f", 2), array("d", "e", 6), array("e", "f", 9)); $path = dijkstra($graph_array, "a", "e"); echo "path is: ".implode(", ", $path)."\n";


    Python

    from collections import namedtuple, queue from pprint import pprint as pp inf = float("inf") Edge = namedtuple("Edge", "start, end, cost") class Graph(): def __init__(self, edge): self .edges = edge2 = self.vertices = set(sum(( for e in edge2), )) def dijkstra(self, source, dest): assert source in self.vertices dist = (vertex: inf for vertex in self.vertices ) précédent = (vertex : aucun pour le sommet dans self.vertices) dist = 0 q = self.vertices.copy() voisins = (vertex : set() pour le sommet dans self.vertices) pour le début, la fin, le coût dans self. arêtes : neighbors.add((end, cost)) #pp(neighbors) while q : u = min(q, key=lambda vertex : dist) q.remove(u) if dist[u] == inf or u = = dest : pause pour v, coût en voisins[u] : alt = dist[u] + coût si alt< dist[v]: # Relax (u,v,a) dist[v] = alt previous[v] = u #pp(previous) s, u = deque(), dest while previous[u]: s.pushleft(u) u = previous[u] s.pushleft(u) return s graph = Graph([("a", "b", 7), ("a", "c", 9), ("a", "f", 14), ("b", "c", 10), ("b", "d", 15), ("c", "d", 11), ("c", "f", 2), ("d", "e", 6), ("e", "f", 9)]) pp(graph.dijkstra("a", "e")) Output: ["a", "c", "d", "e"]

    Articles similaires