你已經是個成熟的程式設計師了,該學會用程式幫自己省錢了————狄克斯特拉演算法

chengxiansheng發表於2020-06-27

  說起回家,路途漫漫,行李滿滿,尤其我等村裡交通不發達的地方,可能連直達的票都沒有,雖說條條大陸通羅馬,但畢竟還是想找個換乘最少的路線,畢竟誰不想回家更輕鬆點呢(*^_^*),下面就是我回家的所有路線。

 

  思路很簡單,先找起點看是否能到,不能到的話,看起點能到的點的下一步是否能到

 

  話不多說,擼程式碼:

public static void main(String[] args) {
    HashMap<String,List<String>> data = new HashMap<String, List<String>>();
    List<String> list1 = new ArrayList<String>();
    data.put("起點",list1);
    list1.add("A");
    list1.add("B");
    List<String> list2 = new ArrayList<String>();
    data.put("A",list2);
    list2.add("終點");
    List<String> list3 = new ArrayList<String>();
    data.put("B",list3);
    list3.add("A");
    list3.add("終點");
    query(data,"終點","起點");
}

public static void query(Map<String,List<String>> data, String queryValue, String start){
    if(data==null || queryValue ==null){
        return;
    }
    Queue<String> queue = new LinkedList<String>();
    Map quaryLog  = new HashMap();
    Map<String,List<String>> routes = new HashMap<String, List<String>>();
    queue.offer(start);
    quaryLog.put(start,"");
    String parent = null;
    while (!queue.isEmpty()){
        parent = queue.poll();
        List<String> values = data.get(parent);
        for(String value:values){
            List<String> r = new ArrayList<String>();
            if(routes.containsKey(parent)){
                r.addAll(routes.get(parent));
            }
            r.add(parent);
            routes.put(value,r);
            if(queryValue.equals(value)){
                routes.get(value).add(value);
                System.out.println(routes.get(value));
                return;
            }
            if(!quaryLog.containsKey(value)){
                queue.offer(value);
                quaryLog.put(value,"");
            }
        }
    }
    return ;
}

  

  run 一把,結果出來了

  [起點, A, 終點]

  終於,結果出來了,先到A地,再從A到終點,其實這就是廣度優先搜尋,so easy興沖沖去買票,發現錢不夠,哎,沒有考慮票價啊!!!我的票價是這樣的:

 

  按照現在的規劃需要700元,可是我只有650元,不夠啊,沒辦法,修改演算法把,這次需要把價錢考慮進去,我需要最便宜的路線

  思路也類似,先從起點開始走,分別計算最便宜的路線

 

  終點暫時到不了,我們把到終點的距離記作無窮,接著我們從B點開始往下找,計算最便宜的價錢如下:

 

  然後再計算A點走的話,最便宜的路線,比從B點走便宜的話我們就更新,不便宜的話代表原來的價錢已經是最便宜的了

 

  找到了,最便宜的路線是600,但是程式要如何做呢,畢竟我以後不僅要回家,還要去旅遊,還要去丈母孃家,我要每次都最便宜!!!,擼碼如下:


public static void  queryMainSaled(HashMap<String,HashMap<String,Integer>> data,String start,String end){

    HashMap<String,Integer> costs = new HashMap<String, Integer>();

    HashMap<String,List<String>> route = new HashMap<String, List<String>>();

    for(Map.Entry<String,Integer> entry: data.get(start).entrySet()){

        costs.put(entry.getKey(),entry.getValue());

        List<String> list = new ArrayList<String>();

        list.add(entry.getKey());

        route.put(entry.getKey(),list);

    }

    costs.put(end,Integer.MAX_VALUE);

    HashMap<String,String> queryLog = new HashMap<String, String>();

    String key = findMainSaleKey(costs,queryLog);

    while (key != null){

        queryLog.put(key,"");

        if(data.get(key) == null){

            break;

        }

        for(Map.Entry<String,Integer> entry:data.get(key).entrySet()){

            if(costs.containsKey(entry.getKey())){

                if(entry.getValue()+costs.get(key)<costs.get(entry.getKey())){

                    costs.put(entry.getKey(),entry.getValue()+costs.get(key));

                    List<String> list = new ArrayList<String>();

                    list.addAll(route.get(key));

                    list.add(entry.getKey());

                    route.put(entry.getKey(),list);

                }

            }else {

                costs.put(entry.getKey(),entry.getValue()+costs.get(key));

                List<String> list = new ArrayList<String>();

                list.addAll(route.get(key));

                route.put(entry.getKey(),list);

            }

        }

        key = findMainSaleKey(costs,queryLog);

    }

    System.out.println("最小花費:"+costs.get(end));

    System.out.println("最小花費路徑:"+route.get(end));

}

private static String findMainSaleKey(HashMap<String,Integer> data,HashMap<String,String> queryLog){

    String key = null;

    for(Map.Entry<String,Integer> entry : data.entrySet()){

        if(!queryLog.containsKey(entry.getKey()) && key == null ){

            key = entry.getKey();

        }

        if(!queryLog.containsKey(entry.getKey()) && entry.getValue()<data.get(key)){

            key = entry.getKey();

        }

    }

    return  key;

}

  

  執行結果:

  最小花費:600

  最小花費路徑:[B, A, 終點]

  結果出來了,先買到B的票,然後在到A,再回家,只要600塊,還能省50塊,完美!!這就是大名鼎鼎的狄克斯特拉演算法。

相關文章