Bellman-Ford Code

复制代码
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)
复制代码

 

posted @   johnny_zhao  阅读(181)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示