Znate li zašto je dalje u pravoj liniji nego u luku? Najkraći put na zemlji i na karti Odredi udaljenost između dvije paralelne linije.

UDALJENOST, udaljenosti, usp. 1. Prostor koji razdvaja dvije točke, jaz između nečega. Najkraća udaljenost između dvije točke u pravoj liniji. Živi od nas na udaljenosti od dva kilometra. „Komandant ih je pustio unutra na najbližoj udaljenosti... Objašnjavajući rječnik Ushakova

udaljenosti- imenica, s., upotreba. često Morfologija: (ne) što? udaljenost za što? udaljenost, (vidi) što? udaljenost od? udaljenost, što? o udaljenosti; pl. što? udaljenost, (ne) što? udaljenosti, zašto? udaljenosti, (vidi) što? udaljenost od? udaljenosti... Rječnik Dmitriev

udaljenosti- ja; usp. Prostor koji razdvaja dvije točke, dva objekta, itd., jaz između nekoga, nego l. Najkraća rijeka između dvije točke. R. od kuće do škole. Povlačenje do obližnje rijeke. Na udaljenosti od metar, ispruženih ruku. Znati nešto, osjetiti nešto. na… … enciklopedijski rječnik

udaljenosti- ja; usp. vidi također udaljenost a) Prostor koji razdvaja dvije točke, dva predmeta, itd., jaz između nekoga, nego l. Najkraća udaljenost između dvije točke. Udaljenost od kuće do škole. Povlačenje na blisku udaljenost / nie ... Rječnik mnogih izraza

GEOMETRIJA- grana matematike koja proučava svojstva raznih oblika (točke, linije, kutovi, dvodimenzionalni i trodimenzionalni objekti), njihovu veličinu i relativni položaj. Radi praktičnosti nastave geometrija se dijeli na planimetriju i geometriju čvrstog tijela. NA… … Enciklopedija Collier

Navigacija*

Navigacija- odjel za plovidbu (vidi), zaključujući prikaz načina određivanja mjesta broda na moru, pomoću kompasa i dnevnika (vidi). Odrediti mjesto broda na moru znači staviti na kartu točku na kojoj se brod trenutno nalazi. ... ... Enciklopedijski rječnik F.A. Brockhaus i I.A. Efron

COGEN- (Cohen) Hermann (1842. 1918.) njemački filozof, utemeljitelj i istaknuti predstavnik marburške škole neokantovizma. Glavna djela: 'Kantova teorija iskustva' (1885), 'Kantovo opravdanje etike' (1877), 'Kantovo opravdanje estetike' (1889), 'Logika… ...

Kant Immanuel- Životni put i spisi Kanta Immanuel Kant rođen je u Königsbergu (danas Kalinjingrad) u Istočnoj Pruskoj 1724. godine. Otac mu je bio sedlar, a majka domaćica, šestero njihove djece nije doživjelo punoljetnost. Kant se svojih roditelja uvijek sjećao s ... ... Zapadna filozofija od nastanka do danas

KANTOVA KRITIČKA FILOZOFIJA: DOKTRINA SPOSOBNOSTI- (La philosophie critique de Kant: Doctrines des facultes, 1963.) od Deleuzea. Opisujući transcendentalnu metodu u uvodu, Deleuze napominje da Kant shvaća filozofiju kao znanost o odnosu cjelokupnog znanja prema bitnim ciljevima... ... Povijest filozofije: Enciklopedija

princip farme- osnovni princip geometrijske optike (Vidi Geometrijska optika). Najjednostavniji oblik F. p. je tvrdnja da se zraka svjetlosti uvijek širi u prostoru između dviju točaka duž putanje duž koje je vrijeme njenog prolaska manje od ... Velika sovjetska enciklopedija

Put uz isprekidanu liniju na slici kraći je od puta uz punu liniju. A sada malo detaljnije na primjeru morskih putova:

Ako plovite stalnim kursom, tada će putanja broda na zemljinoj površini biti krivulja, koja se u matematici naziva logaritamskispirala.

U navigaciji se ova složena linija dvostruke zakrivljenosti naziva loksodromija, što na grčkom znači "koso trčanje".

