• The shortest distance between two points. Do you know why it is further in a straight line than in an arc? Determining the distance between two intersecting lines

    01.02.2022

    Having outlined two points on the blackboard with chalk, the teacher offers the young student a task: to draw the shortest path between both points.

    The student, after thinking, diligently draws a winding line between them.

    - That's the shortest way! the teacher is surprised. - Who taught you that?

    - My father. He is a taxi driver.

    The drawing of a naive schoolboy is, of course, anecdotal, but wouldn't you smile if you were told that the dotted arc in fig. 1 is the shortest way from the Cape of Good Hope to the southern tip of Australia!

    Even more striking is the following statement: depicted in Fig. 2 round trip from Japan to the Panama Canal is shorter than the straight line drawn between them on the same map!

    Rice. 1. On a nautical chart, the shortest route from the Cape of Good Hope to the southern tip of Australia is not indicated by a straight line (“loxodrome”), but by a curve (“orthodromy”)


    All this looks like a joke, but meanwhile before you are indisputable truths, well known to cartographers.




    Rice. 2. It seems incredible that the curved path connecting Yokohama on the sea chart with the Panama Canal is shorter than a straight line drawn between the same points


    To clarify the issue, a few words will have to be said about charts in general and about nautical charts in particular. Depicting parts of the earth's surface on paper is not an easy task, even in principle, because the Earth is a sphere, and it is known that no part of the spherical surface can be deployed on a plane without folds and breaks. Involuntarily, one has to put up with the inevitable distortions on the maps. Many ways of drawing maps have been invented, but all maps are not free from shortcomings: some have distortions of one kind, others of a different kind, but there are no maps without distortions at all.

    Sailors use maps drawn according to the method of an old Dutch cartographer and mathematician of the 16th century. Mercator. This method is called the Mercator projection. It is easy to recognize a sea chart by its rectangular grid: the meridians are shown on it as a series of parallel straight lines; circles of latitude - also in straight lines perpendicular to the first (see Fig. 5).

    Imagine now that you want to find the shortest path from one ocean port to another on the same parallel. On the ocean, all paths are available, and it is always possible to travel there along the shortest path if you know how it lies. In our case, it is natural to think that the shortest path goes along the parallel on which both ports lie: after all, on the map it is a straight line, and what can be shorter than a straight path! But we are mistaken: the path along the parallel is not at all the shortest.

    Indeed: on the surface of a sphere, the shortest distance between two points is the arc of the great circle connecting them. But the circle of parallel small a circle. The arc of a great circle is less curved than the arc of any small circle drawn through the same two points: a larger radius corresponds to a smaller curvature. Pull the thread on the globe between our two points (cf. Fig. 3); you will make sure that it does not lie along the parallel at all. A stretched thread is an indisputable indicator of the shortest path, and if it does not coincide with a parallel on a globe, then on a sea chart the shortest path is not indicated by a straight line: remember that circles of parallels are depicted on such a map by straight lines, any line that does not coincide with a straight line , eat curve .



    Rice. 3. A simple way to find the really shortest path between two points: you need to pull a thread on the globe between these points


    After what has been said, it becomes clear why the shortest path on the sea chart is depicted not as a straight line, but as a curved line.

    They say that when choosing the direction for the Nikolaev (now Oktyabrskaya) railway, there were endless disputes about which way to lay it. The disputes were put to an end by the intervention of Tsar Nicholas I, who solved the problem literally “straightforward”: he connected St. Petersburg with Moscow along the line. If this had been done on a Mercator map, it would have been an embarrassing surprise: instead of a straight line, the road would have turned out to be a curve.

    Those who do not avoid calculations can make sure by a simple calculation that the path that seems crooked to us on the map is actually shorter than the one that we are ready to consider straight. Let our two harbors lie on the 60th parallel and be separated by a distance of 60°. (Whether such two harbors actually exist is, of course, immaterial for calculation.)



    Rice. 4. To the calculation of the distances between points A and B on the ball along the arc of the parallel and along the arc of the great circle


    On fig. 4 point ABOUT - center of the globe, AB - the arc of the circle of latitude on which harbors lie A and B; in her 60°. The center of the circle of latitude is at a point FROM Imagine that from the center ABOUT of the globe is drawn through the same harbors a great circle arc: its radius OB = OA = R; it will pass close to the drawn arc AB, but it doesn't match.

    Let's calculate the length of each arc. Since the points BUT And IN lie at a latitude of 60°, then the radii OA And OV make up with OS(the axis of the globe) an angle of 30°. In a right triangle ASO leg AC (=r), lying opposite an angle of 30° is equal to half the hypotenuse JSC;

    means, r=R/2 Arc length AB is one-sixth the length of the circle of latitude, and since this circle has half the length of the large circle (corresponding to half the radius), then the length of the arc of the small circle



    To determine now the length of the arc of a great circle drawn between the same points (i.e., the shortest path between them), we need to know the magnitude of the angle AOW. Chord AS, subtracting the arc to 60 ° (small circle), is the side of a regular hexagon inscribed in the same small circle; that's why AB \u003d r \u003d R / 2

    Drawing a straight line od, connecting center ABOUT the globe with the middle D chords AB, get a right triangle ODA, where is the angle D- straight:

    DA= 1/2 AB and OA=R.

    sinAOD=AD: AO=R/4:R=0.25

    From here we find (according to the tables):

    =14°28",5

    and hence

    = 28°57".

    Now it is not difficult to find the desired length of the shortest path in kilometers. The calculation can be simplified if we remember that the length of a minute of a great circle of the globe is

    We learn that the path along the circle of latitude, shown on the sea chart by a straight line, is 3333 km, and the path along the large circle - along the curve on the map - 3213 km, i.e. 120 km shorter.

    Armed with a thread and a globe at hand, you can easily check the correctness of our drawings and make sure that the arcs of the great circles really lie as shown in the drawings. Shown in fig. 1 as if the "straight" sea route from Africa to Australia is 6020 miles, and the "curve" - ​​5450 miles, i.e. shorter by 570 miles, or 1050 km. The "direct" air route on the sea chart from London to Shanghai cuts through the Caspian Sea, while the really shortest route lies north of St. Petersburg. It is clear what role these issues play in saving time and fuel.

    If in the era of sailing shipping time was not always valued - then "time" was not yet considered "money", then with the advent of steam ships, one has to pay for each extra ton of coal consumed. That is why in our days ships are navigating along the really shortest path, often using maps made not in the Mercator, but in the so-called "central" projection: on these maps, the arcs of great circles are depicted as straight lines.

    Why, then, did former navigators use such deceptive maps and choose unfavorable paths? It is a mistake to think that in the old days they did not know about the now indicated feature of sea charts. The matter is explained, of course, not by this, but by the fact that charts drawn according to the Mercator method, along with inconveniences, have very valuable benefits for sailors. Such a map, firstly, depicts separate small parts of the earth's surface without distortion, preserving the corners of the contour. This is not contradicted by the fact that with distance from the equator, all contours are noticeably stretched. At high latitudes, the stretch is so significant that a sea chart inspires a person who is unfamiliar with its features with a completely false idea of ​​​​the true size of the continents: Greenland seems to be the same size as Africa, Alaska is larger than Australia, although Greenland is 15 times smaller than Africa, and Alaska together with Greenland half the size of Australia. But a sailor who is well acquainted with these features of the chart cannot be misled by them. He puts up with them, especially since, within small areas, a sea chart gives an exact likeness of nature (Fig. 5).

    On the other hand, the sea chart greatly facilitates the solution of the tasks of navigational practice. This is the only kind of charts on which the path of a ship on a constant course is depicted as a straight line. To follow a "constant course" means to keep invariably one direction, one definite "rhumb", in other words, to go in such a way as to cross all the meridians at an equal angle. But this path ("loxodrome") can be depicted as a straight line only on a map on which all meridians are straight lines parallel to each other. And since on the globe the circles of latitude intersect with the meridians at right angles, then on such a map the circles of latitude should be straight lines perpendicular to the lines of the meridians. In short, we arrive precisely at the coordinate grid that constitutes a characteristic feature of the sea chart.




    Rice. 5. Nautical or Mercator map of the globe. On such maps, the dimensions of contours far from the equator are greatly exaggerated. Which, for example, is bigger: Greenland or Australia? (answer in text)


    Sailors' predilection for Mercator maps is now understandable. Wanting to determine the course to be followed when going to the designated port, the navigator applies a ruler to the end points of the path and measures the angle it makes with the meridians. Keeping in the open sea all the time in this direction, the navigator will accurately bring the ship to the target. You see that the “loxodrome” is, although not the shortest and not the most economical, but in a certain respect a very convenient way for a sailor. To reach, for example, from the Cape of Good Hope to the southern tip of Australia (see Fig. 1), one must always keep the same course S 87 °, 50 ". Meanwhile, in order to bring the ship to the same final point in the shortest way (along the" ”), it is necessary, as can be seen from the figure, to continuously change the course of the vessel: start from the course S 42 °, 50 "and end with the course N 53 °. 50" (in this case, the shortest path is not even feasible - it rests on the ice wall of Antarctica ).

    Both paths - along the "loxodrome" and along the "orthodromy" - coincide only when the path along the great circle is depicted on the sea chart as a straight line: when moving along the equator or along the meridian. In all other cases, these paths are different.

    (Descriptive geometry)
  • CD (CXDX, C2D2) displayed as a dot C5 = D5 A5B5 equals...
    (Descriptive geometry)
  • Determining the distance between two parallel planes
    Determining the distance between two parallel planes in general position 01| X it is convenient to reduce it to the problem of determining the distance between the same two planes, transformed into the position of the projecting ones. In this case, the distance between the planes is defined as the perpendicular between the lines, ...
    (Descriptive geometry)
  • Determining the distance between two intersecting lines
    If you want to determine the shortest distance between two intersecting lines, you have to change the systems of projection planes twice. When solving this problem, the direct CD (CXDX, C2D2) displayed as a dot C5 = D5(Fig. 198). Distance from this point to the projection A5B5 equals...
    (Descriptive geometry)
  • Angle between two intersecting straight lines
    This is the angle between two intersecting lines that are parallel to the data. Thus, this task is similar to the previous one. To solve it, you need to take an arbitrary point and draw two straight lines through it, parallel to the given skew straight lines, and using projection transformations, determine the desired angle....
    (Fundamentals of descriptive geometry. A short course and a collection of problems.)
  • Determining the distance between two parallel lines
    The problem is solved by the method of double replacement of projection planes. At the final stage, one of the projection planes must be perpendicular to one of the intersecting lines. Then the shortest distance between them is determined by the value of the segment perpendicular to the other skew line (Fig. 199)....
    (Descriptive geometry)
  • The path along the dotted line in the picture is shorter than the path along the solid line. And now a little more in detail on the example of sea routes:

    If you sail in a constant course, then the trajectory of the ship on the earth's surface will be a curve, called in mathematics logarithmicspiral.

    In navigation, this complex double curvature line is called loxodromia, which in Greek means "oblique run".

    However, the shortest distance between two points on the globe is measured along the arc of a great circle.

    The arc of a great circle is obtained as a trace from the intersection of the earth's surface with a plane passing through the center of the Earth, taken as a ball.

    In navigation, the great circle arc is called great circle, which means "straight run". The second feature of the great circle is that it crosses the meridians at different angles (Fig. 29).

    The difference in distances between two points on the earth's surface along the loxodrome and orthodrome is of practical importance only for large ocean crossings.

    Under normal conditions, this difference is neglected and navigation is carried out on a constant course, i.e. by loxodrome.

    To derive the equation, we take loxodromies (Fig. 30, but) two dots BUT And IN, the distance between them is simply small. Drawing meridians and a parallel through them, we get an elementary right-angled spherical triangle ABC. In this triangle, the angle formed by the intersection of the meridian and the parallel is right, and the angle PnAB equal to the course of the ship K. Katet AC represents a meridian arc segment and can be expressed

    where R - radius of the Earth taken as a sphere;

    Δφ - elementary increment of latitude (difference of latitudes).

    leg SW represents an arc segment parallel

    where r - radius of the parallel;

    Δλ - elementary difference of longitudes.

    From triangle OO 1 C can be found that

    Then in the final form the leg SW can be expressed like this:

    Assuming an elementary spherical triangle ABC for flat, write

    After reduction R and replacing elementary small increments of coordinates by infinitesimal ones, we have

    We integrate the resulting expression in the range from φ 1, λ 1 to φ 2, λ 2 considering the value of tgK as a constant value:

    On the right side we have a tabular integral. After substituting its value, we obtain the loxodrome equation on the ball

    Analysis of this equation allows us to draw the following conclusions:

    At courses of 0 and 180 °, the loxodrome turns into an arc of a great circle - a meridian;

    At courses of 90 and 270 °, the loxodrome coincides with the parallel;

    The loxodrome crosses each parallel only once, and each meridian an uncountable number of times. those. spirally approaching the pole, it does not reach it.

    Navigation in a constant course, i.e., along the loxodrome, although it is not the shortest distance between two points on Earth, represents considerable convenience for the navigator.

    The requirements for a marine navigation chart can be formulated based on the advantage of navigation along the loxodrome and the results of the analysis of its equation as follows.

    1. Loxodrome, crossing the meridians at a constant angle, should be depicted as a straight line.

    2. The cartographic projection used for the construction of maps must be conformal so that the courses, bearings and angles on it correspond to their value on the ground.

    3. Meridians and parallels, like course lines 0, 90, 180° and 270°, must be mutually perpendicular straight lines.

    The shortest distance between two given points on the surface of the Earth, taken as a sphere, is the smaller of the arcs of a great circle passing through these points. Except in the case of a ship following a meridian or the equator, the great circle crosses the meridians at different angles. Therefore, a ship following such a curve must change its course all the time. It is practically more convenient to follow a course that makes a constant angle with the meridians and is depicted on the map in the Mercator projection by a straight line - loxodrome. However, at large distances, the difference in the length of the orthodrome and loxodrome reaches a significant value. Therefore, in such cases, the orthodrome is calculated and intermediate points are marked on it, between which they swim along the loxodrome.

    A cartographic projection that meets the above requirements was proposed by the Dutch cartographer Gerard Cramer (Mercator) in 1569. In honor of its creator, the projection was named Mercator.

    And who wants to learn even more interesting information find out more The original article is on the website InfoGlaz.rf Link to the article from which this copy is made -

    DISTANCE, distances, cf. 1. A space separating two points, a gap between something. The shortest distance between two points in a straight line. Lives from us at a distance of two kilometers. “The commandant let them in at the closest distance ... Explanatory Dictionary of Ushakov

    distance- noun, s., use. often Morphology: (no) what? distance for what? distance, (see) what? distance than? distance, what? about distance; pl. what? distance, (no) what? distances, why? distances, (see) what? distance than? distances... Dictionary of Dmitriev

    distance- I; cf. The space separating two points, two objects, etc., the gap between someone, than l. The shortest river between two points. R. from home to school. Retreat to a nearby river. At a distance of a meter, arms outstretched. Know something, feel something. on the… … encyclopedic Dictionary

    distance- I; cf. see also distance a) The space separating two points, two objects, etc., the gap between someone, than l. The shortest distance between two points. Distance from home to school. Retreat to a close distance / nie ... Dictionary of many expressions

    GEOMETRY- a branch of mathematics that studies the properties of various shapes (points, lines, angles, two-dimensional and three-dimensional objects), their size and relative position. For the convenience of teaching, geometry is divided into planimetry and solid geometry. IN… … Collier Encyclopedia

    Navigation*

    Navigation- department of navigation (see), concluding a presentation of ways to determine the place of a ship at sea, using a compass and a log (see). To determine the place of the ship at sea means to put on the map the point at which the ship is currently located. ... ... Encyclopedic Dictionary F.A. Brockhaus and I.A. Efron

    COGEN- (Cohen) Hermann (1842 1918) German philosopher, founder and most prominent representative of the Marburg school of neo-Kantianism. Major works: 'Kant's Theory of Experience' (1885), 'Kant's Justification of Ethics' (1877), 'Kant's Justification of Aesthetics' (1889), 'Logic… ...

    Kant Immanuel- Kant's life and writings Immanuel Kant was born in Konigsberg (now Kaliningrad) in East Prussia in 1724. His father was a saddler, and his mother was a housewife, six of their children did not live to adulthood. Kant always remembered his parents with ... ... Western philosophy from its origins to the present day

    KANT'S CRITICAL PHILOSOPHY: THE DOCTRINE OF ABILITIES- (La philosophie critique de Kant: Doctrines des facultes, 1963) by Deleuze. Describing the transcendental method in the introduction, Deleuze notes that Kant understands philosophy as the science of the relation of all knowledge to essential goals... ... History of Philosophy: Encyclopedia

    farm principle- the basic principle of geometric optics (See Geometric optics). The simplest form of F. p. is the assertion that a ray of light always propagates in space between two points along the path along which the time of its passage is less than ... Great Soviet Encyclopedia

    Dijkstra's algorithm is a graph algorithm invented by the Dutch scientist Edsger Dijkstra in 1959. Finds the shortest paths from one of the vertices of the graph to all the others. Algorithm works only for graphs without edges of negative weight.

    Consider the execution of the algorithm on the example of the graph shown in the figure.

    Let it be required to find the shortest distances from the 1st vertex to all the others.

    The circles indicate the vertices, the lines indicate the paths between them (the edges of the graph). The numbers of the vertices are indicated in the circles, their "price" - the length of the path - is indicated above the edges. Next to each vertex, a red label is marked - the length of the shortest path to this vertex from vertex 1.

    First step. Consider a step in Dijkstra's algorithm for our example. Vertex 1 has the minimum label. Vertices 2, 3, and 6 are its neighbors.

    The first neighbor of vertex 1 in turn is vertex 2, because the length of the path to it is minimal. The length of the path to it through vertex 1 is equal to the sum of the value of the label of vertex 1 and the length of the edge going from 1st to 2nd, that is, 0 + 7 = 7. This is less than the current label of vertex 2, infinity, so the new label of 2nd vertex is 7.

    We perform a similar operation with two other neighbors of the 1st vertex - the 3rd and 6th.

    All neighbors of node 1 are checked. The current minimum distance to peak 1 is considered final and is not subject to revision (the fact that this is indeed the case was first proved by E. Dijkstra). Cross it out of the graph to mark that this vertex has been visited.

    Second step. The algorithm step is repeated. Again we find the “nearest” of the unvisited vertices. This is vertex 2 labeled 7.

    Again we try to reduce the labels of the neighbors of the selected vertex, trying to pass through them through the 2nd vertex. Vertex 2's neighbors are vertices 1, 3, and 4.

    The first (in order) neighbor of vertex 2 is vertex 1. But it has already been visited, so we do nothing with the 1st vertex.

    The next neighbor of vertex 2 is vertex 3, since it has the minimum label of the vertices marked as unvisited. If you go to it through 2, then the length of such a path will be equal to 17 (7 + 10 = 17). But the current label of the third vertex is 9, which is less than 17, so the label doesn't change.

    Another neighbor of vertex 2 is vertex 4. If you go to it through the 2nd, then the length of such a path will be equal to the sum of the shortest distance to the 2nd vertex and the distance between vertices 2 and 4, that is, 22 (7 + 15 = 22) . Since 22<, устанавливаем метку вершины 4 равной 22.

    All neighbors of vertex 2 have been viewed, we freeze the distance to it and mark it as visited.

    Third step. We repeat the step of the algorithm by selecting vertex 3. After its “processing”, we get the following results:

    Next steps. We repeat the step of the algorithm for the remaining vertices. These will be vertices 6, 4 and 5, respectively.

    Completion of the algorithm execution. The algorithm terminates when no more vertices can be processed. In this example, all vertices are crossed out, but it is a mistake to assume that this will be the case in any example - some vertices may remain uncrossed out if they cannot be reached, i.e. if the graph is disconnected. The result of the algorithm is visible in the last figure: the shortest path from vertex 1 to 2 is 7, to 3 is 9, to 4 is 20, to 5 is 20, to 6 is 11.

    Implementation of the algorithm in various programming languages:

    C++

    #include "stdafx.h" #include using namespace std; const int V=6; // Dijkstra's algorithm void Dijkstra(int GR[V][V], int st) ( int distance[V], count, index, i, u, m=st+1; bool visited[V]; for (i= 0 i "< "<> "; cin>>start; Dijkstra(GR, start-1); system("pause>>void"); )

    Pascal

    program DijkstraAlgorithm; usescrt; constV=6; inf=100000; type vector=array of integer; var start: integer; const GR: array of 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)); (Dijkstra's algorithm) procedure Dijkstra(GR: array of integer; st: integer); var count, index, i, u, m, min: integer; distance: vector; visited: array of boolean; beginm:=st; for i:=1 to V do begin distance[i]:=inf; visited[i]:=false; end; distance:=0; for count:=1 to V-1 do begin min:=inf; for i:=1 to V do if (not visited[i]) and (distance[i]<=min) then begin min:=distance[i]; index:=i; end; u:=index; visited[u]:=true; for i:=1 to V do if (not visited[i]) and (GR<>0) and (distance[u]<>inf) and (distance[u]+GR inf then writeln(m," > ", i," = ", distance[i]) else writeln(m," > ", i," = ", "route unavailable"); end; (main program block) begin clrscr; write("Starting node >> "); read(start); Dijkstra(GR, start); end.

    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; //number of vertices in digraph private int m; //number of arcs in digraph private ArrayList adj; //adjacency list private ArrayList weight; //weight of edge in digraph private boolean used; //array for storing information about passed and not passed peaks private int dist; //array to store the distance from the starting vertex //an array of ancestors needed to restore the shortest path from the starting vertex private int pred; int start; //starting vertex, from which the distance to all others is searched private BufferedReader cin; private PrintWriter cout; private StringTokenizer tokenizer; //procedure for starting Dijkstra's algorithm from the starting vertex private void dejkstra(int s) ( dist[s] = 0; //the shortest distance to the starting vertex is 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(); ) //initializing the list that stores the weights of the edges weight = new ArrayList[n]; for (int i = 0; i< n; ++i) { weight[i] = new ArrayList(); ) //read the graph given by the list of edges for (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(); } }

    Another option:

    Import 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(); ) ) class Graph ( private final Map graph; // mapping of vertex names to Vertex objects, built from a set of Edges /** One edge of the graph (only used by Graph constructor) */ 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; ) ) /** One vertex of the graph, complete with mappings to neighboring vertices */ public static class Vertex implements Comparable ( public final String name; public int dist = Integer.MAX_VALUE; // MAX_VALUE assumed to be infinity public Vertex previous = null; public final Map neighbors = new HashMap<>(); public Vertex(String name) ( this.name = name; ) private void printPath() ( if (this == this.previous) ( System.out.printf("%s", this.name); ) else if ( this.previous == null) ( System.out.printf("%s(unreached)", this.name); ) else ( this.previous.printPath(); System.out.printf(" -> %s( %d)", this.name, this.dist); ) ) public int compareTo(Vertex other) ( return Integer.compare(dist, other.dist); ) ) /** Builds a graph from a set of edges * / public Graph(Edge edges) ( graph = new HashMap<>(edges.length); //one pass to find all vertices for (Edge e: edges) ( 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)); ) //another pass to set neighboring vertices for (Edge e: edges) ( graph.get(e.v1). neighbours.put(graph.get(e.v2), e.dist); //graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // also do this for an undirected graph ) ) /** Runs dijkstra using a specified source vertex */ public void dijkstra(String startName) ( if (!graph.containsKey(startName)) ( System.err.printf("Graph doesn't contain start vertex \"%s\"\n", startName); return; ) final Vertex source = graph.get(startName); NavigableSet q = new TreeSet<>(); // set-up vertices for (Vertex v: graph.values()) ( v.previous = v == source ? source: null; v.dist = v == source ? 0: Integer.MAX_VALUE; q.add( v); ) dijkstra(q); ) /** Implementation of dijkstra"s algorithm using a binary heap. */ private void dijkstra(final NavigableSet q) ( Vertex u, v; while (!q.isEmpty()) ( u = q.pollFirst(); // vertex with shortest distance (first iteration will return source) if (u.dist == Integer.MAX_VALUE) break; // we can ignore u (and any other remaining vertices) since they are unreachable //look at distances to each neighbor for (Map.Entry a: u.neighbours.entrySet()) ( v = a.getKey(); //the neighbor in this iteration 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; /* target of this edge */ edge_t *sibling;/* for singly linked list */ int len; /* edge cost */ ); struct node_t ( edge_t *edge; /* singly linked list of edges */ node_t *via; /* where previous node is in shortest path */ double dist; /* distance from originating node */ char name; /* the, er , name */ int heap_idx; /* link to heap position for updating distance */ ); /* --- edge management --- */ #ifdef BIG_EXAMPLE # define BLOCK_SIZE (1024 * 32 - 1) #else # define BLOCK_SIZE 15 #endif edge_t *edge_root = 0, *e_next = 0; /* Don't mind the memory management stuff, they are besides the point. Pretend e_next = malloc(sizeof(edge_t)) */ void add_edge(node_t *a, node_t *b, double d) ( if (e_next == edge_root ) ( edge_root = malloc(sizeof(edge_t) * (BLOCK_SIZE + 1)); edge_root.sibling = e_next; e_next = edge_root + BLOCK_SIZE; ) --e_next; e_next->nd = b; e_next->len = d; e_next ->sibling = a->edge; a->edge = e_next; ) void free_edges() ( for (; edge_root; edge_root = e_next) ( e_next = edge_root.sibling; free(edge_root); ) ) /* --- priority queue stuff --- */ heap_t *heap; int heap_len; void set_dist(node_t *nd, node_t *via, double d) ( int i, j; /* already knew better path */ if (nd->via && d >= nd->dist) return; /* find existing heap entry, or create a new one */ 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; heap[i] = nd; nd->heap_idx = i; ) node_t * pop_queue() ( node_t *nd, *tmp; int i, j; if (!heap_len) return 0; /* remove leading element, pull tail element there and downheap */ nd = heap; tmp = heap; for (i = 1; i< heap_len && (j = i * 2) <= heap_len; i = j) { if (j < heap_len && heap[j]->dist > heap->dist) j++; if (heap[j]->dist >= tmp->dist) break; (heap[i] = heap[j])->heap_idx = i; ) heap[i] = tmp; tmp->heap_idx = i; return nd; ) /* --- Dijkstra stuff; unreachable nodes will never make into the 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; # define N_NODES ("f" - " a" + 1) node_t *nodes = calloc(sizeof(node_t), N_NODES); for (i = 0; i< N_NODES; i++) sprintf(nodes[i].name, "%c", "a" + i); # define E(a, b, c) add_edge(nodes + (a - "a"), nodes + (b - "a"), c) E("a", "b", 7); E("a", "c", 9); E("a", "f", 14); E("b", "c", 10);E("b", "d", 15);E("c", "d", 11); E("c", "f", 2); E("d", "e", 6); E("e", "f", 9); # undef E #else /* BIG_EXAMPLE */ int i, j, c; # define N_NODES 4000 node_t *nodes = calloc(sizeof(node_t), N_NODES); for (i = 0; i < N_NODES; i++) sprintf(nodes[i].name, "%d", i + 1); /* given any pair of nodes, there"s about 50% chance they are not connected; if connected, the cost is randomly chosen between 0 and 49 (inclusive! see output for consequences) */ for (i = 0; i < N_NODES; i++) { for (j = 0; j < N_NODES; j++) { /* majority of runtime is actually spent here */ if (i == j) continue; c = rand() % 100; if (c < 50) continue; add_edge(nodes + i, nodes + j, c - 50); } } #endif heap = calloc(sizeof(heap_t), N_NODES + 1); heap_len = 0; calc_all(nodes); for (i = 0; i < N_NODES; i++) { show_path(nodes + i); putchar("\n"); } #if 0 /* real programmers don"t free memories (they use Fortran) */ free_edges(); free(heap); free(nodes); #endif return 0; }

    PHP

    $edge, "cost" => $edge); $neighbours[$edge] = array("end" => $edge, "cost" => $edge); ) $vertices = array_unique($vertices); foreach ($vertices as $vertex) ( $dist[$vertex] = INF; $previous[$vertex] = NULL; ) $dist[$source] = 0; $Q = $vertices; while (count($Q) > 0) ( // TODO - Find faster way to get minimum $min = INF; foreach ($Q as $vertex)( if ($dist[$vertex]< $min) { $min = $dist[$vertex]; $u = $vertex; } } $Q = array_diff($Q, array($u)); if ($dist[$u] == INF or $u == $target) { break; } if (isset($neighbours[$u])) { foreach ($neighbours[$u] as $arr) { $alt = $dist[$u] + $arr["cost"]; if ($alt < $dist[$arr["end"]]) { $dist[$arr["end"]] = $alt; $previous[$arr["end"]] = $u; } } } } $path = array(); $u = $target; while (isset($previous[$u])) { array_unshift($path, $u); $u = $previous[$u]; } array_unshift($path, $u); return $path; } $graph_array = array(array("a", "b", 7), array("a", "c", 9), array("a", "f", 14), array("b", "c", 10), array("b", "d", 15), array("c", "d", 11), array("c", "f", 2), array("d", "e", 6), array("e", "f", 9)); $path = dijkstra($graph_array, "a", "e"); echo "path is: ".implode(", ", $path)."\n";


    Python

    from collections import namedtuple, queue from pprint import pprint as pp inf = float("inf") Edge = namedtuple("Edge", "start, end, cost") class Graph(): def __init__(self, edges): self .edges = edges2 = self.vertices = set(sum(( for e in edges2), )) def dijkstra(self, source, dest): assert source in self.vertices dist = (vertex: inf for vertex in self.vertices ) previous = (vertex: None for vertex in self.vertices) dist = 0 q = self.vertices.copy() neighbors = (vertex: set() for vertex in self.vertices) for start, end, cost in self. edges: neighbors.add((end, cost)) #pp(neighbours) while q: u = min(q, key=lambda vertex: dist) q.remove(u) if dist[u] == inf or u = = dest: break for v, cost in neighbors[u]: alt = dist[u] + cost if 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"]

    Similar articles