Znate li zašto je dalje u pravoj liniji nego u luku? Određivanje udaljenosti između dvije paralelne prave Koja je najkraća udaljenost između dvije tačke

Staza duž isprekidane linije na slici je kraća od putanje duž pune. A sada malo više detalja na primjeru morskih puteva:

Ako plovite na stalnom kursu, onda trajektorija broda duž zemljine površine biće kriva koja se u matematici naziva logaritamskispirala.

U navigaciji se ova složena linija dvostruke zakrivljenosti naziva rhoxodrome, što u prijevodu s grčkog znači “koso trčanje”.

Međutim, najkraća udaljenost između dvije točke na globusu mjeri se duž luka velikog kruga.

Luk velikog kruga se dobija kao trag od preseka zemljine površine sa ravninom koja prolazi kroz centar zemlje, uzeta kao lopta.

U navigaciji se zove veliki kružni luk ortodromija, što u prevodu znači "ravno trčanje". Druga karakteristika ortodromije je da meridijane seče pod različitim uglovima (slika 29).

Razlika u rastojanju između dve tačke na zemljinoj površini prema loksodromu i ortodromu je od praktične važnosti samo prilikom velikih prelazaka preko okeana.

U normalnim uslovima ova razlika se zanemaruje i plivanje se izvodi na konstantnom kursu, tj. po rhoxodrome.

Za izvođenje jednačine, uzmimo roksodrom (Sl. 30, A) dva poena A I IN, udaljenost između njih je jednostavno mala. Crtajući meridijane i paralelu kroz njih, dobijamo elementarni pravokutni sferni trokut ABC. U ovom trokutu, ugao nastao presekom meridijana i paralele je pravi, a ugao PnAB jednak kursu broda K. Katet AC predstavlja segment meridijanskog luka i može se izraziti

Gdje R - poluprečnik Zemlje uzet kao sfera;

Δφ - elementarni prirast geografske širine (razlika u geografskoj širini).

Noga NE predstavlja segment paralelnog luka

gdje je r - paralelni radijus;

Δλ - elementarna razlika u geografskoj dužini.

Iz trougla OO 1 C to se može naći

Zatim u konačnom obliku nogu NE može se izraziti ovako:

Uzimanje elementarnog sfernog trougla ABC za stan, pisaćemo

Nakon smanjenja R i zamenu elementarnih malih prirasta koordinata sa beskonačno malim koje ćemo imati

Integrirajmo rezultirajući izraz u rasponu od φ 1, λ 1 do φ 2, λ 2 smatrajući da je vrijednost tgK konstantna:

Na desnoj strani imamo integral tablice. Nakon zamjene njegove vrijednosti, dobijamo jednačinu loksodromije na lopti

Analiza ove jednadžbe nam omogućava da izvučemo sljedeće zaključke:

Na kursevima od 0 i 180°, loksodrom se pretvara u luk velikog kruga - meridijan;

Na kursevima od 90 i 270°, roksodrom se poklapa sa paralelom;

Loksodrom prelazi svaku paralelu samo jednom, a svaki meridijan beskonačan broj puta. one. spiralno prema polu, ne dostiže ga.

Plovidba na stalnom kursu, odnosno duž rhoxodroma, iako to nije najkraća udaljenost između dvije točke na Zemlji, pruža značajnu pogodnost za navigatora.

Zahtjevi za pomorsku navigacijsku kartu mogu se formulirati na temelju prednosti plovidbe duž roksodroma i rezultata analize njegove jednadžbe na sljedeći način.

1. Loksodrom, koji prelazi meridijane pod stalnim uglom, treba prikazati kao prava linija.

2. Projekcija karte, koji se koristi za izradu karata, mora biti jednakougaonog oblika tako da kursevi, smjerovi i uglovi na njemu odgovaraju njihovom značenju na terenu.

3. Meridijani i paralele, kao i linije kursa od 0, 90, 180° i 270°, moraju biti međusobno okomite prave.

Najkraća udaljenost između dvije date tačke na površini Zemlje, uzete kao sfera, je manji od lukova velikog kruga koji prolazi kroz ove tačke. Osim u slučaju da brod prati meridijan ili ekvator, ortodrom siječe meridijane pod različitim uglovima. Stoga, brod koji slijedi takvu krivinu mora stalno mijenjati svoj kurs. U praksi je zgodnije pratiti kurs koji pravi konstantan ugao sa meridijanima i koji je na karti u Mercatorovoj projekciji prikazan ravnom linijom - loksodromom. Međutim, na velikim udaljenostima razlika u dužini ortodroma i loksodroma dostiže značajnu vrijednost. Stoga se u takvim slučajevima ortodrom izračunava i na njemu se označavaju međutačke između kojih plove duž loksodroma.