Međutim, najkraća udaljenost između dviju točaka na globusu mjeri se duž luka velike kružnice.

Luk velike kružnice dobiva se kao trag od presjeka zemljine površine s ravninom koja prolazi kroz središte Zemlje, uzeta kao lopta.

U navigaciji se zove veliki kružni luk veliki krug, što znači "ravno trčanje". Druga značajka velikog kruga je to što on prelazi meridijane pod različitim kutovima (slika 29).

Razlika u udaljenostima između dviju točaka na zemljinoj površini duž loksodroma i ortodroma od praktične je važnosti samo za velike prijelaze preko oceana.

U normalnim uvjetima ta se razlika zanemaruje i plovidba se vrši stalnim kursom, t.j. loksodromom.

Za izvođenje jednadžbe uzimamo loksodromije (slika 30, a) dvije točkice ALI i NA, udaljenost između njih je jednostavno mala. Crtajući meridijane i paralelu kroz njih, dobivamo elementarni pravokutni sferni trokut ABC. U ovom trokutu kut nastao presjekom meridijana i paralele je pravi, a kut PnAB jednak kursu broda K. Katet AC predstavlja segment meridijanskog luka i može se izraziti

gdje R - polumjer Zemlje uzet kao kugla;

Δφ - elementarni prirast zemljopisne širine (razlika zemljopisnih širina).

noga SW predstavlja paralelni lučni segment

gdje je r - polumjer paralele;

Δλ - elementarna razlika dužina.

Iz trokuta OO 1 C može se naći da

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

Uz pretpostavku elementarnog sfernog trokuta ABC za stan, napiši

Nakon redukcije R i zamjenom elementarnih malih prirasta koordinata beskonačno malim, imamo

Dobiveni izraz integriramo u raspon od φ 1, λ 1 do φ 2, λ 2 smatrajući vrijednost tgK konstantnom vrijednošću:

Na desnoj strani imamo tablični integral. Nakon zamjene njegove vrijednosti, dobivamo jednadžbu loksodroma na lopti

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

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

Na tečajevima od 90 i 270 °, loksodrom se podudara s paralelom;

Loksodrom presijeca svaku paralelu samo jednom, a svaki meridijan nebrojen broj puta. oni. spiralno se približava polu, ne dopire do njega.

Plovidba stalnim kursom, odnosno loksodromom, iako to nije najkraća udaljenost između dvije točke na Zemlji, predstavlja znatnu pogodnost za navigatora.

Zahtjevi za pomorsku navigacijsku kartu mogu se formulirati na temelju prednosti plovidbe duž loksodroma i rezultata analize njegove jednadžbe kako slijedi.

1. Loksodrom, koji prelazi meridijane pod stalnim kutom, trebao bi biti prikazan kao ravna linija.

2. Kartografska projekcija koja se koristi za izradu karata mora biti konformna tako da smjerovi, smjerovi i kutovi na njoj odgovaraju njihovoj vrijednosti na terenu.

3. Meridijani i paralele, poput pravca tečaja 0, 90, 180° i 270°, moraju biti međusobno okomite ravne linije.

Najkraća udaljenost između dviju zadanih točaka na površini Zemlje, uzeta kao kugla, je manji od lukova velike kružnice koji prolazi kroz te točke. Osim u slučaju da plovilo prati meridijan ili ekvator, veliki krug prelazi meridijane pod različitim kutovima. Stoga brod koji slijedi takvu krivulju mora cijelo vrijeme mijenjati svoj kurs. Praktički je prikladnije pratiti kurs koji čini stalan kut s meridijanima i koji je na karti u Mercatorovoj projekciji prikazan ravnom linijom - loksodromom. Međutim, na velikim udaljenostima razlika u duljini ortodroma i loksodroma doseže značajnu vrijednost. Stoga se u takvim slučajevima ortodrom izračunava i na njemu se označavaju međutočke između kojih plivaju po loksodromu.

Kartografsku projekciju koja zadovoljava navedene zahtjeve predložio je nizozemski kartograf Gerard Cramer (Mercator) 1569. godine. U čast svog tvorca projekcija je nazvana Mercator.

