日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

揽货最短路径解决方案算法 - C# 蚁群优化算法实现

發(fā)布時(shí)間:2023/12/4 C# 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 揽货最短路径解决方案算法 - C# 蚁群优化算法实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

需求為(自己編的,非實(shí)際項(xiàng)目):

某配送中心進(jìn)行攬貨,目標(biāo)客戶數(shù)為50個(gè)客戶,配送中心目前的運(yùn)力資源如下:

  • 現(xiàn)有車輛5臺(tái)

  • 單臺(tái)運(yùn)力最大行駛距離200千米

  • 單臺(tái)運(yùn)力最大載重公斤1噸

  • 問(wèn):運(yùn)力怎樣走法才能以最低的成本完成針對(duì)這50個(gè)客戶的攬貨行為

    是個(gè)最優(yōu)化問(wèn)題(運(yùn)籌學(xué)),我們只考慮簡(jiǎn)化后的模型,不考慮路面交通、時(shí)間窗口這些復(fù)雜計(jì)算,用蟻群優(yōu)化算法來(lái)實(shí)現(xiàn)接近最優(yōu)解的計(jì)算。

    關(guān)于蟻群優(yōu)化算法的理論請(qǐng)看這篇文章:https://www.cnblogs.com/asxinyu/p/Path_Optimization_Tsp_Problem_Ant_System_CSharp.html

    里面的基本算法已經(jīng)寫明了,也有demo,本文是針對(duì)如何適應(yīng)到具體業(yè)務(wù)的介紹(本文用的蟻群核心代碼也是上文中改來(lái)的)

    蟻群主要步驟為:

  • 初始化(如信息素)

  • 開始迭代

  • 構(gòu)造各個(gè)螞蟻,以及螞蟻?zhàn)叩穆窂?#xff08;核心是針對(duì)后續(xù)節(jié)點(diǎn)的SELECT)

  • 計(jì)算適應(yīng)度

  • 加入優(yōu)秀螞蟻到跟蹤列表

  • 更新信息素(根據(jù)適應(yīng)度)

  • 結(jié)束迭代

  • 給出報(bào)告

  • 原文章里用的是TSP做DEMO,比較難看清楚如何應(yīng)用到實(shí)際業(yè)務(wù)邏輯中

    同樣的,最困惑的核心中的核心,類似遺傳算法,也是適應(yīng)度值的計(jì)算,有的地方是一步一步增加vlaue,比如單純距離的增加,但是復(fù)雜點(diǎn)的都沒(méi)法這么操作,而是要看整體路徑的指標(biāo)(包括懲罰等)

    由于蟻群優(yōu)化算法和本文代碼都能下載,所以只介紹適應(yīng)度value的計(jì)算

    class FitnessValueCalculator

    ? ? {

    ? ? ? ? private static int 擁有運(yùn)力車輛數(shù) = 5;

    ? ? ? ? private static int 單臺(tái)運(yùn)力最大行駛距離 = 200;

    ? ? ? ? private static int 單臺(tái)運(yùn)力最大載重公斤 = 1000;

    ? ? ? ? private static double 懲罰權(quán)重 = 20;


    ? ? ? ? public static double Calculator(ShortestDeliverAnt ant)

    ? ? ? ? {

    ? ? ? ? ? ? var paths = new List<string>();


    ? ? ? ? ? ? var distances = new List<double>();

    ? ? ? ? ? ? var weights = new List<double>();


    ? ? ? ? ? ? double 當(dāng)前行駛距離 = 0;

    ? ? ? ? ? ? double 當(dāng)前運(yùn)力載重 = 0;

    ? ? ? ? ? ? string 當(dāng)前行駛路徑 = "";

    ? ? ? ? ? ? int 當(dāng)前所需運(yùn)力數(shù) = 1;


    ? ? ? ? ? ? //計(jì)算樞紐到第一個(gè)客戶配送距離

    ? ? ? ? ? ? 當(dāng)前行駛路徑 += "HUB-->" + ant.PathNodes.First();

    ? ? ? ? ? ? 當(dāng)前行駛距離 += ant.DistanceHelper.hub.DistanceTo(ant.DistanceHelper.customers[ant.PathNodes.First()]);

    ? ? ? ? ? ? 當(dāng)前運(yùn)力載重 += ant.DistanceHelper.customers[ant.PathNodes.First()].需求量_公斤;


    ? ? ? ? ? ? foreach (var path in ant.Edges)

    ? ? ? ? ? ? {

    ? ? ? ? ? ? ? ? var fromNodeId = path.Key;

    ? ? ? ? ? ? ? ? var toNodeId = path.Value;


    ? ? ? ? ? ? ? ? var fromNode = ant.DistanceHelper.customers[fromNodeId];

    ? ? ? ? ? ? ? ? var toNode = ant.DistanceHelper.customers[toNodeId];


    ? ? ? ? ? ? ? ? double newAddedDistance2Customer = 0;

    ? ? ? ? ? ? ? ? double newAddedDistance2Hub = 0;

    ? ? ? ? ? ? ? ? double newAddedWeight = 0;


    ? ? ? ? ? ? ? ? newAddedDistance2Customer = fromNode.DistanceTo(toNode);

    ? ? ? ? ? ? ? ? newAddedDistance2Hub = toNode.DistanceTo(ant.DistanceHelper.hub);


    ? ? ? ? ? ? ? ? newAddedWeight = toNode.需求量_公斤;


    ? ? ? ? ? ? ? ? if (當(dāng)前行駛距離 + newAddedDistance2Customer + newAddedDistance2Hub <= 單臺(tái)運(yùn)力最大行駛距離

    ? ? ? ? ? ? ? ? ? ? &&

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前運(yùn)力載重 <= 單臺(tái)運(yùn)力最大載重公斤)

    ? ? ? ? ? ? ? ? {

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前行駛距離 += newAddedDistance2Customer;

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前運(yùn)力載重 += newAddedWeight;

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前行駛路徑 += "-->" + toNodeId;

    ? ? ? ? ? ? ? ? }

    ? ? ? ? ? ? ? ? else

    ? ? ? ? ? ? ? ? {

    ? ? ? ? ? ? ? ? ? ? //加當(dāng)前客戶距離、以及回到HUB的距離

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前行駛距離 += fromNode.DistanceTo(ant.DistanceHelper.hub);

    ? ? ? ? ? ? ? ? ? ? distances.Add(當(dāng)前行駛距離);


    ? ? ? ? ? ? ? ? ? ? weights.Add(當(dāng)前運(yùn)力載重);


    ? ? ? ? ? ? ? ? ? ? 當(dāng)前行駛路徑 += "-->HUB";

    ? ? ? ? ? ? ? ? ? ? paths.Add(當(dāng)前行駛路徑);


    ? ? ? ? ? ? ? ? ? ? //RESET

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前行駛距離 = 0;

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前行駛距離 += ant.DistanceHelper.hub.DistanceTo(toNode);


    ? ? ? ? ? ? ? ? ? ? 當(dāng)前運(yùn)力載重 = 0;

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前運(yùn)力載重 += toNode.需求量_公斤;


    ? ? ? ? ? ? ? ? ? ? 當(dāng)前行駛路徑 = "";

    ? ? ? ? ? ? ? ? ? ? 當(dāng)前行駛路徑 += "HUB-->" + toNodeId;


    ? ? ? ? ? ? ? ? ? ? 當(dāng)前所需運(yùn)力數(shù)++;

    ? ? ? ? ? ? ? ? }

    ? ? ? ? ? ? }


    ? ? ? ? ? ? //回到樞紐

    ? ? ? ? ? ? 當(dāng)前行駛距離 += ant.DistanceHelper.customers[ant.PathNodes.Last()].DistanceTo(ant.DistanceHelper.hub);

    ? ? ? ? ? ? distances.Add(當(dāng)前行駛距離);


    ? ? ? ? ? ? 當(dāng)前行駛路徑 += "-->HUB";

    ? ? ? ? ? ? paths.Add(當(dāng)前行駛路徑);




    ? ? ? ? ? ? int 懲罰系數(shù) = 0;

    ? ? ? ? ? ? if (當(dāng)前所需運(yùn)力數(shù) > 擁有運(yùn)力車輛數(shù))

    ? ? ? ? ? ? ? ? 懲罰系數(shù) = 當(dāng)前所需運(yùn)力數(shù) - 擁有運(yùn)力車輛數(shù);



    ? ? ? ? ? ? ant.運(yùn)輸距離順序 = distances;

    ? ? ? ? ? ? ant.運(yùn)輸路徑 = paths;


    ? ? ? ? ? ? ant.Total行駛距離 = distances.Sum();

    ? ? ? ? ? ? ant.Total運(yùn)力數(shù) = 當(dāng)前所需運(yùn)力數(shù);


    ? ? ? ? ? ? return ant.Total行駛距離 + 懲罰系數(shù) * 懲罰權(quán)重;

    ? ? ? ? }

    ? ? }

    ant.DistanceHelper.hub: 是配送中心的info,有地址信息
    ant.DistanceHelper.customers: 是50個(gè)客戶的info,也有地址信息
    目前為了簡(jiǎn)化,是以街道距離來(lái)計(jì)算距離的目前代碼只是單目標(biāo)優(yōu)化算法,非多目標(biāo)優(yōu)化,后續(xù)研究研究再發(fā)文。
    上述代碼其實(shí)就是第一輛車從配送中心開出到第一個(gè)客戶位置,然后加上客戶需求(攬的貨物重量)
    接著判斷能否開到下一個(gè)客戶那里攬貨,如果里程、重量都在限制條件只能,就開過(guò)去,不滿足條件就開回樞紐;然后繼續(xù)判斷第二輛車,也是這么個(gè)邏輯
    最終車輛的數(shù)量就是完成這50個(gè)客戶攬貨所需的運(yùn)力數(shù)
    萬(wàn)一碰到所需運(yùn)力超出了限制(代碼中為5輛車),這時(shí)就需要懲罰,由于最終函數(shù)返回是double,而且是越小代表越優(yōu)越,因此碰到了需要懲罰的情況,實(shí)際就是大幅度的增加返回值(適應(yīng)度值)
    紅色部分就是懲罰變量部分。

    各種優(yōu)化算法的核心寫完框架后基本就不怎么變化了,最易變的其實(shí)是適應(yīng)度函數(shù)的計(jì)算,如果適應(yīng)度計(jì)算中用到了預(yù)測(cè)技術(shù),還得在上面那函數(shù)里調(diào)機(jī)器學(xué)習(xí)的代碼,感覺強(qiáng)化學(xué)習(xí)中動(dòng)作施加后給出的反饋值也是這么個(gè)值

    原文:https://www.cnblogs.com/aarond/p/ant_wuliu.html


    .NET社區(qū)新聞,深度好文,歡迎訪問(wèn)公眾號(hào)文章匯總 http://www.csharpkit.com

    總結(jié)

    以上是生活随笔為你收集整理的揽货最短路径解决方案算法 - C# 蚁群优化算法实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。