Loading

最优路径的一种算法(原创)

问题来自博问:http://q.cnblogs.com/q/28763/

给定的测试矩阵:

测试矩阵数据
  1. public int[,] InitMap()
  2. {
  3.     //x-1,??-2,??-3,??????
  4.     return new int[Width,Height]
  5.                {
  6.                    {-2, 1, 5, 2, 4, 5, 8, 2, 1},
  7.                    {1, 5, 2, 4, 5, 8, 2, -1, 5},
  8.                    {2, 7, 5, 2, 4, 5, -1, 2, 1},
  9.                    {2, 1, 3, 2, -1, 0, 8, 7, 3},
  10.                    {2, 1, 5, 1, 9, 5, 2, 2, 1},
  11.                    {4, 8, 4, 3, 4, 2, 8, 2, 3},
  12.                    {2, 1, 5, 6, 4, 5, 7, 4, 1},
  13.                    {2, 8, 7, 2, 4, 5, 8, 2, 1},
  14.                    {1, 5, 5, 4, 5, 6, 2, 2, -3}
  15.                };
  16. }

 

递归路径查找:

Code Snippet
  1. public bool NextStep(int x,int y )
  2. {
  3.     if (x < 0 || x >=Width)
  4.         return false;
  5.     if(y<0||y>=Height)
  6.         return false;
  7.  
  8.     //?????????1
  9.     if(CurRoad.Count==KKCatStep+1)
  10.         return false;
  11.  
  12.     int curScore = map[x, y];
  13.     //?
  14.     if(curScore==-1)
  15.         return false;
  16.     //??????
  17.     if (CurRoad.Any(c => c.X == x && c.Y == y))
  18.         return false;
  19.  
  20.     CurRoad.Push(new Coord(x,y));
  21.  
  22.     //?????????
  23.     if (curScore == -3)
  24.     {
  25.         var score = CurRoad.Skip(1).Take(CurRoad.Count - 2).Sum(c => map[c.X, c.Y]);
  26.         if(score>LastScore)
  27.         {
  28.             LastScore = score;
  29.             var road = CurRoad.ToList();
  30.             road.Reverse();
  31.             NiceRoads.Add(road);
  32.         }
  33.  
  34.         return true;
  35.     }
  36.     
  37.     //???
  38.  
  39.     if (NextStep(x + 1, y))
  40.         CurRoad.Pop();
  41.     if(NextStep(x, y + 1))
  42.         CurRoad.Pop();
  43.     if(NextStep(x - 1, y))
  44.         CurRoad.Pop();
  45.     if(NextStep(x, y - 1))
  46.         CurRoad.Pop();
  47.     return true;
  48. }

 

效率还不是很高,特别对更大的地图时算法还有待优化。

以下是完整的代码:

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Xunit;
  6.  
  7. namespace KKCatWalking
  8. {
  9.     public class Walking
  10.     {
  11.         protected int[,] map;
  12.         const int Width= 9, Height = 9;
  13.         private Stack<Coord> CurRoad = new Stack<Coord>();
  14.         private List<List<Coord>> NiceRoads = new List<List<Coord>>();
  15.         private int KKCatStep = 19;
  16.         private int LastScore=0;
  17.         public Walking()
  18.         {
  19.             map = InitMap();
  20.  
  21.         }
  22.  
  23.         [Fact]
  24.         public void FindWays()
  25.         {
  26.             NextStep(0, 0);
  27.             NiceRoads.TrimExcess();
  28.             Console.WriteLine("KKCatStep:{0}\tTotal Roads:{1} MaxScore:{2}",KKCatStep,NiceRoads.Count,NiceRoads.Max(r=>r.Skip(1).Take(r.Count-2).Sum(c=>map[c.X,c.Y])));
  29.             foreach(var r in NiceRoads.OrderByDescending(r=>r.Skip(1).Take(r.Count-2).Sum(c=>map[c.X,c.Y])).Take(20))
  30.             {
  31.                 int sum = 0;
  32.                 foreach (var c in r)
  33.                 {
  34.                     Console .Write("{0},{1}\t",c.X,c.Y);
  35.                     sum += map[c.X, c.Y];
  36.                 }
  37.                 Console.WriteLine("Score:{0}\t", sum+5);
  38.                 Console.WriteLine();
  39.             }
  40.         }
  41.  
  42.         public bool NextStep(int x,int y )
  43.         {
  44.             if (x < 0 || x >=Width)
  45.                 return false;
  46.             if(y<0||y>=Height)
  47.                 return false;
  48.  
  49.             //?????????1
  50.             if(CurRoad.Count==KKCatStep+1)
  51.                 return false;
  52.  
  53.             int curScore = map[x, y];
  54.             //?
  55.             if(curScore==-1)
  56.                 return false;
  57.             //??????
  58.             if (CurRoad.Any(c => c.X == x && c.Y == y))
  59.                 return false;
  60.  
  61.             CurRoad.Push(new Coord(x,y));
  62.  
  63.             //?????????
  64.             if (curScore == -3)
  65.             {
  66.                 var score = CurRoad.Skip(1).Take(CurRoad.Count - 2).Sum(c => map[c.X, c.Y]);
  67.                 if(score>LastScore)
  68.                 {
  69.                     LastScore = score;
  70.                     var road = CurRoad.ToList();
  71.                     road.Reverse();
  72.                     NiceRoads.Add(road);
  73.                 }
  74.  
  75.                 return true;
  76.             }
  77.             
  78.             //???
  79.  
  80.             if (NextStep(x + 1, y))
  81.                 CurRoad.Pop();
  82.             if(NextStep(x, y + 1))
  83.                 CurRoad.Pop();
  84.             if(NextStep(x - 1, y))
  85.                 CurRoad.Pop();
  86.             if(NextStep(x, y - 1))
  87.                 CurRoad.Pop();
  88.             return true;
  89.         }
  90.  
  91.         public int[,] InitMap()
  92.         {
  93.             //x-1,??-2,??-3,??????
  94.             return new int[Width,Height]
  95.                        {
  96.                            {-2, 1, 5, 2, 4, 5, 8, 2, 1},
  97.                            {1, 5, 2, 4, 5, 8, 2, -1, 5},
  98.                            {2, 7, 5, 2, 4, 5, -1, 2, 1},
  99.                            {2, 1, 3, 2, -1, 0, 8, 7, 3},
  100.                            {2, 1, 5, 1, 9, 5, 2, 2, 1},
  101.                            {4, 8, 4, 3, 4, 2, 8, 2, 3},
  102.                            {2, 1, 5, 6, 4, 5, 7, 4, 1},
  103.                            {2, 8, 7, 2, 4, 5, 8, 2, 1},
  104.                            {1, 5, 5, 4, 5, 6, 2, 2, -3}
  105.                        };
  106.         }
  107.         public struct Coord
  108.         {
  109.             public Coord(int x,int y)
  110.             {
  111.                 X = x;
  112.                 Y = y;
  113.             }
  114.  
  115.             public int X;
  116.             public int Y;
  117.         }
  118.     }
  119.     public enum MapEnum
  120.     {
  121.         Hole = -1,
  122.         Start = -2,
  123.         End = -3
  124.     }
  125. }

posted @ 2011-10-09 15:22  today4king  阅读(928)  评论(6编辑  收藏  举报