Viete, prečo je ďalej v priamke ako v oblúku? Určenie vzdialenosti medzi dvoma rovnobežnými priamkami Aká je najkratšia vzdialenosť medzi dvoma bodmi

Cesta pozdĺž bodkovanej čiary na obrázku je kratšia ako cesta pozdĺž plnej čiary. A teraz trochu podrobnejšie na príklade námorných trás:

Ak navigujete v konštantnom kurze, potom trajektória pohybu lode pozdĺž zemského povrchu bude krivka nazývaná v matematike logaritmickýšpirála.

V navigácii sa táto zložitá čiara dvojitého zakrivenia nazýva loxodromia, čo v gréčtine znamená „šikmý beh“.

Najkratšia vzdialenosť medzi dvoma bodmi na zemeguli sa však meria pozdĺž oblúka veľkého kruhu.

Oblúk veľkého kruhu sa získa ako stopa z priesečníka zemského povrchu s rovinou prechádzajúcou stredom zeme, branou ako guľa.

V navigácii sa nazýva veľký kruhový oblúk veľký kruh, čo znamená „priamy beh“. Druhým znakom veľkého kruhu je, že pretína meridiány pod rôznymi uhlami (obr. 29).

Rozdiel vo vzdialenostiach medzi dvoma bodmi na zemskom povrchu pozdĺž loxodrómu a ortodrómu má praktický význam len pri veľkých prechodoch cez oceán.

Za normálnych podmienok sa tento rozdiel zanedbáva a navigácia sa uskutočňuje konštantným kurzom, t.j. loxodrómom.

Na odvodenie rovnice použijeme loxodrómie (obr. 30, a) dve bodky ALE a AT, vzdialenosť medzi nimi je jednoducho malá. Nakreslením poludníkov a rovnobežky cez ne dostaneme elementárny pravouhlý sférický trojuholník ABC. V tomto trojuholníku je uhol vytvorený priesečníkom poludníka a rovnobežky pravý a uhol PnAB rovná kurzu lode K. Katet AC predstavuje segment meridiánového oblúka a môže byť vyjadrený

kde R - polomer Zeme braný ako guľa;

Δφ - elementárny prírastok zemepisnej šírky (rozdiel zemepisných šírok).

nohu SW predstavuje paralelný oblúkový segment

kde r - polomer rovnobežky;

Δλ - elementárny rozdiel zemepisných dĺžok.

Z trojuholníka OO 1 C dá sa to nájsť

Potom v konečnej podobe nohu SW možno vyjadriť takto:

Za predpokladu elementárneho sférického trojuholníka ABC na byt, napíš

Po redukcii R a nahradenie elementárnych malých prírastkov súradníc nekonečne malými, máme

Výsledný výraz integrujeme v rozsahu od φ 1, λ 1 do φ 2, λ 2 berúc do úvahy hodnotu tgK ako konštantnú hodnotu:

Na pravej strane máme tabuľkový integrál. Po dosadení jeho hodnoty získame loxodrómovú rovnicu na guľôčke

Analýza tejto rovnice nám umožňuje vyvodiť nasledujúce závery:

Pri kurzoch 0 a 180 ° sa loxodróm mení na oblúk veľkého kruhu - poludníka;

Pri kurzoch 90 a 270 ° sa loxodróm zhoduje s rovnobežkou;

Loxodróm pretína každú rovnobežku iba raz a každý poludník nespočetne veľakrát. tie. špirálovito sa približuje k pólu, nedosiahne ho.

Navigácia v konštantnom kurze, t. j. po loxodróme, hoci to nie je najkratšia vzdialenosť medzi dvoma bodmi na Zemi, predstavuje pre navigátora značné pohodlie.

Požiadavky na námornú navigačnú mapu možno formulovať na základe výhodnosti plavby pozdĺž loxodrómu a výsledkov analýzy jej rovnice nasledovne.

1. Loxodróm pretínajúci meridiány v konštantnom uhle by mal byť znázornený ako priamka.

2. mapová projekcia, ktorý sa používa na stavbu máp, musí byť rovnouhlý, aby kurzy, smery a uhly na ňom zodpovedali ich hodnote na zemi.

3. Poludníky a rovnobežky, ako sú čiary kurzu 0, 90, 180° a 270°, musia byť vzájomne kolmé priamky.

Najkratšia vzdialenosť medzi dvoma danými bodmi na povrchu Zeme, braná ako guľa, je menší z oblúkov veľkej kružnice prechádzajúcej týmito bodmi. S výnimkou prípadu lode sledujúcej poludník alebo rovník veľký kruh pretína poludníky v rôznych uhloch. Preto loď, ktorá ide po takejto zákrute, musí neustále meniť svoj kurz. Prakticky výhodnejšie je sledovať kurz, ktorý zviera s poludníkmi konštantný uhol a na mape je v Mercatorovej projekcii znázornený priamkou – loxodrómom. Pri veľkých vzdialenostiach však rozdiel v dĺžke ortodrómu a loxodrómu dosahuje významnú hodnotu. Preto sa v takýchto prípadoch vypočíta ortodróm a vyznačia sa na ňom medziľahlé body, medzi ktorými plávajú po loxodróme.