A tko želi saznati još zanimljivije informacije, saznajte više Originalni članak je na web stranici InfoGlaz.rf Link na članak iz kojeg je napravljena ova kopija -

(Deskriptivna geometrija)
  • CD (CXDX, C2D2) prikazano kao točka C5 = D5 A5B5 jednako...
    (Deskriptivna geometrija)
  • Određivanje udaljenosti između dvije paralelne ravnine
    Određivanje udaljenosti između dvije paralelne ravnine u općem položaju 01| x zgodno ga je svesti na problem određivanja udaljenosti između iste dvije ravnine, transformirane u položaj projiciranih. U ovom slučaju, udaljenost između ravnina definira se kao okomica između linija, ...
    (Deskriptivna geometrija)
  • Određivanje udaljenosti između dvaju linija koje se sijeku
    Ako želite odrediti najkraću udaljenost između dvije linije koje se sijeku, morate dvaput promijeniti sustave projekcijskih ravnina. Prilikom rješavanja ovog problema izravna CD (CXDX, C2D2) prikazano kao točka C5 = D5(Sl. 198). Udaljenost od ove točke do projekcije A5B5 jednako...
    (Deskriptivna geometrija)
  • Kut između dvije ravne crte koje se sijeku
    Ovo je kut između dvije linije koje se sijeku paralelne s podacima. Dakle, ovaj zadatak je sličan prethodnom. Da biste ga riješili, potrebno je uzeti proizvoljnu točku i kroz nju povući dvije ravne, paralelne sa zadanim kosim ravnim linijama, te pomoću projekcijskih transformacija odrediti željeni kut....
    (Osnove deskriptivne geometrije. Kratak tečaj i zbirka zadataka.)
  • Određivanje udaljenosti između dva paralelna pravca
    Problem se rješava metodom dvostruke zamjene projekcijskih ravnina. U završnoj fazi, jedna od ravnina projekcije mora biti okomita na jednu od linija koje se sijeku. Tada je najkraća udaljenost između njih određena vrijednošću odsječka okomice na drugu kosinu (slika 199)....
    (Deskriptivna geometrija)
  • Dijkstraov algoritam je grafski algoritam koji je izumio nizozemski znanstvenik Edsger Dijkstra 1959. godine. Pronalazi najkraće staze od jednog od vrhova grafa do svih ostalih. Algoritam radi samo za grafove bez rubova negativne težine.

    Razmotrimo izvođenje algoritma na primjeru grafa prikazanog na slici.

    Neka je potrebno pronaći najkraće udaljenosti od 1. vrha do svih ostalih.

    Krugovi označavaju vrhove, linije označavaju putove između njih (rubove grafa). Brojevi vrhova su naznačeni u krugovima, njihova "cijena" - duljina puta - naznačena je iznad rubova. Pored svakog vrha označena je crvena oznaka - duljina najkraćeg puta do ovog vrha od vrha 1.

    Prvi korak. Razmotrimo korak u Dijkstrinom algoritmu za naš primjer. Vrh 1 ima minimalnu oznaku. Vrhovi 2, 3 i 6 su njegovi susjedi.

    Prvi susjed vrha 1 je zauzvrat vrh 2, jer je duljina puta do njega minimalna. Duljina puta do njega kroz vrh 1 jednaka je zbroju vrijednosti oznake vrha 1 i duljine ruba koji ide od 1. do 2., odnosno 0 + 7 = 7. To je manje od trenutna oznaka vrha 2, beskonačnost, tako da je nova oznaka 2. vrha 7.

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

    Svi susjedi čvora 1 su provjereni. Trenutna minimalna udaljenost do vrha 1 smatra se konačnom i ne podliježe reviziji (činjenicu da je to doista slučaj prvi je dokazao E. Dijkstra). Prekrižite ga iz grafa kako biste označili da je ovaj vrh posjećen.

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

    Opet pokušavamo smanjiti oznake susjeda odabranog vrha, pokušavajući proći kroz njih kroz 2. vrh. 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 s 1. vrhom.

    Sljedeći susjed vrha 2 je vrh 3, budući da ima minimalnu oznaku vrhova označenih kao neposjećeni. Ako idete do njega kroz 2, tada će duljina takvog puta 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 duljina takve staze 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.

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

    Treći korak. Korak algoritma ponavljamo odabirom vrha 3. Nakon njegove "obrade" dobivamo sljedeće rezultate:

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

    Završetak izvođenja algoritma. Algoritam završava kada se više ne mogu obraditi vrhovi. U ovom su primjeru 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, tj. 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 raznim 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; usescrt; constV=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)); (Dijkstraov algoritam) procedura Dijkstra(GR: niz cijelih brojeva; st: cijeli broj); var broj, indeks, i, u, m, min: cijeli broj; udaljenost: vektor; posjećeno: niz booleova; početak:=st; za i:=1 do V do start distance[i]:=inf; posjećeno[i]:=netočno; kraj; udaljenost:=0; za count:=1 do V-1 početi min:=inf; za i:=1 do V učiniti 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 programski blok) begin clrscr; write("Početni čvor >> "); čitati (početi); 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 prid; //popis susjedstva privatni ArrayList težina; //težina ruba u digrafu private boolean used; //niz za pohranjivanje informacija o prošlim i neprolaznim vrhovima private int dist; //niz za pohranjivanje udaljenosti od početnog vrha //niz predaka potrebnih za vraćanje najkraćeg puta od početnog vrha private int pred; int početak; //početni vrh, od kojeg se traži udaljenost do svih ostalih private BufferedReader cin; privatni PrintWriter cout; privatni StringTokenizer tokenizer; //procedura za pokretanje Dijkstrinog algoritma od 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 popisa koji pohranjuje težine rubova weight = new ArrayList[n]; za (int i = 0; i< n; ++i) { weight[i] = new ArrayList(); ) //čitaj graf zadan popisom bridova 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(GRAPH); g.dijkstra (START); g.printPath(END); //g.printAllPaths(); ) ) class Graph (privatna konačna karta graf; // mapiranje imena vrhova u objekte Vertex, izgrađeno od skupa rubova /** Jedan rub grafa (koristi ga samo konstruktor Graph) */ 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 s preslikavanjima na susjedne vrhove */ javna statička klasa Vertex implementira Comparable ( javni konačni naziv niza; public int dist = Integer.MAX_VALUE; // MAX_VALUE pretpostavlja se da je beskonačno javni vrh prethodni = null; javna konačna karta susjedi = novi HashMap<>(); public Vertex(Naziv niza) ( this.name = name; ) private void printPath() ( if (ovo == 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) (vrati Integer.compare(dist, other.dist); ) ) /** Gradi graf iz skupa bridova * / javni graf (rubovi rubova) ( graf = novi HashMap<>(rubovi.dužina); //jedan prolaz za pronalaženje svih vrhova za (Edge e: bridovi) ( 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: bridove) ( graph.get(e.v1). susjedi.put(graph.get(e.v2), e.dist); //graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // također učinite to za neusmjereni graf ) ) /** Pokreće dijkstru koristeći specificirani izvorni vrh */ public void dijkstra(String startName) ( if (!graph.containsKey(startName)) ( System.err.printf("Graf ne sadržavati početni vrh \"%s\"\n", startName); return; ) konačni izvor vrha = graph.get(startName); NavigableSet q = novi skup stabala<>(); // 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 korištenjem binarne hrpe. */ private void dijkstra(final NavigableSet q) ( Vertex u, v; while (!q.isEmpty()) ( u = q.pollFirst(); // vrh s 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

    #uključiti #uključiti #uključiti //#define BIG_EXAMPLE typedef struct node_t node_t, *heap_t; typedef struktura rub_t rub_t; struct edge_t ( node_t *nd; /* cilj ovog ruba */ edge_t *sibling;/* za jednostruko povezan popis */ int len; /* trošak ruba */ ); struct node_t ( edge_t *edge; /* jednostruko povezana lista rubova */ node_t *via; /* gdje je prethodni čvor na najkraćem putu */ dupla dist; /* udaljenost od izvornog čvora */ char naziv; /* the, er , name */ int heap_idx; /* veza do pozicije hrpe za ažuriranje udaljenosti */ ); /* --- upravljanje rubovima --- */ #ifdef BIG_EXAMPLE # definiraj BLOCK_SIZE (1024 * 32 - 1) #else # definiraj BLOCK_SIZE 15 #endif edge_t *edge_root = 0, *e_next = 0; /* Ne obazirite se na stvari za upravljanje memorijom, one nisu bitne. Pretvarajte se 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; lenne_next; e_next; e_ ->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 hrpe 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) (gomila[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; (gomila[i] = hrpa[j])->heap_idx = i; ) hrpa[i] = tmp; tmp->heap_idx = i; vratiti nd; ) /* --- Dijkstra stvari; nedostupni čvorovi nikada neće ući u red čekanja --- */ 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-> preko == 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 VELIKI_PRIMJER int i; # definiraj N_Čvorova ("f" - " a" + 1) node_t *čvorovi = calloc(sizeof(node_t), N_NODES); za (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); $neighbours[$edge] = array("end" => $edge, "cost" => $edge); ) $vrhovi = array_unique($vertices); foreach ($vertices kao $vertex) ( $dist[$vertex] = INF; $previous[$vertex] = NULL; ) $dist[$source] = 0; $Q = $vrhovi; 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";


    Piton

    iz zbirki uvoz namedtuple, red čekanja iz pprint uvoz pprint kao pp inf = float("inf") Edge = namedtuple("Edge", "početak, kraj, cijena") class Graph(): def __init__(self, rubovi): self .edges = rubovi2 = self.vertices = set(zbroj(( 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 = (vrh: set() za vrh u self.vertices) za početak, kraj, trošak u self. rubovi: susjedi.dodaj((kraj, trošak)) #pp(susjedi) dok je q: u = min(q, ključ=lambda vrh: dist) q.ukloni(u) ako je dist[u] == inf ili u = = odredište: 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"]

    Nakon što je kredom ocrtao dvije točke na ploči, učitelj nudi mladom učeniku zadatak: nacrtati najkraći put između obje točke.

    Učenik, nakon razmišljanja, marljivo povlači vijugavu liniju između njih.

    - To je najkraći put! začudi se učiteljica. - Tko te je tome naučio?

    - Moj otac. On je taksist.

    Crtež naivnog školarca je, naravno, anegdotalan, ali zar se ne biste nasmiješili da vam kažu da je točkasti luk na si. 1 je najkraći put od Rta dobre nade do južnog vrha Australije!

    Još je upečatljivija sljedeća izjava: prikazana na sl. 2 povratno putovanje od Japana do Panamskog kanala kraće je od ravne linije povučene između njih na istoj karti!

    Riža. 1. Na nautičkoj karti najkraći put od Rta dobre nade do južnog vrha Australije nije označen ravnom linijom ("loksodrom"), već krivuljom ("ortodromija")


    Sve ovo izgleda kao šala, ali u međuvremenu su pred vama neosporne istine, dobro poznate kartografima.




    Riža. 2. Čini se nevjerojatnim da je zakrivljena staza koja povezuje Yokohamu na morskoj karti s Panamskim kanalom kraća od ravne linije povučene između istih točaka


    Da bi se razjasnilo pitanje, morat će se reći nekoliko riječi o kartama općenito, a posebno o nautičkim kartama. Prikaz dijelova zemljine površine na papiru nije lak zadatak, čak ni načelno, jer je Zemlja kugla, a poznato je da se niti jedan dio sferne površine ne može rasporediti na ravninu bez nabora i lomova. Nehotice se mora pomiriti s neizbježnim iskrivljenjima na kartama. Izmišljeni su mnogi načini crtanja karata, ali sve karte nisu slobodne od nedostataka: neke imaju izobličenja jedne vrste, druge druge, ali karte bez izobličenja uopće nema.

    Pomorci koriste karte nacrtane prema metodi starog nizozemskog kartografa i matematičara iz 16. stoljeća. Mercator. Ova metoda se zove Mercatorova projekcija. Lako je prepoznati morsku kartu po pravokutnoj mreži: meridijani su na njoj prikazani kao niz paralelnih ravnih linija; krugovi zemljopisne širine - također u ravnim linijama okomitim na prvi (vidi sliku 5).

    Zamislite sada da želite pronaći najkraći put od jedne oceanske luke do druge na istoj paraleli. Na oceanu su sve staze dostupne, a tamo je uvijek moguće putovati najkraćom stazom ako znate kako leži. U našem slučaju, prirodno je misliti da najkraći put ide paralelom na kojoj se nalaze obje luke: uostalom, na karti je to ravna crta, a što može biti kraće od ravne staze! Ali varamo se: put uz paralelu nije nimalo najkraći.

    Doista: na površini kugle, najkraća udaljenost između dvije točke je veliki kružni luk koji ih povezuje. Ali krug paralela mali krug. Luk velike kružnice je manje zakrivljen od luka bilo koje male kružnice povučen kroz iste dvije točke: veći polumjer odgovara manjoj zakrivljenosti. Povucite nit na globusu između naše dvije točke (usp. sl. 3); pobrinut ćeš se da uopće ne leži uz paralelu. Istegnuta nit je neosporan pokazatelj najkraćeg puta, a ako se ne podudara s paralelom na globusu, tada na morskoj karti najkraći put nije označen ravnom linijom: zapamtite da su na takvim kružnicama prikazane paralele karta po ravnim linijama, bilo koja linija koja se ne poklapa s ravnom linijom, postoji zavoj .



    Riža. 3. Jednostavan način da pronađete stvarno najkraći put između dvije točke: trebate povući nit na globusu između ovih točaka


    Nakon što je rečeno, postaje jasno zašto se najkraći put na morskoj karti ne prikazuje kao ravna, već kao zakrivljena linija.

    Kažu da su pri odabiru smjera za Nikolajevsku (sada Oktjabrsku) željeznicu postojali beskrajni sporovi o tome na koji način je postaviti. Sporovi su okončani intervencijom cara Nikole I., koji je problem riješio doslovno "jednostavno": linijom je povezao Sankt Peterburg s Moskvom. Da je to učinjeno na karti Mercatora, bilo bi to neugodno iznenađenje: umjesto ravne, cesta bi ispala krivulja.

    Tko ne izbjegava izračune, može se jednostavnom računicom uvjeriti da je put koji nam se na karti čini zakrivljenim 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°. (Postoje li takve dvije luke, naravno, nebitno je za izračun.)



    Riža. 4. Za izračun udaljenosti između točaka A i B na lopti duž luka paralele i duž luka velike kružnice


    Na sl. 4 bod O - središte svijeta, AB - luk kruga zemljopisne širine na kojem leže luke A i B; u njenih 60°. Središte kruga zemljopisne širine nalazi se u točki IZ Zamislite to iz centra O globusa je povučen kroz iste luke veliki kružni luk: njegov polumjer OB = OA = R; proći će blizu nacrtanog luka AB, ali ne odgovara.

    Izračunajmo duljinu svakog luka. Budući da bodovi ALI i NA leže na geografskoj širini od 60°, zatim polumjeri OA i OV pomiriti se OS(os globusa) kut od 30°. U pravokutnom trokutu ASO noga AC (=r), koja leži nasuprot kuta od 30° jednaka je polovici hipotenuze dd;

    sredstva, r=R/2 Dužina luka AB je jedna šestina duljine kruga zemljopisne širine, a budući da ovaj krug ima polovicu duljine velikog kruga (što odgovara polovici polumjera), onda je duljina luka malog kruga



    Da bismo sada odredili duljinu luka velikog kruga nacrtanog između istih točaka (tj. najkraći put između njih), moramo znati veličinu kuta AOW. Akord KAO, oduzimajući luk na 60 ° (mali krug), je stranica pravilnog šesterokuta upisana u isti mali krug; zato AB \u003d r \u003d R / 2

    Crtanje ravne linije od, spojno središte O globus sa sredinom D akordi AB, dobiti pravokutni trokut ODA, gdje je kut D- ravno:

    DA= 1/2 AB i OA=R.

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

    Odavde nalazimo (prema tablicama):

    =14°28",5

    i zbog toga

    = 28°57".

    Sada nije teško pronaći željenu duljinu najkraćeg puta u kilometrima. Izračun se može pojednostaviti ako se sjetimo da je duljina minute velikog kruga globusa

    Saznajemo da je put po kružnici zemljopisne širine, prikazan na morskoj karti ravnom crtom, 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 stvarno leže kako je prikazano na crtežima. Prikazano na sl. 1 kao da je "ravni" morski put od Afrike do Australije 6020 milja, a "krivulja" - 5450 milja, odnosno kraći za 570 milja, odnosno 1050 km. "Izravna" zračna ruta na morskoj karti od Londona do Šangaja presijeca Kaspijsko more, dok stvarno najkraća ruta leži sjeverno od St. Jasno je kakvu ulogu ova pitanja imaju u uštedi vremena i goriva.

    Ako se u doba plovidbe vrijeme dostave nije uvijek cijenilo - tada se "vrijeme" još nije smatralo "novcem", onda se s pojavom parnih brodova mora platiti svaka dodatna tona potrošenog ugljena. Zato u naše dane brodovi plove stvarno najkraćim putem, često koristeći karte napravljene ne u Mercatoru, već u takozvanoj "središnjoj" projekciji: na tim kartama lukovi velikih krugova prikazani su kao ravne linije.

    Zašto su se onda bivši navigatori služili takvim varljivim kartama i birali nepovoljne putove? Pogrešno je misliti da u stara vremena nisu znali za sada naznačeno obilježje morskih karata. Stvar se, naravno, ne objašnjava time, već činjenicom da karte nacrtane po Mercator metodi, uz neugodnosti, imaju vrlo vrijedne prednosti za nautičare. Takva karta, prvo, prikazuje odvojene male dijelove zemljine površine bez izobličenja, čuvajući kutove konture. Tome ne proturječi činjenica da se s udaljenosti od ekvatora sve konture primjetno rastežu. Na visokim geografskim širinama, dio je toliko značajan da morska karta inspirira osobu koja nije upoznata s njegovim značajkama na potpuno lažnu ideju o pravoj veličini kontinenata: čini se da je Grenland iste veličine kao Afrika, Aljaska je veći od Australije, iako je Grenland 15 puta manji od Afrike, a Aljaska zajedno s Grenlandom upola manji od Australije. Ali pomorac koji dobro poznaje te značajke karte ne može se njima zavesti. On ih podnosi, pogotovo jer na malim površinama morska karta daje točnu sličnost prirode (slika 5.).

    S druge strane, pomorska karta uvelike olakšava rješavanje zadataka plovidbene prakse. Ovo je jedina vrsta karata na kojoj je put broda na stalnom kursu prikazan ravnom linijom. Slijediti "konstantan kurs" znači držati se uvijek u jednom smjeru, jednom određenom "rumbu", drugim riječima, ići na takav način da prijeći sve meridijane pod jednakim kutom. Ali ovaj put ("loksodrom") može se prikazati kao ravna crta samo na karti na kojoj su svi meridijani ravne linije paralelne jedna s drugom. A budući da se na globusu krugovi zemljopisne širine sijeku s meridijanima pod pravim kutom, tada bi na takvoj karti krugovi zemljopisne širine trebali biti ravne linije okomite na linije meridijana. Ukratko, dolazimo upravo do koordinatne mreže koja čini karakteristično obilježje morske karte.




    Riža. 5. Nautička ili Mercator karta globusa. Na takvim su kartama dimenzije kontura daleko od ekvatora uvelike pretjerane. Što je, na primjer, veće: Grenland ili Australija? (odgovor u tekstu)


    Sklonost mornara za Mercatorove karte sada je razumljiva. Želeći odrediti smjer kojim se ide u naznačenu luku, navigator postavlja ravnalo na krajnje točke puta i mjeri kut koji čini s 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 zgodan put za nautičara. Da bi se, na primjer, došlo do Rta dobre nade do južnog vrha Australije (vidi sliku 1), uvijek se mora držati isti kurs S 87°, 50". U međuvremenu, kako bi se brod doveo na isti konačnu točku na najkraći način (uz" ) potrebno je, kao što se vidi iz slike, kontinuirano mijenjati kurs plovila: krenuti od kursa S 42°, 50" i završiti kursom N 53 °. 50" (u ovom slučaju, najkraći put nije ni izvediv - počiva na ledenom zidu Antarktika).

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

    Udio: