2016-08-02 9 views
0

これはしばらく見ていて、理解できません。以下のコメントが指摘しているように、問題の指標がリストにあります。ここでは範囲外の例外はどのようにして得られますか?

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); 
    } 
} 

フィドル:https://dotnetfiddle.net/hYa3A0

  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); 

ラインが

bestMove.DestinationIndex = 2 
bestMove.DestinationIndex = 1 

、初めて実行されているので、それは意味がありません

多分私はちょっと狂っています。

+1

質問はこの1つに驚くほど似ています:http://stackoverflow.com/questions/38711479/where-is-the-flaw-in -my-consolidating-gold-mines/38711949 これは割り当てですか? –

+0

あなたはbestMoveの同じインスタンスを使用しているので、毎回loop(i推測)の間にそのフィールドをリセットする必要があります。 – lcastillov

+0

'bestMove.DestinationIndex'と' bestMove.SourceIndex'の値は何行ですか?それはあなたが例外を得ている理由を教えてくれるでしょう。 –

答えて

2

インデックスはゼロベースのインデックスです。

変更し、これにforループ:

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

問題は、あなたのカウンタjです。 jはあなたの鉱山コレクション(3)のサイズを超えて1ポイントで4を割り当てられます。

変更し、これに、whileループの最初の行:

var indices = Enumerable.Range(0, mines.Count - 1).ToArray(); 
関連する問題