Kartografickú projekciu, ktorá spĺňa vyššie uvedené požiadavky, navrhol holandský kartograf Gerard Cramer (Mercator) v roku 1569. Na počesť svojho tvorcu bola projekcia pomenovaná Mercator.

A kto chce získať ešte viac zaujímavé informácie uč sa viac Pôvodný článok je na webe InfoGlaz.rf Odkaz na článok, z ktorého je táto kópia vytvorená -

VZDIALENOSŤ, distances, cf. 1. Priestor oddeľujúci dva body, medzera medzi niečím. Najkratšia vzdialenosť medzi dvoma bodmi v priamke. Žije od nás vo vzdialenosti dvoch kilometrov. "Veliteľ ich pustil dnu v najbližšej vzdialenosti... Slovník Ušakov

vzdialenosť- podstatné meno, s., použiť. často Morfológia: (nie) čo? vzdialenosť za čo? vzdialenosť, (pozri) čo? vzdialenosť ako? vzdialenosť, čo? o vzdialenosti; pl. čo? vzdialenosť, (nie) čo? vzdialenosti, prečo? vzdialenosti, (pozri) čo? vzdialenosť ako? vzdialenosti... Slovník Dmitriev

vzdialenosť- ja; porov. Priestor oddeľujúci dva body, dva predmety atď., medzera medzi niekým, než l. Najkratšia rieka medzi dvoma bodmi. R. z domu do školy. Ústup k neďalekej rieke. Vo vzdialenosti metra vystreté ruky. Niečo vedieť, niečo cítiť. na…… encyklopedický slovník

vzdialenosť- ja; porov. pozri tiež vzdialenosť a) Priestor oddeľujúci dva body, dva predmety atď., medzera medzi niekým, než l. Najkratšia vzdialenosť medzi dvoma bodmi. Vzdialenosť z domu do školy. Ústup do blízka / nie ... Slovník mnohých výrazov

GEOMETRIA- odvetvie matematiky, ktoré študuje vlastnosti rôznych tvarov (body, čiary, uhly, dvojrozmerné a trojrozmerné predmety), ich veľkosť a vzájomnú polohu. Pre pohodlie výučby je geometria rozdelená na planimetriu a objemovú geometriu. AT…… Collierova encyklopédia

Navigácia*

Navigácia- odbor plavby (pozri), uzatvárajúci prezentáciu spôsobov určenia miesta lode na mori pomocou kompasu a denníka (pozri). Určiť miesto lode na mori znamená umiestniť na mapu bod, v ktorom sa loď nachádza tento moment Nachádza.… … Encyklopedický slovník F.A. Brockhaus a I.A. Efron

COGEN- (Cohen) Hermann (1842 1918) nemecký filozof, zakladateľ a najvýznamnejší predstaviteľ marburskej školy novokantovstva. Hlavné diela: „Kantova teória skúsenosti“ (1885), „Kantovo ospravedlnenie etiky“ (1877), „Kantovo ospravedlnenie estetiky“ (1889), „Logika... ...

Kant Immanuel- Životná cesta a spisy Kanta Immanuel Kant sa narodil v Königsbergu (dnes Kaliningrad) vo Východnom Prusku v roku 1724. Jeho otec bol sedlár a matka bola žena v domácnosti, šesť z ich detí sa nedožilo dospelosti. Kant vždy spomínal na svojich rodičov s ... ... Západná filozofia od jej počiatkov až po súčasnosť

KANTOVA KRITICKÁ FILOZOFIA: NÁUKA O SCHOPNOSTIACH- (La philosophie critique de Kant: Doctrines des facultes, 1963) od Deleuzea. Pri opise transcendentálnej metódy v úvode Deleuze poznamenáva, že Kant chápe filozofiu ako vedu o vzťahu všetkého poznania k základným cieľom... ... Dejiny filozofie: Encyklopédia

farmársky princíp- základný princíp geometrickej optiky (Pozri Geometrická optika). Najjednoduchšou formou F. p. je tvrdenie, že lúč svetla sa vždy šíri v priestore medzi dvoma bodmi pozdĺž dráhy, po ktorej je čas jeho prechodu kratší ako ... Veľký sovietska encyklopédia

