From f0e18897ccfc26a69f88db0529cdbf4049ccfcda Mon Sep 17 00:00:00 2001 From: Werner de Groot Date: Fri, 22 Nov 2019 15:37:50 +0100 Subject: [PATCH] Dijkstra. --- backend/src/nl/codestar/interchange/Graph.kt | 90 ++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 backend/src/nl/codestar/interchange/Graph.kt diff --git a/backend/src/nl/codestar/interchange/Graph.kt b/backend/src/nl/codestar/interchange/Graph.kt new file mode 100644 index 0000000..0135683 --- /dev/null +++ b/backend/src/nl/codestar/interchange/Graph.kt @@ -0,0 +1,90 @@ +package nl.codestar.interchange + +import java.lang.RuntimeException +import java.util.* +import kotlin.collections.HashMap + +data class Node(val name: String) + +data class Edge( + val a: Node, + val b: Node, + val w: Double +) { + fun swap(): Edge { + return Edge(b, a, w) + } +} + +val rotterdam = Node("Rotterdam") +val amsterdam = Node("Amsterdam") +val groningen = Node("Groningen") +val utrecht = Node("Utrecht") +val nijmegen = Node("Nijmegen") + +val nodes = listOf(rotterdam, amsterdam, groningen, utrecht, nijmegen) + +val unidirecitonalEdges = listOf( + Edge(rotterdam, amsterdam, 1.0), + Edge(amsterdam, utrecht, 1.0), + Edge(utrecht, rotterdam, 3.0), + Edge(utrecht, groningen, 2.0), + Edge(utrecht, nijmegen, 2.0) +) + +val edges = unidirecitonalEdges.union(unidirecitonalEdges.map { it.swap() }) + +fun getSmallestDistance(distances: Map, alreadyVisited: Set): Pair? { + return distances.entries.minBy { p -> + if (alreadyVisited.contains(p.key)) { + Double.MAX_VALUE + } else { + p.value + } + }?.toPair() +} + +fun getNeighbours(node: Node): List> { + return edges.filter{e -> e.a == node}.map{e -> Pair(e.b, e.w) } +} + +fun doIt(): List? { + + val from = rotterdam + val to = groningen + val distances = HashMap() + val routes = HashMap>() + nodes.forEach { node -> + if (node.name == from.name) { + distances[node] = 0.0 + routes[node] = listOf(node) + } else { + distances[node] = Double.MAX_VALUE + } + } + + val q = nodes.toMutableList() + val alreadyVisited = HashSet() + while (q.isNotEmpty()) { + val minDistance = getSmallestDistance(distances, alreadyVisited) ?: throw RuntimeException() + val previousRoute = routes.getOrDefault(minDistance.first, emptyList()) + q.remove(minDistance.first) + alreadyVisited.add(minDistance.first) + + val neighbours = getNeighbours(minDistance.first) + neighbours.forEach { neighbour -> + val newDistance = minDistance.second + neighbour.second // neighbour.weight + if (newDistance < distances.getOrDefault(neighbour.first, Double.MAX_VALUE)) { + distances[neighbour.first] = newDistance + routes[neighbour.first] = previousRoute + neighbour.first + } + } + } + + return routes[to] +} + +fun main(args: Array) { + System.out.println(doIt()?.toString()) +} +