package _Algorithm.BellmanFord
class BellmanFord {
//create graph
val ab = Edge("A", "B", -1)
val ac = Edge("A", "C", 4)
val bc = Edge("B", "C", 3)
val be = Edge("B", "E", 2)
val ed = Edge("E", "D", -3)
val dc = Edge("D", "C", 5)
val bd = Edge("B", "D", 2)
val db = Edge("D", "B", 1)
val edges = arrayOf(ab, ac, bc, be, bd, ed, dc, db)
//store cost of each node
val costMap = HashMap<String, Int>()
//store parent of each node
val parentMap = HashMap<String, String>()
init {
//init node
costMap.put("A", 0)
costMap.put("B", Int.MAX_VALUE)
costMap.put("C", Int.MAX_VALUE)
costMap.put("D", Int.MAX_VALUE)
costMap.put("E", Int.MAX_VALUE)
}
fun handler() {
//relax for every edge
for (i in 1 until costMap.size) {
var hasChange = false
for (edge in edges) {
val startPointCost = if (costMap.get(edge.startPoint) == null) 0 else costMap.get(edge.startPoint) ?: 0
val endPointCost = if (costMap.get(edge.endPoint) == null) 0 else costMap.get(edge.endPoint) ?: 0
//if cur edge's endPointCost large than (startPointCost + edge.weight),
//that's mean there is shorter path exist
if (endPointCost > (startPointCost + edge.weight)) {
costMap.put(edge.endPoint, startPointCost + edge.weight)
parentMap.put(edge.endPoint, edge.startPoint)
hasChange = true
}
}
//经常还没达到最大遍历次数便已经求出解了,此时可以优化为提前退出循环
if (!hasChange) {
break
}
}
//check if exist ring
var hasRing = false
for (edge in edges) {
val startPointCost = if (costMap.get(edge.startPoint) == null) 0 else costMap.get(edge.startPoint) ?: 0
val endPointCost = if (costMap.get(edge.endPoint) == null) 0 else costMap.get(edge.endPoint) ?: 0
if (endPointCost > (startPointCost + edge.weight)) {
hasRing = true
break
}
}
//print all
if (!hasRing) {
for (item in costMap) {
print("reach target node:${item.key}, minimum cost is: ${item.value}")
if (parentMap.contains(item.key)) {
val pathList = ArrayList<String>()
var parentKey = parentMap.get(item.key)
while (parentKey != null) {
pathList.add(0, parentKey)
parentKey = parentMap.get(parentKey)
}
pathList.add(item.key)
print(", path list:")
print(pathList.toString().replace(",","->").replace(" ",""))
}
println()
}
}
}
}
/**
* startPoint,起始点
* endPoint,终点
* weight,权重
* */
data class Edge(var startPoint: String, var endPoint: String, var weight: Int)