已解决:我自己想通了。我无法在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;
}
答案 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();
...但我不知道你的算法是否有意义。我只是展示了什么是可能的。