单向路由算法

物流行业受成本、中转仓、时间等因素的限制,往往需要对货品的路由线路提出很多要求,怎样快速精准的找到这样的线路,并使用计算机语言实现出来?

根据相关行业经验,抽取了以下计算模型,该算法效率不是最高的,但是比Dijkstra、链路向量等专业算法可能更容易理解:

 

单向路由解递归实现:

       /// <summary>
       /// 单向路由算法
       /// </summary>
       /// <param name="start">起点</param>
       /// <param name="end">终点</param>
       /// <param name="map">地图</param>
       /// <param name="LIMIT">限制路由距离</param>
       /// <returns></returns>
       public static List<List<int>> GetAllRouteLine(int start, int end, Dictionary<int, List<int>> map, int LIMIT)
       {
           //已找到的通路
           var result = new List<List<int>>();

           //类似于深度优先遍历法,回到原点遍历完成

           //纵横栈-->未处理的各层节点
           var stackstack = new Stack<Queue<int>>();
           //纵向栈-->已连通路段
           var verstack = new Stack<int>();
           //起点可1步直达的节点列表
           var nextNodes = GetNextNodes(start, verstack.ToList(), LIMIT, end, map, result);
           if (nextNodes != null)
           {
               //起点
               verstack.Push(start);
               //起点对应的下一层
               stackstack.Push(nextNodes);
               while (stackstack.Count > 0)
               {
                   //当前处理层
                   var horqueue = stackstack.Peek();

                   //层层压入(待处理的层)
                   while (horqueue.Count > 0)
                   {
                       nextNodes = GetNextNodes(horqueue.Peek(), verstack.ToList(), LIMIT, end, map, result);
                       if (nextNodes != null)
                       {
                           verstack.Push(horqueue.Peek());
                           stackstack.Push(nextNodes);
                           horqueue = stackstack.Peek();
                       }
                       else
                       {
                           horqueue.Dequeue();
                       }
                   }
                   //层层弹出(处理完的层)
                   while (stackstack.Peek().Count == 0)
                   {
                       stackstack.Pop();
                       verstack.Pop();
                       if (stackstack.Count==0)
                       {
                           break;
                       }
                       if (stackstack.Peek().Count > 0)
                       {
                           stackstack.Peek().Dequeue();
                       }
                   }
               }
           }
           return result;
       }

 

辅助函数(可增加各种实际限制条件)

      /// <summary>
       /// 获取当前点能走通的下一点集合
       /// </summary>
       /// <param name="current">当前点</param>
       /// <param name="hadNode">已走通路段</param>
       /// <param name="LIMIT">限制路由距离</param>
       /// <param name="end">终点</param>
       /// <param name="map">地图</param>
       /// <param name="result">已完成线路集合</param>
       /// <returns></returns>
       private static Queue<int> GetNextNodes(int current, List<int> hadNode, int LIMIT, int end, Dictionary<int, List<int>> map, List<List<int>> result)
       {
           for (int i = hadNode.Count; i > 0; i--)
           {
               Console.Write(hadNode[i-1]+"-->");
           }
           Console.WriteLine(current);
           if (current==end)
           {
               var line = new List<int>();
               for (int i = hadNode.Count; i >0; i--)
               {
                   line.Add(hadNode[i - 1]);
               }
               line.Add(current);
               result.Add(line);
               return null;
           }

           if (hadNode.Count>=LIMIT||hadNode.Contains(current))
           {
               return null;
           }

           var stack = new Queue<int>();
           if (map.ContainsKey(current))
           {
               foreach (var item in map[current])
               {
                   if (!hadNode.Contains(item)&&!stack.Contains(item))
                   {
                       stack.Enqueue(item);
                   }
               }
               if (stack.Count>0)
               {
                   return stack;
               }
           }

           return null;
       }

 

调用方法

      static void Main1(string[] args)
       {
           /*
                        1
                       / \
                      2   3
                     /   / \
                    4   6   7
                   /   / \
                  5   8   9
          */
           Console.WriteLine("地图:");
           Console.WriteLine("       1");
           Console.WriteLine("      / \\");
           Console.WriteLine("     2   3");
           Console.WriteLine("    /   / \\");
           Console.WriteLine("   4   6   7");
           Console.WriteLine("  /   / \\");
           Console.WriteLine(" 5   8   9");

           var list = new Dictionary<int, List<int>>();
           list.Add(1, new List<int>() { 2, 3 });
           list.Add(2, new List<int>() { 4 });
           list.Add(3, new List<int>() { 6, 7 });
           list.Add(4, new List<int>() { 5 });
           list.Add(6, new List<int>() { 8, 9 });

           Console.WriteLine("路由过程:");
           var result = GetAllRouteLine(1, 8, list, 10);

           Console.WriteLine("找到通路:");
           foreach (var item in result)
           {
               foreach (var s in item)
               {
                   Console.Write(s + "-->");
               }
               Console.WriteLine();
           }
           Console.ReadLine();
       }

 

运行结果

 

posted @ 2015-09-24 14:56  格子左左  阅读(334)  评论(0编辑  收藏  举报