Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6af84eb

Browse files
Dijkstra algorithm
1 parent f1d3085 commit 6af84eb

File tree

6 files changed

+204
-2
lines changed

6 files changed

+204
-2
lines changed

‎src/main/kotlin/pl/dmichalski/algorithms/data_structures/_11_graph_traversal/Runner.kt‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ object Runner {
3232
val breadthFirstSearch = undirectedGraph.breadthFirstSearch(VERTEX_A)
3333
println("Graph elements: $breadthFirstSearch")
3434
printUndirectedGraph(undirectedGraph)
35-
36-
3735
}
3836

3937
/**
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package pl.dmichalski.algorithms.data_structures._12_dijkstra_algorithm
2+
3+
class Connection(private val vertex: String, private val weight: Int) {
4+
5+
fun getVertex(): String {
6+
return vertex
7+
}
8+
9+
fun getWeight(): Int {
10+
return weight
11+
}
12+
13+
override fun toString(): String {
14+
return "Connection(vertex='$vertex', weight=$weight)"
15+
}
16+
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package pl.dmichalski.algorithms.data_structures._12_dijkstra_algorithm
2+
3+
data class Node(private val vertex: String, private val connections: MutableList<Connection>) {
4+
5+
fun getVertex(): String {
6+
return vertex
7+
}
8+
9+
fun getConnections(): MutableList<Connection> {
10+
return connections
11+
}
12+
13+
override fun toString(): String {
14+
return "Node(vertex='$vertex', connections=$connections)"
15+
}
16+
17+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package pl.dmichalski.algorithms.data_structures._12_dijkstra_algorithm
2+
3+
class QueueNode(private val value: String, private val priority: Int) {
4+
5+
fun getValue(): String {
6+
return value
7+
}
8+
9+
fun getPriority(): Int {
10+
return priority
11+
}
12+
13+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package pl.dmichalski.algorithms.data_structures._12_dijkstra_algorithm
2+
3+
object Runner {
4+
5+
private const val VERTEX_A = "A"
6+
private const val VERTEX_B = "B"
7+
private const val VERTEX_C = "C"
8+
private const val VERTEX_D = "D"
9+
private const val VERTEX_E = "E"
10+
private const val VERTEX_F = "F"
11+
12+
@JvmStatic
13+
fun main(args: Array<String>) {
14+
println("------------------ Initial weighted graph ------------------ ")
15+
var weightedGraph = getWeightedGraph()
16+
printWeightedGraph(weightedGraph)
17+
18+
println("------------------ Finding the shortest path using Dijkstra algorithm ------------------ ")
19+
weightedGraph = getWeightedGraph()
20+
val shortestPath = weightedGraph.dijkstra(VERTEX_A, VERTEX_E)
21+
println("Shortest path between $VERTEX_A and $VERTEX_E: $shortestPath")
22+
}
23+
24+
/**
25+
* It returns weighted graph like this:
26+
* <pre>
27+
* 4
28+
* A --------- B
29+
* 2 / |
30+
* / 2 |
31+
* C ------- D | 3
32+
* \ / \ |
33+
* 4 \ 1 / \ 3 |
34+
* \ / \ |
35+
* F --------- E
36+
* 1
37+
*
38+
* </pre>
39+
*/
40+
private fun getWeightedGraph(): WeightedGraph {
41+
val weightedGraph = WeightedGraph()
42+
43+
weightedGraph.addVertex(VERTEX_A)
44+
weightedGraph.addVertex(VERTEX_B)
45+
weightedGraph.addVertex(VERTEX_C)
46+
weightedGraph.addVertex(VERTEX_D)
47+
weightedGraph.addVertex(VERTEX_E)
48+
weightedGraph.addVertex(VERTEX_F)
49+
50+
weightedGraph.addEdge(VERTEX_A, VERTEX_B, 4)
51+
weightedGraph.addEdge(VERTEX_A, VERTEX_C, 2)
52+
weightedGraph.addEdge(VERTEX_B, VERTEX_E, 3)
53+
weightedGraph.addEdge(VERTEX_C, VERTEX_D, 2)
54+
weightedGraph.addEdge(VERTEX_C, VERTEX_F, 4)
55+
weightedGraph.addEdge(VERTEX_D, VERTEX_E, 3)
56+
weightedGraph.addEdge(VERTEX_D, VERTEX_F, 1)
57+
weightedGraph.addEdge(VERTEX_E, VERTEX_F, 1)
58+
59+
return weightedGraph
60+
}
61+
62+
private fun printWeightedGraph(weightedGraph: WeightedGraph) {
63+
println(weightedGraph)
64+
}
65+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package pl.dmichalski.algorithms.data_structures._12_dijkstra_algorithm
2+
3+
import java.util.*
4+
import kotlin.collections.ArrayList
5+
import kotlin.collections.HashMap
6+
7+
class WeightedGraph {
8+
9+
private val adjacencyList: MutableList<Node> = ArrayList()
10+
11+
fun addVertex(vertex: String) {
12+
val node = findNode(vertex)
13+
14+
if (node == null) {
15+
val newNode = Node(vertex, mutableListOf())
16+
this.adjacencyList.add(newNode)
17+
}
18+
}
19+
20+
fun addEdge(vertex1: String, vertex2: String, weight: Int) {
21+
val node1 = findNode(vertex1)
22+
val node2 = findNode(vertex2)
23+
24+
val connection1 = Connection(vertex1, weight)
25+
val connection2 = Connection(vertex2, weight)
26+
27+
node1!!.getConnections().add(connection2)
28+
node2!!.getConnections().add(connection1)
29+
}
30+
31+
fun dijkstra(start: String, finish: String): List<String> {
32+
val compareByWeight: Comparator<QueueNode> = compareBy { it.getPriority() }
33+
val nodesQueue = PriorityQueue(compareByWeight)
34+
val path: MutableList<String> = ArrayList()
35+
36+
val distances = HashMap<String, Int>(adjacencyList.size)
37+
val previous = HashMap<String, String?>(adjacencyList.size)
38+
var smallest: String
39+
40+
for (vertexNode in adjacencyList) {
41+
val vertex = vertexNode.getVertex()
42+
if (vertex == start) {
43+
distances[vertex] = 0
44+
val queueNode = QueueNode(vertex, 0)
45+
nodesQueue.add(queueNode)
46+
} else {
47+
distances[vertex] = Int.MAX_VALUE
48+
val queueNode = QueueNode(vertex, Int.MAX_VALUE)
49+
nodesQueue.add(queueNode)
50+
}
51+
previous[vertex] = null
52+
}
53+
54+
while (nodesQueue.size > 0) {
55+
smallest = nodesQueue.poll().getValue()
56+
if (smallest === finish) {
57+
while (previous[smallest] != null) {
58+
path.add(smallest)
59+
smallest = previous[smallest]!!
60+
}
61+
break
62+
}
63+
if (distances[smallest] != Int.MAX_VALUE) {
64+
val node = adjacencyList.first { vertexNode -> vertexNode.getVertex() === smallest }
65+
for (neighbor in node.getConnections()) {
66+
val candidate = distances[smallest]?.plus(neighbor.getWeight())
67+
val nextNeighbor = neighbor.getVertex()
68+
if (candidate!! < distances[nextNeighbor]!!) {
69+
distances[nextNeighbor] = candidate
70+
previous[nextNeighbor] = smallest
71+
val queueNode = QueueNode(nextNeighbor, candidate)
72+
nodesQueue.add(queueNode)
73+
}
74+
}
75+
}
76+
}
77+
78+
return path
79+
}
80+
81+
override fun toString(): String {
82+
return "UndirectedGraph(adjacencyList='$adjacencyList')\n"
83+
}
84+
85+
private fun findNode(vertex: String): Node? {
86+
return adjacencyList.stream()
87+
.filter { node -> node.getVertex() == vertex }
88+
.findFirst()
89+
.orElse(null)
90+
}
91+
92+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /