2016-03-06 30 views
0

这是我在StackOverflow上的第一篇文章,所以请告诉我如果我做错了什么,而且英文不是我的母语,请原谅我,如果有任何格式化错误。从GoogleMapsAPI NuGet包中排列类型为“位置”的数组排列

我的问题是如何排列“位置”类型数组的项目,我需要获取用户给出的所有路标的排列,然后根据时间或距离计算出最佳路线。 (我不想使用正常的路线计算)

我已经搜索了算法,但是当我把类型“Location []”的数组放在函数的参数中时,我得到的错误是对象需要IEnumerable,我不知道如何转换,如果甚至可能的话,我从来没有使用过IEnumerable。

如果它的任何帮助,这是我的计算路线代码:

//Gets the waypoints from a listBox provided by the user, "mode" selects between best time and best distance 
    //backgroundworker so the UI dont freezes, and return the optimal waypoint order 
    public Location[] CalcularRota(Location[] waypoints, int mode, BackgroundWorker work, DoWorkEventArgs e) 
    { 
     //Declarations 
     string origem = ""; 
     string destino = ""; 
     Rota[] prop = new Rota[100]; //this index is the number of times the algorithm will be executed, more equals accuracy but much more time to complete 
     Rota bestDist = new Rota(); 
     Rota bestTime = new Rota(); 
     DirectionService serv = new DirectionService(); 
     DirectionRequest reqs = new DirectionRequest(); 
     DirectionResponse resp; 
     Random rnd = new Random(); 
     Location[] rndWays; 
     int dist = 0; 
     int ti = 0; 

     bestDist.Distance = 1000000000; //put higher values for the first comparation to be true (end of code) 
     bestTime.Time = 1000000000; 

     if (waypoints != null) 
     { 
      reqs.Sensor = false; 
      reqs.Mode = TravelMode.driving;    

      for (int i = 0; i < prop.Length; i++) //initializes prop 
       prop[i] = new Rota(); 

      for (int i = 0; i < prop.Length; i++) 
      { 
       rndWays = waypoints.OrderBy(x => rnd.Next()).ToArray(); //randomizes the order, I want to get all permutations and then test 
                     //but I dont know how so I've been using randomized 
       dist = ti = 0; 
       origem = prop[0].ToString(); //save this particular waypoint's origin and destination 
       destino = prop[1].ToString(); 

       reqs.Origin = origem; 
       reqs.Destination = destino; 

       if (waypoints.Length > 0) 
        reqs.Waypoints = rndWays; 

       resp = serv.GetResponse(reqs); //request the route with X order of waypoints to google 

       if (resp.Status == ServiceResponseStatus.Ok) //wait the response otherwise the program crashes 
       { 
        for (int j = 0; j < resp.Routes[0].Legs.Length; j++) //gets the distance and time of this particular order 
        { 
         ti += int.Parse(resp.Routes[0].Legs[j].Duration.Value); 
         dist += int.Parse(resp.Routes[0].Legs[j].Distance.Value); 
        } 
       } 

       prop[i].Origem = origem; //saves this waypoints order details for further comparison 
       prop[i].Destino = destino; 
       prop[i].Distance = dist; 
       prop[i].Time = ti; 
       prop[i].Order = rndWays; 

       work.ReportProgress(i); //report the progress 
      } 

      for (int i = 0; i < prop.Length; i++) //gets the best distance and time 
      { 
       if (bestDist.Distance > prop[i].Distance) 
       { 
        bestDist.Distance = prop[i].Distance; 
        bestDist.Time = prop[i].Time; 
        bestDist.Order = prop[i].Order; 
        bestDist.Origem = prop[i].Origem; 
        bestDist.Destino = prop[i].Destino; 
       } 
       if (bestTime.Time > prop[i].Time) 
       { 
        bestTime.Distance = prop[i].Distance; 
        bestTime.Time = prop[i].Time; 
        bestTime.Order = prop[i].Order; 
        bestTime.Origem = prop[i].Origem; 
        bestTime.Destino = prop[i].Destino; 
       } 
      } 

      if (bestDist.Order == bestTime.Order) //if the same waypoint order has the same time and distance 
       return bestDist.Order;   // returns whatever bestDist.Order or bestTime.Order 
      else if (bestDist.Order != bestTime.Order) //if different returns corresponding to the mode selected 
      { 
       if (mode == 1) return bestDist.Order; 
       if (mode == 2) return bestTime.Order; 
      } 
     } 
     return null; 
    } 

我想是到重排列给出的航点和测试每个排列,我一直在挣扎这一段时间,如果你们能以任何方式帮助我,那就太好了。

Ty。

编辑。

我在这里发现这个功能在计算器上:

public static bool NextPermutation<T>(T[] elements) where T : IComparable<T> 
    { 
     var count = elements.Length; 

     var done = true; 

     for (var i = count - 1; i > 0; i--) 
     { 
      var curr = elements[i]; 

      // Check if the current element is less than the one before it 
      if (curr.CompareTo(elements[i - 1]) < 0) 
      { 
       continue; 
      } 

      // An element bigger than the one before it has been found, 
      // so this isn't the last lexicographic permutation. 
      done = false; 

      // Save the previous (bigger) element in a variable for more efficiency. 
      var prev = elements[i - 1]; 

      // Have a variable to hold the index of the element to swap 
      // with the previous element (the to-swap element would be 
      // the smallest element that comes after the previous element 
      // and is bigger than the previous element), initializing it 
      // as the current index of the current item (curr). 
      var currIndex = i; 

      // Go through the array from the element after the current one to last 
      for (var j = i + 1; j < count; j++) 
      { 
       // Save into variable for more efficiency 
       var tmp = elements[j]; 

       // Check if tmp suits the "next swap" conditions: 
       // Smallest, but bigger than the "prev" element 
       if (tmp.CompareTo(curr) < 0 && tmp.CompareTo(prev) > 0) 
       { 
        curr = tmp; 
        currIndex = j; 
       } 
      } 

      // Swap the "prev" with the new "curr" (the swap-with element) 
      elements[currIndex] = prev; 
      elements[i - 1] = curr; 

      // Reverse the order of the tail, in order to reset it's lexicographic order 
      for (var j = count - 1; j > i; j--, i++) 
      { 
       var tmp = elements[j]; 
       elements[j] = elements[i]; 
       elements[i] = tmp; 
      } 

      // Break since we have got the next permutation 
      // The reason to have all the logic inside the loop is 
      // to prevent the need of an extra variable indicating "i" when 
      // the next needed swap is found (moving "i" outside the loop is a 
      // bad practice, and isn't very readable, so I preferred not doing 
      // that as well). 
      break; 
     } 

     // Return whether this has been the last lexicographic permutation. 
     return done; 
    } 

用法是:

NextPermutation(array); 

这样做的,把我的阵列(rndWays)的过载,我得到了以下错误:

类型'Google.Maps.Location'不能用作泛型类型或方法'Form1.NextPermutation < T>(T [])'中的类型参数'T''。没有从'Google.Maps.Location'到'System.IComparable < Google.Maps.Location>'的隐式引用转换。

+0

C#中的数组应该实现IEnumerable。你能提供特定的代码来显示错误吗? –

+0

添加置换算法。 –

回答

0

问题是Location没有实现IComparable接口。

变化:

public static bool NextPermutation<T>(T[] elements) where T : IComparable<T> 

到:

public static bool NextPermutation(Location[] elements) 

并用自己的比较函数替换每个的CompareTo()。