有时列表没有初始化

时间:2014-12-11 09:36:14

标签: c# list initialization

已解决:我自己想通了。我无法在2天内选择我的答案。谢谢大家!

我有这个奇怪的错误。有时我的列表是0,当我不明白为什么。每次我通过调试器,它都有效。它让我发疯了。请帮忙!顺便说一句,这是旅行销售员的分支和约束。

 public static BSSFPair generateBSSF(ref City[] Cities, int numberOfTrials)
    {
        int n = Cities.Length;

        //Declare variable for updating.
        double minCostOfBSSF = double.PositiveInfinity;
        List<int> minRandomCityOrder = new List<int>();

        //Try many random paths, and keep track of the minimum-cost path. Then select the minimum-cost path as the BSSF.
        for (int iteration = 0; iteration < numberOfTrials; iteration++)
        {
            //Choose a random path.
            List<int> randomCityOrder = new List<int>(generateRandomOrderInts(n)); //a list of ints of cities. Each city int only occurs once.

            //Determine cost of route using the TSPSolution class.
            System.Collections.ArrayList cities = new System.Collections.ArrayList(); //a list of City objects
            foreach (int i in randomCityOrder)
            {
                cities.Add(Cities[i]);
            }
            ProblemAndSolver.TSPSolution bssf = new ProblemAndSolver.TSPSolution(cities);
            double costOfBSSF = bssf.costOfRoute();

            //Update the minimums.
            if (costOfBSSF < minCostOfBSSF)
            {
                minCostOfBSSF = costOfBSSF;
                minRandomCityOrder = new List<int>(randomCityOrder);
            }
        }

        //return the path and the cost of the BSSF.

//<---- This is where the method with the bug was called.

        return new BSSFPair(minCostOfBSSF, convertCityListToEdges(minRandomCityOrder)); //<---- THIS IS WHERE THE METHOD WITH THE BUG WAS CALLED.
    }

此方法是发生错误的地方:

    /// <summary>
    /// Converts a list of cities (WITHOUT THE LAST CITY BEING A DUPLICATE OF THE FIRST CITY) to a list of edges
    /// (WITH THE LAST EDGE GOING BACK TO THE START OF THE FIRST EDGE because it wraps around so you can easily draw it).
    /// </summary>
    /// <param name="minRandomCityOrder"></param>
    /// <returns></returns>
    public static List<Edge> convertCityListToEdges(List<int> minRandomCityOrder)
    {
        if(minRandomCityOrder.Count < 2)
        {

//Right here->

            throw new NotImplementedException();  //<------- RIGHT HERE. minRandomCityOrder count is 0. How did that happen?
        }
        int n = minRandomCityOrder.Count;
        //Convert the BSSF path to a list of edges.
        List<Edge> newBssfPath = new List<Edge>();
        int prev = minRandomCityOrder[0];
        for (int i = 1; i < n; i++)
        {
            newBssfPath.Add(new Edge(prev, minRandomCityOrder[i]));
            prev = minRandomCityOrder[i];
        }
        //Add edge from end to start.
        newBssfPath.Add(new Edge(minRandomCityOrder[n - 1], minRandomCityOrder[0]));

        return newBssfPath;
    }

以下代码调用的实用程序函数。我自己测试了这个,它永远不会返回一个空列表。

    /// <summary>
    /// Generate a list of ints in the range [0, (maximum-1)] (Inclusive) in a random order. Each int occurs only once in the list.
    /// </summary>
    /// <param name="maximum"> "maximum" is the upper bound, and is not included in the list.</param>
    /// <returns>the random-ordered list.</returns>
    private static List<int> generateRandomOrderInts(int maximum)
    {
        if (maximum < 1)
        {
            throw new NotImplementedException();
        }
        Random random = new Random();
        List<int> intsToAdd = new List<int>();
        List<int> randomOrderList = new List<int>();

        for (int i = 0; i < maximum; i++)
        {
            intsToAdd.Add(i);
        }
        while (intsToAdd.Count > 0)
        {
            //Returns a random int between 0 and n-1, inclusive.
            int randomInt = random.Next(intsToAdd.Count);
            randomOrderList.Add(intsToAdd[randomInt]);
            intsToAdd.RemoveAt(randomInt);
        }

        return randomOrderList;
    }

2 个答案:

答案 0 :(得分:1)

我发现了什么问题。在这种方法中:

  public static BSSFPair generateBSSF(ref City[] Cities, int numberOfTrials)
    {
        int n = Cities.Length;

        //Declare variable for updating.
        double minCostOfBSSF = double.PositiveInfinity;
        List<int> minRandomCityOrder = new List<int>();//<--------------here
    ...

它从空开始。问题是这假设最小值(初始化为无穷大)将被更新,然后然后 minRandomCityOrder将获得一个初始化它的新列表。但是,如果我随机选择具有无穷大成本的路径,那么它将永远不会更新。

所以,这就是修复我的代码的原因:

  public static BSSFPair generateBSSF(ref City[] Cities, int numberOfTrials)
    {
        int n = Cities.Length;

        //Declare variable for updating.
        double minCostOfBSSF = double.PositiveInfinity;
        List<int> minRandomCityOrder = new List<int>(generateRandomOrderInts(n)); //<---fixed
  ...

现在,如果到目前为止它还没有更新最佳解决方案,它就不会破坏代码,只会有一个垃圾路径来计算。

答案 1 :(得分:0)

我猜这个条件是true,你的列表会被重置:

//Update the minimums.
if (costOfBSSF < minCostOfBSSF)
{
    minCostOfBSSF = costOfBSSF;
    minRandomCityOrder = new List<int>(randomCityOrder);
}

这并不意味着您使用randomCityOrder初始化列表 - 项目数量,但列表具有此初始容量。如果您想拥有该数量的物品,可以尝试:

minRandomCityOrder = Enumerable.Range(0, randomCityOrder).ToList();

...但我不知道你的算法是否有意义。我只是展示了什么是可能的。