zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    函数式注释、文件头部注释
    slice()与splice()的区别
    纯前端跨域下载pdf链接文件解决方案
    SqlServer数据库设计一个字段的值是由其他字段运算结果所得
    关键字的几种用法
    DataContract和DataMember的作用
    windows10如何打开vhd文件
    c#中partial 作用
    c#中(&&,||)与(&,|)的区别和应用
    c#MD5加密
  • 原文地址:https://www.cnblogs.com/johnnyzhao/p/13139987.html
Copyright © 2011-2022 走看看