2016-08-02 13 views
0

Ich habe schon eine Weile nachgesehen und kann es nicht herausfinden. Wie die folgenden Kommentare zeigen, befinden sich die fraglichen Indizes in der Liste.Wie bekomme ich hier eine Ausnahme außerhalb des Bereichs?

using System; 
using System.IO; 
using System.Linq; 
using System.Collections.Generic; 

public class Mine 
{ 
    public int Distance { get; set; } 
    public int Gold { get; set; } 
} 

public class Move 
{ 
    public int SourceIndex { get; set; } 
    public int DestinationIndex { get; set; } 
    public int Cost { get; set; } 
} 

public class Program 
{ 
    public static void Main() 
    { 

     var mines = new List<Mine>() { 
      new Mine() { Distance = 10, Gold = 1 }, 
      new Mine() { Distance = 20, Gold = 2 }, 
      new Mine() { Distance = 25, Gold = 1 } 
     }; 

     // Cost of consolidating the gold from mines[i1] to mines[i2] 
     Func<int,int,int> Cost = (i1, i2) => Math.Abs(mines[i1].Distance - mines[i2].Distance) * mines[i1].Gold; 

     // Number of mines to consolidate the gold into 
     int k = 1; 


     var bestMove = new Move() { SourceIndex = -1, DestinationIndex = -1, Cost = Int32.MaxValue }; 

     // total cost 
     int sum = 0; 

     while(mines.Count != k) 
     { 
      var indices = Enumerable.Range(0, mines.Count).ToArray(); 
      for(int i = 0, j = 1; j < indices.Length; ++i, ++j) 
      { 
       int cost_ij = Cost(i,j); 
       if(cost_ij < bestMove.Cost) 
       { 
        bestMove.SourceIndex = i; 
        bestMove.DestinationIndex = j; 
        bestMove.Cost = cost_ij; 
       } 

       int cost_ji = Cost(j,i); 
       if(cost_ji < bestMove.Cost) 
       { 
        bestMove.SourceIndex = j; 
        bestMove.DestinationIndex = i; 
        bestMove.Cost = cost_ji; 
       } 
      } 
      Console.WriteLine("bestMove.SourceIndex = {0}, bestMove.DestinationIndex = {1}", bestMove.SourceIndex, bestMove.DestinationIndex); // prints "bestMove.SourceIndex = 2, bestMove.DestinationIndex = 1" 
      sum += bestMove.Cost; 
      mines[bestMove.DestinationIndex].Gold += mines[bestMove.SourceIndex].Gold; // this is throwing an exception "Index was out of range. Must be non-negative and less than the size of the collection." 
      mines.RemoveAt(bestMove.SourceIndex); 

     } 
     Console.WriteLine(sum); 
    } 
} 

Geige: https://dotnetfiddle.net/hYa3A0

Es macht keinen Sinn, weil zum Zeitpunkt der

  Console.WriteLine("bestMove.SourceIndex = {0}, bestMove.DestinationIndex = {1}", bestMove.SourceIndex, bestMove.DestinationIndex); // prints "bestMove.SourceIndex = 2, bestMove.DestinationIndex = 1" 
      sum += bestMove.Cost; 
      mines[bestMove.DestinationIndex].Gold += mines[bestMove.SourceIndex].Gold; // this is throwing an exception "Index was out of range. Must be non-negative and less than the size of the collection." 
      mines.RemoveAt(bestMove.SourceIndex); 

Linien zum ersten Mal ausgeführt werden,

bestMove.DestinationIndex = 2 
bestMove.DestinationIndex = 1 

und

mines.Count = 3 

Vielleicht bin ich einfach verrückt.

+1

Die Frage zu diesem überraschend ähnlich aussieht: http://stackoverflow.com/questions/38711479/where-is-the-flaw-in -my-algorithm-for-consolidating-gold-mines/38711949 Ist das eine Aufgabe? –

+0

Sie verwenden die selbe Instanz von bestMove, Sie müssen die Felder nach jeder while-Schleife zurücksetzen (schätze ich). – lcastillov

+0

Was ist der Wert von 'bestMove.DestinationIndex' und' bestMove.SourceIndex', wenn diese Zeile ausgeführt wird? Das wird Ihnen sagen, warum Sie die Ausnahme bekommen. –

Antwort

2

Indizes ist ein auf Null basierender Index.

die zu diesem for-Schleife ändern:

for(int i = 0, j = 1; j < indices.Length-1; ++i, ++j) 
0

Das Problem mit Ihrem Zähler j. j wird an einer Stelle 4 zugewiesen, die die Größe Ihrer Minensammlung übersteigt (3).

Ändern Sie die erste Zeile in while-Schleife dazu:

var indices = Enumerable.Range(0, mines.Count - 1).ToArray();