(Deskriptívna geometria)
  • CD (CXDX, C2D2) zobrazené ako bodka C5 = D5 A5B5 rovná sa...
    (Deskriptívna geometria)
  • Určenie vzdialenosti medzi dvoma rovnobežnými rovinami
    Určenie vzdialenosti medzi dvoma rovnobežnými rovinami vo všeobecnej polohe 01| X je vhodné to zredukovať na problém určenia vzdialenosti medzi rovnakými dvoma rovinami, pretransformovanými do polohy vyčnievajúcich. V tomto prípade je vzdialenosť medzi rovinami definovaná ako kolmica medzi čiarami, ...
    (Deskriptívna geometria)
  • Určenie vzdialenosti medzi dvoma pretínajúcimi sa čiarami
    Ak chcete určiť najkratšiu vzdialenosť medzi dvoma pretínajúcimi sa čiarami, musíte dvakrát zmeniť systémy premietacích rovín. Pri riešení tohto problému prím CD (CXDX, C2D2) zobrazené ako bodka C5 = D5(Obr. 198). Vzdialenosť od tohto bodu k projekcii A5B5 rovná sa...
    (Deskriptívna geometria)
  • Uhol medzi dvoma pretínajúcimi sa priamkami
    Toto je uhol medzi dvoma pretínajúcimi sa čiarami, ktoré sú rovnobežné s údajmi. Táto úloha je teda podobná predchádzajúcej. Aby ste to vyriešili, musíte vziať ľubovoľný bod a nakresliť cez neho dve čiary rovnobežné s danými šikmými čiarami a pomocou transformácie projekcie určiť požadovaný uhol....
    (Základy deskriptívnej geometrie. Krátky kurz a súbor úloh.)
  • Určenie vzdialenosti medzi dvoma rovnobežnými čiarami
    Problém je riešený metódou dvojitej výmeny projekčných rovín. V záverečnej fáze musí byť jedna z projekčných rovín kolmá na jednu z pretínajúcich sa čiar. Potom je najkratšia vzdialenosť medzi nimi určená hodnotou úsečky kolmice na druhú šikmú čiaru (obr. 199)....
    (Deskriptívna geometria)
  • Po nakreslení dvoch bodov na tabuľu kriedou učiteľ ponúkne mladému študentovi úlohu: nakresliť medzi oboma bodmi najkratšiu cestu.

    Žiak po premýšľaní medzi nimi usilovne nakreslí kľukatú čiaru.

    - To je najkratšia cesta! čuduje sa učiteľ. - Kto ťa to naučil?

    - Môj otec. Je taxikár.

    Kresba naivného školáka je, samozrejme, neoficiálna, ale neusmiali by ste sa, keby vám povedali, že bodkovaný oblúk na obr. 1 je najkratšia cesta z Mysu dobrej nádeje na južný cíp Austrálie!

    Ešte nápadnejšie je nasledujúce tvrdenie: znázornené na obr. 2 spiatočný let z Japonska do Panamského prieplavu je kratší ako priamka nakreslená medzi nimi na tej istej mape!

    Ryža. 1. Zapnuté morská mapa najkratšia cesta z Mysu dobrej nádeje na južný cíp Austrálie nie je naznačená priamou čiarou („loxodrom“), ale krivkou („ortodromy“)


    Toto všetko vyzerá ako vtip, ale medzitým sú pred vami nesporné pravdy, dobre známe kartografom.




    Ryža. 2. Zdá sa neuveriteľné, že zakrivená cesta spájajúca Jokohamu na námornej mape s Panamským prieplavom je kratšia ako priama čiara nakreslená medzi rovnakými bodmi


    Na objasnenie problému je potrebné povedať niekoľko slov o mapách vo všeobecnosti a najmä o námorných mapách. Nakresliť časti zemského povrchu na papier nie je ľahká úloha ani v princípe, pretože Zem je guľa a je známe, že žiadna časť guľového povrchu sa nedá rozložiť na rovinu bez záhybov a zlomov. Chtiac-nechtiac sa človek musí zmieriť s nevyhnutnými skresleniami máp. Bolo vynájdených veľa spôsobov kreslenia máp, ale všetky mapy nie sú bez nedostatkov: niektoré majú deformácie jedného druhu, iné iného druhu, ale neexistujú žiadne mapy bez deformácií.

    Námorníci používajú mapy nakreslené podľa metódy starého holandského kartografa a matematika zo 16. storočia. Mercator. Táto metóda sa nazýva Mercatorova projekcia. Námornú mapu je ľahké rozpoznať podľa jej pravouhlej siete: poludníky sú na nej zobrazené ako séria rovnobežných priamych čiar; kruhy zemepisnej šírky - tiež v priamych líniách kolmých na prvý (pozri obr. 5).

    Predstavte si teraz, že chcete nájsť najkratšiu cestu z jedného oceánskeho prístavu do druhého na rovnakej rovnobežke. Na oceáne sú dostupné všetky cesty a vždy sa tam dá cestovať po najkratšej ceste, ak viete, ako leží. V našom prípade je prirodzené myslieť si, že najkratšia cesta vedie po rovnobežke, na ktorej ležia oba prístavy: veď na mape je to priamka a čo môže byť kratšie ako priama cesta! Ale mýlime sa: cesta pozdĺž rovnobežky nie je vôbec najkratšia.

    Skutočne: na povrchu gule je najkratšia vzdialenosť medzi dvoma bodmi oblúk veľkého kruhu, ktorý ich spája. Ale rovnobežný kruh malý kruh. Oblúk veľkého kruhu je menej zakrivený ako oblúk akéhokoľvek malého kruhu nakresleného cez rovnaké dva body: väčší polomer zodpovedá menšiemu zakriveniu. Potiahnite niť na zemeguli medzi naše dva body (pozri obr. 3); dáš pozor, aby vôbec neležala pozdĺž rovnobežky. Pevná niť – nesporný ukazovateľ najkratšou cestou a ak sa nezhoduje s rovnobežkou na zemeguli, potom na námornej mape nie je najkratšia cesta označená priamkou: pripomeňme si, že kruhy rovnobežiek sú na takejto mape znázornené rovnými čiarami, každá čiara, ktorá áno nezhoduje sa s priamkou je krivka .



    Ryža. 3. Jednoduchý spôsob, ako nájsť skutočne najkratšiu cestu medzi dvoma bodmi: medzi týmito bodmi musíte potiahnuť niť na zemeguli


    Po tom, čo bolo povedané, je jasné, prečo nie je najkratšia cesta na námornej mape znázornená ako priamka, ale ako zakrivená čiara.

    Hovorí sa, že pri výbere smeru pre Nikolaevskaya (teraz Oktyabrskaya) železnice viedli sa nekonečné spory o tom, akým spôsobom to položiť. Spory ukončil až zásah cára Mikuláša I., ktorý problém vyriešil doslova „na rovinu“: po línii spojil Petrohrad s Moskvou. Ak by sa to urobilo na mape Mercator, bolo by to trápne prekvapenie: namiesto rovinky by sa cesta ukázala ako zákruta.

    Kto sa nevyhýba výpočtom, môže sa jednoduchým výpočtom presvedčiť, že cesta, ktorá sa nám na mape javí ako zakrivená, je v skutočnosti kratšia ako tá, ktorú sme pripravení považovať za priamu. Nech naše dva prístavy ležia na 60. rovnobežke a sú oddelené vzdialenosťou 60°. (To, či takéto dva prístavy skutočne existujú, je, samozrejme, pre výpočet nepodstatné.)



    Ryža. 4. K výpočtu vzdialeností medzi bodmi A a B na loptičke po oblúku rovnobežky a po oblúku veľkej kružnice


    Na obr. 4 bod O - centrum glóbus, AB - oblúk kruhu zemepisnej šírky, na ktorom ležia prístavy A a B; v jej 60°. Stred kruhu zemepisnej šírky je v bode OD Predstavte si to od stredu O zemegule je nakreslený cez rovnaké prístavy veľký kruhový oblúk: jeho polomer OB = OA = R; prejde blízko nakresleného oblúka AB, ale to sa nezhoduje.

    Vypočítajme dĺžku každého oblúka. Od bodov ALE a AT ležia na zemepisnej šírke 60°, potom polomery OA a OV líčiť sa s OS(os zemegule) uhol 30°. V pravouhlom trojuholníku ASO nohu AC (=r), ležiaca oproti uhlu 30° sa rovná polovici prepony JSC;

    znamená, r = R/2 Dĺžka oblúka AB je jedna šestina dĺžky kruhu zemepisnej šírky, a keďže tento kruh má polovicu dĺžky veľkého kruhu (zodpovedá polovici polomeru), potom je dĺžka oblúka malého kruhu



    Aby sme teraz určili dĺžku oblúka veľkej kružnice nakreslenej medzi rovnakými bodmi (t. j. najkratšiu cestu medzi nimi), potrebujeme poznať veľkosť uhla AOW. Chord AS, odpočítaním oblúka na 60 ° (malý kruh), je strana pravidelného šesťuholníka vpísaná do rovnakého malého kruhu; preto AB \u003d r \u003d R / 2

    Kreslenie rovnej čiary od, spojovacie centrum O zemegule so stredom D akordy AB, získajte pravouhlý trojuholník ODA, kde je uhol D- rovno:

    DA = 1/2 AB a OA = R.

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

    Odtiaľto nájdeme (podľa tabuliek):

    =14°28",5

    a preto

    = 28°57".

    Teraz nie je ťažké nájsť požadovanú dĺžku najkratšej cesty v kilometroch. Výpočet možno zjednodušiť, ak si zapamätáme, že dĺžka jednej minúty veľkého kruhu zemegule je

    Dozvedáme sa, že cesta pozdĺž kruhu zemepisnej šírky, ktorý je na námornej mape znázornený priamou čiarou, je 3333 km a cesta po veľkom kruhu - pozdĺž krivky na mape - 3213 km, t. j. o 120 km kratšia.

    Vyzbrojení niťou a so zemeguľou po ruke môžete ľahko skontrolovať správnosť našich výkresov a uistiť sa, že oblúky veľkých kruhov skutočne ležia tak, ako je to znázornené na výkresoch. Znázornené na obr. 1, ako keby „priama“ námorná cesta z Afriky do Austrálie bola 6020 míľ a „krivka“ - 5450 míľ, t. j. kratšia o 570 míľ alebo 1050 km. „Priama“ letecká trasa na námornej mape z Londýna do Šanghaja pretína Kaspické more, pričom skutočne najkratšia trasa leží severne od Petrohradu. Je jasné, akú úlohu zohrávajú tieto problémy pri šetrení času a paliva.

    Ak sa v ére plavby čas prepravy necenil vždy - potom sa "čas" ešte nepovažoval za "peniaze", potom s príchodom parných lodí sa musí platiť za každú ďalšiu tonu spotrebovaného uhlia. Preto sa dnes lode plavia po skutočne najkratšej trase, pričom často používajú mapy vyrobené nie v Mercatore, ale v takzvanej „centrálnej“ projekcii: na týchto mapách sú oblúky veľkých kruhov znázornené ako priame čiary.

    Prečo potom bývalí navigátori používali takéto klamlivé mapy a vyberali si nevýhodné cesty? Je chybou myslieť si, že za starých čias nevedeli o teraz naznačenej vlastnosti námorných máp. Vec sa samozrejme vysvetľuje nie tým, ale skutočnosťou, že mapy nakreslené podľa Mercatorovej metódy spolu s nepríjemnosťami majú pre námorníkov veľmi cenné výhody. Takáto mapa po prvé zobrazuje oddelené malé časti zemského povrchu bez skreslenia, pričom zachováva rohy obrysu. Tomu neodporuje skutočnosť, že so vzdialenosťou od rovníka sú všetky obrysy výrazne natiahnuté. Vo vysokých zemepisných šírkach je úsek taký významný, že námorná mapa inšpiruje človeka, ktorý nie je oboznámený s jej vlastnosťami, úplne falošnou predstavou o skutočnej veľkosti kontinentov: Grónsko sa zdá byť rovnako veľké ako Afrika, Aljaška je väčšia ako Austrália, hoci Grónsko je 15-krát menšie ako Afrika a Aljaška spolu s Grónskom o polovicu menšia ako Austrália. Ale námorník, ktorý dobre pozná tieto vlastnosti mapy, sa nimi nemôže nechať zviesť. Potrpí si na ne najmä preto, že na malých plochách námorná mapa dáva presnú podobu prírody (obr. 5).

    Na druhej strane námorná mapa výrazne uľahčuje riešenie úloh navigačnej praxe. Toto je jediný druh máp, na ktorých je dráha lode na konštantnom kurze znázornená ako priamka. Nasledovať „konštantný kurz“ znamená držať sa vždy jeden smer, jeden určitý „kosokos“, inými slovami, ísť tak, aby prekročili všetky meridiány pod rovnakým uhlom. Ale túto cestu ("loxodrom") možno znázorniť ako priamku iba na mape, na ktorej sú všetky poludníky priamkami navzájom rovnobežnými. A keďže na zemeguli sa kruhy zemepisnej šírky pretínajú s poludníkmi v pravom uhle, potom na takejto mape by kruhy zemepisnej šírky mali byť rovné čiary kolmé na čiary poludníkov. Stručne povedané, dostávame sa presne k súradnicovej sieti, ktorá predstavuje charakteristický znak námornej mapy.




    Ryža. 5. Námorná alebo Mercatorova mapa zemegule. Na takýchto mapách sú rozmery vrstevníc ďaleko od rovníka značne prehnané. Čo je napríklad väčšie: Grónsko alebo Austrália? (odpoveď v texte)


    Náklonnosť námorníkov pre mapy Mercator je teraz pochopiteľná. Aby navigátor určil kurz, ktorý sa má sledovať pri prechode do určeného prístavu, použije pravítko na koncové body trasy a zmeria uhol, ktorý zviera s poludníkmi. Navigátor, ktorý sa neustále drží na otvorenom mori v tomto smere, presne privedie loď k cieľu. Vidíte, že „loxodrom“ je síce nie najkratšia a nie najekonomickejšia, ale v istom ohľade pre námorníka veľmi pohodlná cesta. Aby sa človek dostal napríklad z Mysu dobrej nádeje na južný cíp Austrálie (pozri obr. 1), musí vždy udržiavať rovnaký kurz S 87°.50". posledný bod najkratšou cestou(podľa „ortodrómie“) je potrebné, ako je vidieť z obrázku, priebežne meniť kurz plavidla: začať od kurzu S 42°, 50" a skončiť kurzom N 53°, 50 “ (v tomto prípade najkratšia cesta ani nie je realizovateľná – spočíva v antarktickej ľadovej stene).

    Obe cesty - pozdĺž "loxodromu" a pozdĺž "ortodrómy" - sa zhodujú iba vtedy, keď je cesta pozdĺž veľkého kruhu znázornená na námornej mape ako priamka: pri pohybe pozdĺž rovníka alebo pozdĺž poludníka. Vo všetkých ostatných prípadoch sú tieto cesty odlišné.

    Dijkstrov algoritmus je grafový algoritmus, ktorý vynašiel holandský vedec Edsger Dijkstra v roku 1959. Nájde najkratšie cesty z jedného z vrcholov grafu do všetkých ostatných. Algoritmus funguje len pre grafy bez hrán so zápornou váhou.

    Zvážte vykonanie algoritmu na príklade grafu znázorneného na obrázku.

    Nech sa vyžaduje nájsť najkratšie vzdialenosti od 1. vrcholu ku všetkým ostatným.

    Kruhy označujú vrcholy, čiary označujú cesty medzi nimi (okraje grafu). V krúžkoch sú uvedené čísla vrcholov, nad okrajmi ich „cena“ – dĺžka dráhy. Vedľa každého vrcholu je vyznačený červený štítok - dĺžka najkratšej cesty k tomuto vrcholu z vrcholu 1.

    Prvý krok. Zvážte krok v Dijkstrovom algoritme pre náš príklad. Minimálne označenie má vrchol 1. Vrchol 2, 3 a 6 sú jeho susedmi.

    Prvý sused vrcholu 1 v poradí je vrchol 2, pretože dĺžka cesty k nemu je minimálna. Dĺžka cesty k nemu cez vrchol 1 sa rovná súčtu hodnôt označenia vrcholu 1 a dĺžky hrany od 1. do 2., teda 0 + 7 = 7. To je menej ako aktuálne označenie vrcholu 2, nekonečno, takže nové označenie druhého vrcholu je 7.

    Podobnú operáciu vykonávame s ďalšími dvoma susedmi 1. vrcholu - 3. a 6..

    Všetci susedia uzla 1 sú skontrolovaní. Aktuálna minimálna vzdialenosť k vrcholu 1 sa považuje za konečnú a nepodlieha revízii (to, že je to skutočne tak, prvýkrát dokázal E. Dijkstra). Prečiarknite ho z grafu, aby ste označili, že tento vrchol bol navštívený.

    Druhý krok. Krok algoritmu sa opakuje. Opäť nájdeme „najbližší“ z nenavštívených vrcholov. Toto je vrchol 2 označený ako 7.

    Opäť sa pokúsime zmenšiť štítky susedov vybraného vrcholu a pokúsime sa cez ne prejsť cez 2. vrchol. Susedmi vrcholu 2 sú vrcholy 1, 3 a 4.

    Prvý (v poradí) sused vrcholu 2 je vrchol 1. Ale ten už bol navštívený, takže s prvým vrcholom nič nerobíme.

    Ďalším susedom vrcholu 2 je vrchol 3, pretože má minimálne označenie vrcholov označených ako nenavštívené. Ak na to pôjdete cez 2, tak dĺžka takejto cesty bude rovná 17 (7 + 10 = 17). Ale aktuálne označenie tretieho vrcholu je 9, čo je menej ako 17, takže označenie sa nemení.

    Ďalším susedom vrcholu 2 je vrchol 4. Ak k nemu pôjdete cez 2., tak dĺžka takejto cesty sa bude rovnať súčtu najkratšej vzdialenosti k 2. vrcholu a vzdialenosti medzi vrcholmi 2 a 4, tj. 22 (7 + 15 = 22). Od 22<, устанавливаем метку вершины 4 равной 22.

    Všetci susedia vrcholu 2 boli prezretí, zmrazíme vzdialenosť k nemu a označíme ho ako navštívený.

    Tretí krok. Krok algoritmu zopakujeme výberom vrcholu 3. Po jeho „spracovaní“ dostaneme nasledujúce výsledky:

    Ďalšie kroky. Opakujeme krok algoritmu pre zostávajúce vrcholy. Budú to vrcholy 6, 4 a 5.

    Dokončenie vykonávania algoritmu. Algoritmus sa ukončí, keď už nie je možné spracovať žiadne ďalšie vrcholy. V tomto príklade sú všetky vrcholy prečiarknuté, ale je mylné predpokladať, že to tak bude v akomkoľvek príklade - niektoré vrcholy môžu zostať neprečiarknuté, ak ich nemožno dosiahnuť, t. j. ak je graf odpojený. Výsledok algoritmu je viditeľný na poslednom obrázku: najkratšia cesta z vrcholu 1 do 2 je 7, do 3 je 9, do 4 je 20, do 5 je 20, do 6 je 11.

    Implementácia algoritmu v rôznych programovacích jazykoch:

    C++

    #include "stdafx.h" #include pomocou menného priestoru std; const int V=6; // Dijkstrov algoritmus void Dijkstra(int GR[V][V], int st) ( int vzdialenosť[V], počet, index, i, u, m=st+1; bool navštívené[V]; pre (i= 0 i "< "<> "; cin>>start; Dijkstra(GR, start-1); system("pause>>void"); )

    Pascal

    program DijkstraAlgorithm; usecrt; constV=6; inf=100000; typ vektor=pole integer; var start: integer; const GR: pole integer=((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)); (Dijkstrov algoritmus) procedure Dijkstra(GR: pole integer; st: integer); var počet, index, i, u, m, min: celé číslo; vzdialenosť: vektor; navštívené: pole booleovských hodnôt; začiatok:=st; for i:=1 to V do begin distance[i]:=inf; navštívené[i]:=false; koniec; vzdialenosť:=0; pre počet:=1 až V-1 do begin min:=inf; pre i:=1 až V urobte if (nenavštívené[i]) a (vzdialenosť[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) a (vzdialenosť[u]<>inf) a (vzdialenosť[u]+GR inf then writeln(m," > ", i," = ", vzdialenosť[i]) else writeln(m," > ", i," = ", "trasa nedostupná"); koniec; (hlavný blok programu) begin clrscr; write("Počiatočný uzol >> "); čítať (štart); Dijkstra(GR, začiatok); koniec.

    Java

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.StringTokenizer; public class Solution ( private static int INF = Integer.MAX_VALUE / 2; private int n; //počet vrcholov v digraph private int m; //počet oblúkov v digraph private ArrayList adj; //zoznam susedstva private ArrayList hmotnosť; //váha hrany v digraph použitý súkromný boolean; //pole na ukladanie informácií o prejdených a neprekonaných vrcholoch private int dist; //pole na uloženie vzdialenosti od počiatočného vrcholu //pole predkov potrebných na obnovenie najkratšej cesty z počiatočného vrcholu private int pred; int štart; //počiatočný vrchol, z ktorého sa hľadá vzdialenosť ku všetkým ostatným private BufferedReader cin; súkromný PrintWriter cout; súkromný tokenizér StringTokenizer; //postup na spustenie Dijkstrovho algoritmu z počiatočného vrcholu private void dejkstra(int s) ( dist[s] = 0; //najkratšia vzdialenosť k počiatočnému vrcholu je 0 pre (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(); ) //inicializácia zoznamu, v ktorom sú uložené váhy hrán weight = new ArrayList[n]; pre (int i = 0; i< n; ++i) { weight[i] = new ArrayList(); ) //prečítajte graf daný zoznamom hrán pre (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(); } }

    Ďalšia možnosť:

    Importovať java.io.*; import 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), new Graph.Edge("b", "c", 10), new Graph.Edge("b", "d", 15), new Graph.Edge("c" ", "d", 11), new Graph.Edge("c", "f", 2), new Graph.Edge("d", "e", 6), new Graph.Edge("e", "f", 9), ); private static final String START = "a"; private static final String END = "e"; public static void main(String args) ( Graph g = new Graph(GRAPH); g.dijkstra (START); g.printPath(END); //g.printAllPaths(); ) ) graf triedy (súkromná konečná mapa graf; // mapovanie názvov vrcholov na objekty Vertex, zostavené zo sady Edge /** Jeden okraj grafu (používaný iba konštruktorom 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; ) ) /** Jeden vrchol grafu doplnený o zobrazenia na susedné vrcholy */ verejná statická trieda Vertex implementuje Porovnateľné ( public final name string; public int dist = Integer.MAX_VALUE; // Predpokladá sa, že MAX_VALUE je nekonečný verejný vrchol predchádzajúci = null; verejná konečná mapa susedia = nová HashMap<>(); public Vertex(Názov reťazca) ( 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); ) ) /** Zostaví graf z množiny hrán * / public Graph(hrany okrajov) ( graf = nová HashMap<>(hrany.dĺžka); //jeden prechod na nájdenie všetkých vrcholov pre (Edge e: hrany) ( if (!graph.containsKey(e.v1)) graph.put(e.v1, new Vertex(e.v1)); if (!graph. obsahujeKey(e.v2)) graph.put(e.v2, new Vertex(e.v2)); ) //ďalší prechod na nastavenie susedných vrcholov pre (Edge e: hrany) ( graph.get(e.v1). neighbours.put(graph.get(e.v2), e.dist); //graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // tiež urobte to pre neorientovaný graf ) ) /** Spustí dijkstra s použitím špecifikovaného zdrojového vrcholu */ public void dijkstra(String startName) ( if (!graph.containsKey(startName)) ( System.err.printf("Graph nie obsahovať počiatočný vrchol \"%s\"\n", počiatočný názov); return; ) konečný zdroj vrcholu = graph.get(startName); NavigableSet q = nový TreeSet<>(); // nastavenie vrcholov pre (Vertex v: graph.values()) ( v.previous = v == zdroj ? zdroj: null; v.dist = v == zdroj ? 0: Integer.MAX_VALUE; q.add( v);) dijkstra(q); ) /** Implementácia algoritmu dijkstra pomocou binárnej haldy. */ private void dijkstra(final NavigableSet q) ( Vertex u, v; while (!q.isEmpty()) ( u = q.pollFirst(); // vrchol s najkratšou vzdialenosťou (prvá iterácia vráti zdroj) if (u.dist == Integer.MAX_VALUE) zlom; // môžeme ignorovať u (a všetky ostatné zostávajúce vrcholy), pretože sú nedosiahnuteľné //pozrite sa na vzdialenosti od každého suseda pre (Map.Entry a: u.neighbours.entrySet()) ( v = a.getKey(); //sused v tejto iterácii final int alternativeDist = 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

    #include #include #include //#define BIG_EXAMPLE typedef struct node_t node_t, *heap_t; typedef struct edge_t edge_t; struct edge_t ( node_t *nd; /* cieľ tejto hrany */ edge_t *súrodenec;/* pre jednotlivo prepojený zoznam */ int len; /* cena hrany */ ); struct node_t ( edge_t *edge; /* jednotlivo prepojený zoznam hrán */ node_t *via; /* kde predchádzajúci uzol je v najkratšej ceste */ double dist; /* vzdialenosť od pôvodného uzla */ názov znaku; /* the, er , meno */ int heap_idx; /* odkaz na pozíciu haldy pre aktualizáciu vzdialenosti */ ); /* --- správa hrán --- */ #ifdef BIG_EXAMPLE #definovať BLOCK_SIZE (1024 * 32 - 1) #else #definovať BLOCK_SIZE 15 #endif edge_t *edge_root = 0, *e_next = 0; /* Nezabúdajte na veci súvisiace so správou pamäte, sú zbytočné. Predstierajte e_next = malloc(sizeof(edge_t)) */ void add_edge(node_t *a, node_t *b, double d) ( if (e_next == edge_root ) ( root_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;_nex = e_next;_nex ->súrodenec = a->edge; a->edge = e_next; ) void free_edges() ( for (; root_root; edge_root = e_next) ( e_next = edge_root.sibling; free(edge_root); ) ) /* --- prioritný front --- */ heap_t *heap; int heap_len; void set_dist(node_t *nd, node_t *via, double d) ( int i, j; /* už poznal lepšiu cestu */ if (nd->via && d >= nd->dist) return; /* nájsť existujúcu položku haldy alebo vytvoriť novú */ nd->dist = d; nd->via = via; i = nd->heap_idx; if (!i) i = ++heap_len; /* upheap */ for (; i > 1 && nd->dist< heap->dist; i = j) (heap[i] = heap[j])->heap_idx = i; halda[i] = nd; nd->heap_idx = i; ) node_t * pop_queue() ( node_t *nd, *tmp; int i, j; if (!heap_len) vráti 0; /* odstráni vodiaci prvok, potiahne koncový prvok tam a dole hromadí */ nd = halda; tmp = halda; pre (i = 1; i< heap_len && (j = i * 2) <= heap_len; i = j) { if (j < heap_len && heap[j]->dist > halda->dist) j++; if (heap[j]->dist >= tmp->dist) break; (heap[i] = heap[j])->heap_idx = i; ) halda[i] = tmp; tmp->heap_idx = i; návrat nd; ) /* --- Dijkstra veci; nedosiahnuteľné uzly sa nikdy nevytvoria do front --- */ 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->súrodenec) 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; #definuj N_NODES ("f" - "a" + 1) node_t * uzly = calloc(veľkosť(uzol_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

    $edge, "cena" => $edge); $neighbours[$edge] = array("end" => $edge, "cost" => $edge); ) $vertices = array_unique($vertices); foreach ($vrcholy ako $vertex) ( $vzdial[$vertex] = INF; $predchadzajuci[$vertex] = NULL; ) $vzdial[$zdroj] = 0; $Q = $vertices; while (count($Q) > 0) ( // TODO – Nájdite rýchlejší spôsob, ako získať minimum $min = INF; foreach ($Q ako $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

    z kolekcií import namedtuple, fronta z pprint importovanie pprint ako pp inf = float("inf") Edge = namedtuple("Edge", "start, end, cost") class Graph(): def __init__(self, edge): self .hrany = hrany2 = self.vertices = set(sum(( pre e v hranách2), )) def dijkstra(self, source, dest): tvrdiť zdroj v self.vertices dist = (vertex: inf for vertex in self.vertices ) predchádzajúci = (vrchol: Žiadny pre vrchol v sebe.vrcholoch) dist = 0 q = self.vertices.copy() susedia = (vertex: set() pre vrchol v sebe.vrcholoch) pre začiatok, koniec, náklady v sebe. hrany: susedia.add((koniec, cena)) #pp(susedia) while q: u = min(q, kľúč=vrchol lambda: dist) q.remove(u) if dist[u] == inf alebo u = = dest: prestávka na v, náklady v susedoch[u]: alt = dist[u] + cena, ak 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"]