2016-03-06 54 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()。