Kartografsku projekciju koja zadovoljava gore navedene zahtjeve predložio je holandski kartograf Gerard Cramer (Mercator) 1569. godine. U čast njenog tvorca, projekcija je nazvana Mercatorian

A ko želi da nauči još više? zanimljive informacije saznati više Originalni članak je na web stranici InfoGlaz.rf Link na članak iz kojeg je napravljena ova kopija -

DISTANCE, udaljenosti, pros. 1. Prostor koji razdvaja dvije tačke, jaz između nečega. Najkraća udaljenost između dvije tačke u pravoj liniji. Živi dva kilometra od nas. “Komandant ih je pustio da priđu što bliže... Rječnik Ushakova

razdaljina- imenica, str., korištena često Morfologija: (ne) šta? udaljenosti, zašto? udaljenost, (vidi) šta? udaljenost, sta? udaljenost, o čemu? o udaljenosti; pl. Šta? udaljenost, (ne) šta? udaljenosti, šta? udaljenosti, (vidim) šta? udaljenosti, šta? udaljenosti... Dmitriev's Explantatory Dictionary

razdaljina- I; sri Prostor koji razdvaja dvije tačke, dva objekta, itd., jaz između koga, zatim l. Najkraća rijeka između dve tačke. R. od kuće do škole. Premjestite se na obližnju rijeku. Na udaljenosti od metar, u dužini ruke. Znati nešto, osjetiti nešto. na… … enciklopedijski rječnik

razdaljina- I; sri vidi takođe udaljenost a) Prostor koji razdvaja dvije tačke, dva objekta, itd., razmak između koga, nego l. Najkraća udaljenost između dvije tačke. Udaljenost od kuće do škole. Premjestite se na blisku udaljenost... Rečnik mnogih izraza

GEOMETRIJA- grana matematike koja proučava svojstva različitih figura (tačke, prave, uglovi, dvodimenzionalni i trodimenzionalni objekti), njihove veličine i relativne pozicije. Radi lakšeg podučavanja, geometrija je podijeljena na planimetriju i stereometriju. U… … Collier's Encyclopedia

Navigacija*

Navigacija- odjel za plovidbu (vidi), koji sadrži izjavu o metodama za određivanje položaja broda na moru, pomoću kompasa i dnevnika (vidi). Odrediti mjesto broda na moru znači ucrtati na kartu tačku u kojoj se brod nalazi ovog trenutka nalazi.… … Enciklopedijski rječnik F.A. Brockhaus i I.A. Efron

COHEN- (Cohen) Hermann (1842. 1918.) njemački filozof, osnivač i najistaknutiji predstavnik marburške škole neokantijanizma. Glavna djela: 'Kantova teorija iskustva' (1885), 'Kantovo opravdanje etike' (1877), 'Kantovo opravdanje estetike' (1889), 'Logika... ...

Kant Immanuel- Kantov životni put i spisi Imanuel Kant je rođen u Konigsbergu (danas Kalinjingrad) u Istočnoj Pruskoj 1724. Otac mu je bio sedlar, a majka domaćica, šestoro njihove djece nije doživjelo punoljetstvo. Kant se uvijek sjećao svojih roditelja iz... Zapadna filozofija od njenog nastanka do danas

KANTOVA KRITIČKA FILOZOFIJA: UČENJE SPOSOBNOSTI- (La philosophie critique de Kant: Doctrines des facultes, 1963) Deleuzeovo djelo. Karakterizirajući transcendentalni metod u uvodu, Deleuze primjećuje da Kant razumije filozofiju kao nauku o odnosu svih znanja prema bitnim ciljevima... Istorija filozofije: Enciklopedija

Princip farme- osnovni princip geometrijske optike (vidi Geometrijska optika). Najjednostavniji oblik f.p. je izjava da se zrak svjetlosti uvijek širi u prostoru između dvije tačke duž putanje duž koje je vrijeme njenog putovanja manje od... Veliki Sovjetska enciklopedija

(Deskriptivna geometrija)
  • CD (CXDX, C2D2) prikazano kao tačka C5 = D5 A5B5 jednako...
    (Deskriptivna geometrija)
  • Određivanje udaljenosti između dvije paralelne ravni
    Određivanje udaljenosti između dvije paralelne ravni u općem položaju 01| X Pogodno ga je svesti na problem određivanja udaljenosti između iste dvije ravni, transformirane u položaj projektora. U ovom slučaju, udaljenost između ravnina će se odrediti kao okomita između pravih...
    (Deskriptivna geometrija)
  • Određivanje udaljenosti između dvije linije koje se seku
    Ako trebate odrediti najkraću udaljenost između dvije prave linije koje se seku, morate dva puta promijeniti sistem ravni projekcije. Prilikom rješavanja ovog problema prava linija CD (CXDX, C2D2) prikazano kao tačka C5 = D5(Sl. 198). Udaljenost od ove tačke do projekcije A5B5 jednako...
    (Deskriptivna geometrija)
  • Ugao između dvije prave linije koje se seku
    Ovo je ugao između dve linije koje se seku paralelne sa podacima. Dakle, ovaj zadatak je sličan prethodnom. Da biste ga riješili, potrebno je uzeti proizvoljnu tačku i kroz nju povući dvije prave, paralelne datim linijama koje se sijeku, te pomoću transformacije projekcija odrediti željeni ugao....
    (Osnove deskriptivne geometrije. Kratki kurs i zbirka problema.)
  • Određivanje udaljenosti između dvije paralelne prave
    Problem se rješava metodom dvostruke zamjene projekcijskih ravni. U završnoj fazi, jedna od ravni projekcije mora biti okomita na jednu od linija koje se sijeku. Tada je najkraća udaljenost između njih određena veličinom okomitog segmenta na drugu liniju ukrštanja (Sl. 199)....
    (Deskriptivna geometrija)
  • Nakon što je kredom označio dvije tačke na tabli, učitelj nudi mladom školarcu zadatak: nacrtati najkraći put između obje tačke.

    Učenik, nakon razmišljanja, pažljivo povlači krivudavu liniju između njih.

    - To je najkraći put! – čudi se učiteljica. -Ko te je to naučio?

    - Moj tata. On je taksista.

    Crtež naivnog školarca je, naravno, anegdotalan, ali zar se ne biste nasmejali kada bi vam rekli da je tačkasti luk na Sl. 1 - najkraći put od Rta dobre nade do južnog vrha Australije!

    Još je upečatljivija sljedeća izjava: prikazana na Sl. 2 kružni tok od Japana do Panamskog kanala kraći je od prave linije povučene između njih na istoj karti!

    Rice. 1. On karta mora Najkraći put od Rta dobre nade do južnog vrha Australije nije označen ravnom linijom („loksodrom“), već krivuljom („ortodrom“)


    Sve ovo izgleda kao šala, a ipak pred vama su neosporne istine, dobro poznate kartografima.




    Rice. 2. Čini se nevjerovatnim da je zakrivljena staza koja povezuje Yokohamu sa Panamskim kanalom na karti mora kraća od prave linije povučene između istih tačaka


    Da bismo razjasnili pitanje, morat ćemo reći nekoliko riječi o kartama općenito, a posebno o morskim kartama. Prikazivanje dijelova zemljine površine na papiru nije lak zadatak, čak ni u principu, jer je zemlja lopta, a poznato je da se nijedan dio sferne površine ne može rasklopiti na ravni bez nabora i kidanja. Neminovno se mora trpjeti neizbježna izobličenja na kartama. Izmišljeno je mnogo načina crtanja karata, ali sve karte nisu slobodne od nedostataka: neke imaju izobličenja jedne vrste, druge druge, ali nema karata bez izobličenja.

    Mornari koriste karte nacrtane po metodi starog holandskog kartografa i matematičara iz 16. stoljeća. Mercator. Ova metoda se zove “Merkatorijska projekcija”. Lako je prepoznati morsku kartu po pravokutnoj mreži: meridijani su na njoj prikazani kao niz paralelnih pravih linija; krugovi geografske širine su takođe prave linije, okomite na prve (vidi sliku 5).

    Zamislite sada da trebate pronaći najkraći put od jedne okeanske luke do druge, koja leži na istoj paraleli. Na okeanu su sve staze dostupne, a putovati tamo najkraćom stazom je uvijek moguće ako znate kako ona ide. U našem slučaju, prirodno je misliti da najkraći put ide paralelom na kojoj se nalaze obje luke: na kraju krajeva, na karti je to prava linija, a šta bi moglo biti kraće od pravog puta! Ali griješimo: paralelni put uopće nije najkraći.

    Zaista: na površini lopte, najkraća udaljenost između dvije tačke je veliki kružni luk koji ih povezuje. Ali krug paralela - mala krug. Luk velikog kruga je manje zakrivljen od luka bilo kojeg malog kruga povučen kroz iste dvije tačke: veći radijus odgovara manjoj krivini. Razvucite nit na globusu između naše dvije tačke (vidi sliku 3); bićete uvereni da ona uopšte neće ležati duž paralele. Zategnuta nit je neosporan pokazatelj najkraći put, a ako se ne poklapa s paralelom na globusu, tada na karti mora najkraći put nije označen ravnom linijom: zapamtite da su krugovi paralela na takvoj karti prikazani kao ravne linije, već svaka linija koja to čini ne poklapa se sa pravom linijom krivulja .



    Rice. 3. Jednostavan način da pronađete istinski najkraći put između dvije tačke: trebate povući nit na globusu između ovih tačaka


    Nakon rečenog, postaje jasno zašto se najkraća staza na karti mora ne prikazuje kao prava, već kao kriva linija.

    Kažu da pri odabiru smjera za Nikolaevskaya (sada Oktyabrskaya) željeznica Vodile su se beskrajne rasprave o tome kojim putem krenuti. Kontroverzu je prekinula intervencija cara Nikolaja I, koji je problem riješio bukvalno „jednostavno“: linijom je povezao Sankt Peterburg sa Moskvom. Da je to urađeno na mapi Mercatora, rezultat bi bio neugodno iznenađenje: umjesto pravog puta, put bi ispao krivudav.

    Ko ne izbjegava kalkulacije može se jednostavnom računicom uvjeriti da je put koji nam se na karti čini krivudavim zapravo kraći od one koju smo spremni smatrati ravnim. Neka naše dvije luke leže na 60. paraleli i razdvojene su razmakom od 60°. (Da li takve dvije luke zaista postoje, naravno, nije bitno za proračun.)



    Rice. 4. Izračunati udaljenosti između tačaka A i B na lopti duž paralelnog luka i duž velikog luka


    Na sl. 4 bod O - centar globus, AB – luk kruga geografske širine na kojem leže luke A i B; V to je 60°. Središte kruga geografske širine je u tački WITH Zamislimo to iz centra O globus je povučen kroz iste luke lukom velikog kruga: njegovim radijusom OB = OA = R; proći će blizu nacrtanog luka AB, ali se neće poklopiti s tim.

    Izračunajmo dužinu svakog luka. Od bodova A I IN leže na geografskoj širini 60°, a zatim na poluprečniku OA I OB iznose OS(osa globusa) ugao od 30°. U pravouglu ASO nogu AC (=r), koji leži nasuprot ugla od 30°, jednakom polovini hipotenuze dd;

    znači, r=R/2 Dužina luka AB je jedna šestina dužine kruga geografske širine, a pošto ovaj krug ima polovinu dužine velikog kruga (što odgovara polovini poluprečnika), onda je dužina luka malog kruga



    Da bismo sada odredili dužinu luka velikog kruga nacrtanog između istih tačaka (tj. najkraći put između njih), moramo saznati veličinu ugla AOB. Akord AS, koji obuhvata luk od 60° (malog kruga), je stranica pravilnog šestougla upisana u isti mali krug; Zbog toga AB = r=R/2

    Nakon što smo nacrtali pravu liniju O.D. povezuje centar O globus sa sredinom D akordi AB, dobijamo pravougli trougao ODA, gdje je ugao D – ravno:

    DA= 1/2 AB i OA = R.

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

    Odavde nalazimo (iz tabela):

    =14°28",5

    i zbog toga

    = 28°57".

    Sada nije teško pronaći potrebnu dužinu najkraćeg puta u kilometrima. Izračun se može pojednostaviti ako se sjetimo da je dužina jednog minuta velikog kruga globusa

    Saznajemo da je put po krugu geografske širine, koji je na karti mora prikazan kao prava linija, 3333 km, a put po velikom krugu - duž krivulje na karti - 3213 km, odnosno 120 km kraći.

    Naoružani koncem i globusom pri ruci, lako možete provjeriti ispravnost naših crteža i uvjeriti se da lukovi velikih krugova zaista leže kao što je prikazano na crtežima. Prikazano na sl. 1, navodno, "ravni" morski put od Afrike do Australije je 6020 milja, a "krivi" 5450 milja, odnosno kraći za 570 milja, odnosno 1050 km. “Direktna” zračna ruta od Londona do Šangaja na karti mora preseca Kaspijsko more, dok u stvari najkraća ruta vodi sjeverno od Sankt Peterburga. Jasno je kakvu ulogu ova pitanja imaju u uštedi vremena i goriva.

    Ako se u eri plovidbe vrijeme nije uvijek cijenilo - tada se "vrijeme" još nije smatralo "novcem" - onda se s pojavom parnih brodova mora platiti svaka tona uglja koja se prekomjerno troši. Zato se danas brodovi vode istinski najkraćim putem, često koristeći karte napravljene ne u Mercatorovoj projekciji, već u takozvanoj „centralnoj“ projekciji: na tim kartama lukovi velikih krugova su prikazani kao prave linije.

    Zašto su raniji navigatori koristili takve varljive karte i birali nepovoljne rute? Pogrešno je misliti da u stara vremena nisu znali za sada naznačenu osobinu morskih karata. Stvar se, naravno, ne objašnjava time, već činjenicom da karte iscrtane po Mercatorovoj metodi, uz neugodnosti, imaju i prednosti koje su vrlo vrijedne za nautičare. Takva karta, prvo, prikazuje pojedinačne male dijelove zemljine površine bez izobličenja, zadržavajući kutove konture. Tome nije u suprotnosti činjenica da se s udaljenosti od ekvatora sve konture primjetno rastežu. U visokim geografskim širinama, rastezanje je toliko značajno da nautička karta daje osobi koja nije upoznata s njenim karakteristikama potpuno lažnu ideju o pravoj veličini kontinenata: Grenland izgleda iste veličine kao Afrika, Aljaska je veća od Australije, iako Grenland je 15 puta manji od Afrike, a Aljaska zajedno sa Grenlandom upola manji od Australije. Ali mornara koji dobro poznaje ove karakteristike karte one ne mogu biti zavedene. On ih podnosi, pogotovo jer na malim područjima morska karta daje tačnu sličnost s prirodom (Sl. 5).

    Ali nautička karta uvelike olakšava rješavanje problema navigacijske prakse. Ovo je jedina vrsta karte na kojoj je putanja broda koji se kreće konstantnim kursom prikazana kao prava linija. Hodati „konstantnim kursom“ znači dosledno se pridržavati jednog pravca, jedne specifične „referentne tačke“, drugim rečima, hodati na takav način da sijeku sve meridijane pod jednakim uglom. Ali ovaj put ("loksodrom") može se prikazati kao prava linija samo na karti na kojoj su svi meridijani ravne linije paralelne jedna s drugom. A budući da se na globusu krugovi geografske širine sijeku s meridijanima pod pravim kutom, onda bi na takvoj karti krugovi geografske širine trebali biti ravne linije okomite na linije meridijana. Ukratko, dolazimo do upravo koordinatne mreže koja čini karakterističnu osobinu morske karte.




    Rice. 5. Nautička ili Mercator karta globusa. Takve karte uvelike preuveličavaju veličinu kontura udaljenih od ekvatora. Šta je, na primjer, veće: Grenland ili Australija? (Odgovor u tekstu)


    Sklonost mornara za Mercatorove karte je sada razumljiva. Želeći da odredi kurs koji treba pratiti pri odlasku u naznačenu luku, navigator primenjuje ravnalo na krajnje tačke putanje i meri ugao koji pravi sa meridijanima. Držeći se cijelo vrijeme na otvorenom moru u ovom smjeru, navigator će precizno dovesti brod do cilja. Vidite da je “loksodrom” iako nije najkraći i ne najekonomičniji, ali u određenom pogledu vrlo zgodna ruta za nautičara. Da biste stigli, na primjer, od Rta dobre nade do južnog vrha Australije (vidi sliku 1), uvijek morate ostati na istom kursu S 87°.50". U međuvremenu, da bi se brod doveo do istog finala tačka najkraći put(prema „ortodromu“), potrebno je, kao što se vidi iz slike, kontinuirano mijenjati kurs broda: početi kursom S 42°.50", a završiti kursom N 53°,50 “ (u ovom slučaju najkraći put nije ni izvodljiv – on se naslanja na antarktički ledeni zid).

    Oba puta - duž "loksodroma" i duž "ortodroma" - poklapaju se samo kada je put duž velikog kruga prikazan na morskoj karti kao prava linija: kada se kreće duž ekvatora ili duž meridijana. U svim ostalim slučajevima ovi putevi su različiti.

    Dijkstrin algoritam je algoritam grafa koji je izumio holandski naučnik Edsger Dijkstra 1959. godine. Pronalazi najkraće putanje od jednog od vrhova grafa do svih ostalih. Algoritam radi samo za grafove bez rubova negativne težine.

    Razmotrimo izvođenje algoritma koristeći primjer grafa prikazanog na slici.

    Pretpostavimo da trebate pronaći najkraće udaljenosti od 1. vrha do svih ostalih.

    Krugovi označavaju vrhove, linije označavaju putanje između njih (ivice grafa). Brojevi vrhova su naznačeni u krugovima, a njihova "cijena" je naznačena iznad ivica - dužine puta. Pored svakog vrha nalazi se crvena oznaka - dužina najkraćeg puta do ovog vrha od vrha 1.

    Prvi korak. Pogledajmo korak Dijkstrinog algoritma za naš primjer. Vertex 1 ima minimalnu oznaku.Njegovi susjedi su vrhovi 2, 3 i 6.

    Prvi susjed vrha 1 je vrh 2, jer je dužina puta do njega minimalna. Dužina puta u njega kroz vrh 1 jednaka je zbiru vrijednosti oznake vrha 1 i dužine ivice koja ide od 1. do 2., odnosno 0 + 7 = 7. Ovo je manje od trenutna oznaka vrha 2, beskonačnost, tako da je nova oznaka 2. vrh je 7.

    Sličnu operaciju izvodimo sa još dva susjeda 1. vrha - 3. i 6.

    Svi susjedi vrha 1 su provjereni. Trenutna minimalna udaljenost do vrha 1 smatra se konačnom i ne može se revidirati (da je to zaista slučaj prvi je dokazao E. Dijkstra). Precrtajmo ga iz grafa da označimo da je ovo vrh posjećen.

    Drugi korak. Korak algoritma se ponavlja. Opet nalazimo „najbliži“ od neposjećenih vrhova. Ovo je vrh 2 sa oznakom 7.

    Opet pokušavamo smanjiti oznake susjeda odabranog vrha, pokušavajući proći kroz 2. vrh u njih. Susjedi vrha 2 su vrhovi 1, 3 i 4.

    Prvi (po redu) susjed vrha 2 je vrh 1. Ali on je već posjećen, tako da ne radimo ništa sa 1. vrhom.

    Sljedeći susjed vrha 2 je vrh 3, budući da ima minimalnu oznaku vrhova označenih kao neposjećenih. Ako idete do njega kroz 2, tada će dužina takve staze biti jednaka 17 (7 + 10 = 17). Ali trenutna oznaka trećeg vrha je 9, što je manje od 17, tako da se oznaka ne mijenja.

    Drugi susjed vrha 2 je vrh 4. Ako do njega idete kroz 2., tada će dužina takve putanje biti jednaka zbroju najkraće udaljenosti do 2. vrha i udaljenosti između vrhova 2 i 4, tj. , 22 (7 + 15 = 22) . Od 22<, устанавливаем метку вершины 4 равной 22.

    Svi susjedi vrha 2 su pregledani, zamrzavamo udaljenost do njega i označavamo ga kao posjećenog.

    Treći korak. Ponavljamo korak algoritma, birajući vrh 3. Nakon što ga “obradimo” dobijamo sljedeće rezultate:

    Sljedeći koraci. Ponavljamo korak algoritma za preostale vrhove. To će biti vrhovi 6, 4 i 5, prema redoslijedu.

    Završetak izvođenja algoritma. Algoritam se završava kada se više ne može obraditi vrh. U ovom primjeru su svi vrhovi precrtani, ali je pogrešno pretpostaviti da će to biti slučaj u bilo kojem primjeru - neki vrhovi mogu ostati neprecrtani ako se ne mogu dosegnuti, odnosno ako je graf isključen. Rezultat algoritma je vidljiv na posljednjoj slici: najkraći put od vrha 1 do 2 je 7, do 3 je 9, do 4 je 20, do 5 je 20, do 6 je 11.

    Implementacija algoritma u različitim programskim jezicima:

    C++

    #include "stdafx.h" #include korištenje imenskog prostora std; const int V=6; //Dijkstrin algoritam void Dijkstra(int GR[V][V], int st) (int distance[V], count, index, i, u, m=st+1; bool posjećen[V]; for (i= 0;i "< "<> "; cin>>start; Dijkstra(GR, start-1); system("pause>>void"); )

    Pascal

    program DijkstraAlgoritam; koristi crt; const V=6; inf=100000; tip vektor=niz cijelog broja; var početak: cijeli broj; const GR: niz cijelih brojeva=((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)); (Dijkstrin algoritam) procedura Dijkstra(GR: niz cijelih brojeva; st: cijeli broj); var broj, indeks, i, u, m, min: cijeli broj; udaljenost: vektor; posjećeno: niz boolean; početak m:=st; za i:=1 do V do start distance[i]:=inf; posjećeno[i]:=false; kraj; udaljenost:=0; za count:=1 do V-1 do begin min:=inf; za i:=1 do V uradi ako (nije posjećeno[i]) i (udaljenost[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) i (udaljenost[u]<>inf) i (udaljenost[u]+GR inf zatim writeln(m," > ", i," = ", distance[i]) else writeln(m," > ", i," = ", "ruta nedostupna"); kraj; (glavni blok programa) begin clrscr; write("Početni vrh >> "); čitanje (početak); Dijkstra (GR, početak); kraj.

    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; javna klasa Rješenje ( private static int INF = Integer.MAX_VALUE / 2; private int n; //broj vrhova u digrafu private int m; //broj lukova u digrafu private ArrayList adj; //popis susjedstva privatni ArrayList težina; // težina ruba u digrafu privatni boolean korišten; //niz za pohranjivanje informacija o pređenim i nepređenim vrhovima private int dist; //niz za pohranjivanje udaljenosti od početnog vrha //niz predaka potrebnih za vraćanje najkraće staze od početnog vrha private int pred; int start; //početni vrh od kojeg se traži udaljenost do svih ostalih vrhova private BufferedReader cin; privatni PrintWriter cout; privatni StringTokenizer tokenizer; //procedura za pokretanje Dijkstrinog algoritma iz početnog vrha private void dejkstra(int s) ( dist[s] = 0; //najkraća udaljenost do početnog vrha je 0 for (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(); ) //inicijaliziranje liste koja pohranjuje težine rubova weight = new ArrayList[n]; za (int i = 0; i< n; ++i) { weight[i] = new ArrayList(); ) //čitaj graf specificiran listom ivica za (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(); } }

    Druga opcija:

    Uvezi java.io.*; import java.util.*; javna klasa Dijkstra ( privatni statički konačni Graph.Edge GRAPH = ( novi Graph.Edge("a", "b", 7), novi Graph.Edge("a", "c", 9), novi Graph.Edge( "a", "f", 14), novi Graph.Edge("b", "c", 10), novi Graph.Edge("b", "d", 15), novi Graph.Edge("c ", "d", 11), novi Graph.Edge("c", "f", 2), novi Graph.Edge("d", "e", 6), novi Graph.Edge("e", "f", 9), ); privatni statički konačni niz START = "a"; privatni statički konačni niz END = "e"; javni statički void main(args niza) (Graf g = novi grafikon(GRAF); g.dijkstra (START); g.printPath(END); //g.printAllPaths(); ) ) class Graph ( privatna konačna mapa graf; // mapiranje imena vrhova u Vertex objekte, izgrađeno od skupa rubova /** Jedna ivica grafa (koristi se samo od strane Graph konstruktora) */ javna statička klasa 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; ) ) /** Jedan vrh grafa, zajedno sa preslikavanjima na susjedne vrhove */ javna statička klasa Vertex implementira Comparable ( public final String name; public int dist = Integer.MAX_VALUE; // MAX_VALUE pretpostavlja se da je beskonačnost public Vertex previous = null; javna konačna mapa susjedi = nova HashMap<>(); public Vertex(ime niza) (ovo.name = ime; ) private void printPath() ( if (ovo == ovo.prethodno) ( System.out.printf("%s", ovo.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) (vrati Integer.compare(dist, other.dist); ) ) /** Gradi graf iz skupa ivica * / public Graph (ivice rubova) ( graf = novi HashMap<>(ivice.dužina); //jedan prolaz za pronalaženje svih vrhova za (Edge e: ivice) ( 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)); ) //još jedan prolaz za postavljanje susjednih vrhova za (Edge e: rubove) ( graph.get(e.v1). susjedi.put(graph.get(e.v2), e.dist); //graph.get(e.v2).neighbors.put(graph.get(e.v1), e.dist); // također uradi ovo za neusmjereni graf ) ) /** Pokreće dijkstru koristeći specificirani izvorni vrh */ public void dijkstra(String startName) ( if (!graph.containsKey(startName)) ( System.err.printf("Graph does"t sadrži početni vrh \"%s\"\n", startName); return; ) konačni izvor vrha = graph.get(startName); NavigableSet q = novi TreeSet<>(); // postavljanje vrhova za (Vertex v: graph.values()) ( v.previous = v == izvor ? izvor: null; v.dist = v == izvor ? 0: Integer.MAX_VALUE; q.add( v); ) dijkstra(q); ) /** Implementacija dijkstrinog algoritma koristeći binarnu hrpu */ private void dijkstra(final NavigableSet q) ( Vertex u, v; while (!q.isEmpty()) ( u = q.pollFirst(); // vrh sa najkraćom udaljenosti (prva iteracija će vratiti izvor) if (u.dist == Integer.MAX_VALUE) break; // možemo zanemariti u (i sve ostale preostale vrhove) jer su nedostižni //pogledajte udaljenosti do svakog susjeda za (Map.Entry a: u.neighbours.entrySet()) ( v = a.getKey(); //susjed u ovoj iteraciji 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

    #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; /* cilj ove ivice */ edge_t *sibling;/* za jednostruko povezanu listu */ int len; /* cijena ruba */ ); struct node_t ( edge_t *edge; /* jednostruko povezana lista ivica */ node_t *via; /* gdje je prethodni čvor na najkraćoj putanji */ dupla dist; /* udaljenost od izvornog čvora */ char ime; /* the, er , name */ int heap_idx; /* veza do pozicije hrpe za ažuriranje udaljenosti */ ); /* --- upravljanje ivicama --- */ #ifdef BIG_EXAMPLE # definiše BLOCK_SIZE (1024 * 32 - 1) #else # definiše BLOCK_SIZE 15 #endif edge_t *edge_root = 0, *e_next = 0; /* Ne obazirite se na stvari za upravljanje memorijom, one su izvan poente. Pretvarajte se e_next = malloc(sizeof(edge_t)) */ void add_edge(node_t *a, node_t *b, duplo 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; lenne_next; e_next; ->sibling = a->edge; a->edge = e_next; ) void free_edges() ( za (; edge_root; edge_root = e_next) ( e_next = edge_root.sibling; free(edge_root); ) ) /* --- stvari reda prioriteta --- */ heap_t *heap; int heap_len; void set_dist(node_t *nd, node_t *via, double d) ( int i, j; /* već je znao bolji put */ if (nd->via && d >= nd->dist) return; /* pronađi postojeći unos u hrpi ili kreiraj novi */ nd->dist = d; nd->via = via; i = nd->heap_idx; if (!i) i = ++heap_len; /* upheap */ za (; i > 1 && nd->dist< heap->dist; i = j) (heap[i] = hrpa[j])->heap_idx = i; hrpa[i] = nd; nd->heap_idx = i; ) node_t * pop_queue() ( node_t *nd, *tmp; int i, j; ako (!heap_len) vrati 0; /* ukloni vodeći element, povuci repni element tamo i downheap */ nd = hrpa; tmp = hrpa; za (i = 1; i< heap_len && (j = i * 2) <= heap_len; i = j) { if (j < heap_len && heap[j]->dist > hrpa->dist) j++; if (heap[j]->dist >= tmp->dist) break; (hrpa[i] = gomila[j])->heap_idx = i; ) hrpa[i] = tmp; tmp->heap_idx = i; return nd; ) /* --- Dijkstra stvari; nedostižni čvorovi nikada neće napraviti u queue --- */ 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->sibling) 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; # definiše N_NODES ("f" - "a" + 1) node_t * čvorovi = 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

    $edge, "cost" => $edge); $neighbors[$edge] = array("end" => $edge, "cost" => $edge); ) $vertices = array_unique($vertices); foreach ($vertices kao $vertex) ( $dist[$vertex] = INF; $previous[$vertex] = NULL; ) $dist[$source] = 0; $Q = $vertices; while (count($Q) > 0) ( // TODO - Pronađite brži način da dobijete minimum $min = INF; foreach ($Q kao $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

    iz kolekcija import namedtuple, red iz pprint import pprint kao pp inf = float("inf") Edge = namedtuple("Edge", "početak, kraj, cijena") class Graph(): def __init__(self, rubovi): self .edges = edges2 = self.vertices = set(suma(( za e u rubovima2, )) def dijkstra(self, source, dest): potvrditi izvor u self.vertices dist = (vrh: inf za vrh u self.vertices) prethodni = (vrh: Nema za vrh u self.vertices) dist = 0 q = self.vertices.copy() susjedi = (vertex: set() za vrh u self.vertices) za početak, kraj, trošak u self. ivice : susjedi.add((kraj, cijena)) #pp(susjedi) dok q: u = min(q, ključ=lambda vrh: dist) q.remove(u) ako dist[u] == inf ili u = = dest: prekid za v, cijena u susjedima[u]: alt = dist[u] + cijena ako 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"]