Добрый день! Ошибка в алгоритме, метод ветвей и границ. На некоторых графах работает, на некоторых нет - программа зависает рабочий вариант:
0 1 9 9 0
1 0 6 10 4
9 6 0 2 3
9 10 2 0 1
0 4 3 1 0
нет:
0 0 1 2 4
0 0 1 4 4
1 1 0 6 0
2 4 6 0 6
4 4 0 6 0
Помогите, пожалуйста, найти ошибку
public class CostMatrixItem
{
private int cost;
private int grade;
public int Cost
{
get { return cost; }
set { cost = value; }
}
public int Grade
{
get { return grade; }
set { grade = value; }
}
public CostMatrixItem(int _cost, int _grade)
{
cost = _cost;
grade = _grade;
}
}
public class CostMatrix
{
private int size;
private List<List<CostMatrixItem>> items;
private List<int> rowsNumbers;
private List<int> colsNumbers;
private List<int> currentPartOfPath;
public int Size
{
get { return size; }
}
public List<CostMatrixItem> this[int index]
{
get { return items[index]; }
}
public CostMatrix(List<List<int>> _values)
{
size = _values.Count;
items = new List<List<CostMatrixItem>>();
for (int i = 0; i < size; i++)
{
items.Add(new List<CostMatrixItem>());
for (int j = 0; j < size; j++)
items[i].Add(new CostMatrixItem(_values[i][j], -1));
}
rowsNumbers = new List<int>();
colsNumbers = new List<int>();
for (int i = 0; i < size; i++)
{
rowsNumbers.Add(i + 1);
colsNumbers.Add(i + 1);
}
currentPartOfPath = new List<int>();
}
public void ReduceRowsValues()
{
int rowMinCostValue = Int32.MaxValue;
for (int i = 0; i < size; i++)
{
rowMinCostValue = Int32.MaxValue;
for (int j = 0; j < size; j++)
if (items[i][j].Cost != -1 && items[i][j].Cost < rowMinCostValue)
rowMinCostValue = items[i][j].Cost;
for (int j = 0; j < size; j++)
if (items[i][j].Cost != -1)
items[i][j].Cost -= rowMinCostValue;
}
}
public void ReduceColsValues()
{
int colMinCostValue = Int32.MaxValue;
for (int j = 0; j < size; j++)
{
colMinCostValue = Int32.MaxValue;
for (int i = 0; i < size; i++)
if (items[i][j].Cost != -1 && items[i][j].Cost < colMinCostValue)
colMinCostValue = items[i][j].Cost;
for (int i = 0; i < size; i++)
if (items[i][j].Cost != -1)
items[i][j].Cost -= colMinCostValue;
}
}
public void CalculateGrades()
{
int rowMinCostValue = Int32.MaxValue;
int colMinCostValue = Int32.MaxValue;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
items[i][j].Grade = -1;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (items[i][j].Cost == 0)
{
rowMinCostValue = Int32.MaxValue;
for (int n = 0; n < size; n++)
if (items[i][n].Cost != -1 && n != j && items[i][n].Cost < rowMinCostValue)
rowMinCostValue = items[i][n].Cost;
colMinCostValue = Int32.MaxValue;
for (int n = 0; n < size; n++)
if (items[n][j].Cost != -1 && n != i && items[n][j].Cost < colMinCostValue)
colMinCostValue = items[n][j].Cost;
items[i][j].Grade = rowMinCostValue + colMinCostValue;
}
}
}
}
public void Reduce()
{
int maxGradeValue = Int32.MinValue;
int maxGradeItemRowIndex = 0;
int maxGradeItemColIndex = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (items[i][j].Grade != -1 && items[i][j].Grade > maxGradeValue)
{
maxGradeValue = items[i][j].Grade;
maxGradeItemRowIndex = i;
maxGradeItemColIndex = j;
}
}
}
currentPartOfPath.Clear();
currentPartOfPath.Add(rowsNumbers[maxGradeItemRowIndex]);
currentPartOfPath.Add(colsNumbers[maxGradeItemColIndex]);
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
if (rowsNumbers[i] == colsNumbers[maxGradeItemColIndex] && colsNumbers[j] == rowsNumbers[maxGradeItemRowIndex])
items[i][j].Cost = -1;
for (int n = 0; n < size; n++)
items[n].RemoveAt(maxGradeItemColIndex);
items.RemoveAt(maxGradeItemRowIndex);
colsNumbers.RemoveAt(maxGradeItemColIndex);
rowsNumbers.RemoveAt(maxGradeItemRowIndex);
size--;
}
public List<int> GetCurrentPartOfPath()
{
return currentPartOfPath;
}
}
и:
public class TSPSolver
{
private CostMatrix costMatrix;
private List<List<int>> costValuesMatrix;
private List<int> minPath;
private int minPathLength;
public TSPSolver(CostMatrix _costMatrix)
{
costMatrix = _costMatrix;
costValuesMatrix = new List<List<int>>();
for (int i = 0; i < costMatrix.Size; i++)
{
costValuesMatrix.Add(new List<int>());
for (int j = 0; j < costMatrix.Size; j++)
costValuesMatrix[i].Add(costMatrix[i][j].Cost);
}
minPath = new List<int>();
minPathLength = 0;
}
private void FindMinPath()
{
while (costMatrix.Size != 0)
{
costMatrix.ReduceRowsValues();
costMatrix.ReduceColsValues();
costMatrix.CalculateGrades();
costMatrix.Reduce();
minPath.AddRange(costMatrix.GetCurrentPartOfPath());
}
}
public string GetMinPathInfo()
{
string minPathInfo = String.Empty;
List<int> path = new List<int>();
int currentVertex = 0;
FindMinPath();
path.AddRange(minPath);
minPath.Clear();
minPath.Add(path[0]);
minPath.Add(path[1]);
path.RemoveAt(0);
path.RemoveAt(0);
currentVertex = minPath[1];
while (path.Count != 0)
{
for (int i = 0; i < path.Count - 1; i += 2)
{
if (path[i] == currentVertex)
{
minPath.Add(path[i + 1]);
currentVertex = minPath[minPath.Count - 1];
path.RemoveAt(i);
path.RemoveAt(i);
break;
}
}
}
for (int i = 0; i < minPath.Count - 1; i++)
minPathLength += costValuesMatrix[minPath[i] - 1][minPath[i + 1] - 1];
minPathInfo = "Минимальный путь в заданном графе: ";
for (int i = 0; i < minPath.Count; i++)
{
if (i != minPath.Count - 1)
minPathInfo += minPath[i].ToString() + "->";
else
minPathInfo += minPath[i].ToString() + Environment.NewLine;
}
minPathInfo += "Длина найденного пути: " + minPathLength.ToString();
return minPathInfo;
}
}
Вызов: (costValuesMatrix - заполненный массив, примеры выше)
CostMatrix costMatrix = new CostMatrix(costValuesMatrix);
TSPSolver tspSolver = new TSPSolver(costMatrix);
Console.WriteLine(tspSolver.GetMinPathInfo());
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Здравствуйте, пишу класс сервера, который мог бы обрабатывать несколько подключенийДо этого никогда не писал
Делаю модуль на сайте, который выводит пользователей на сайте за последние 24 часаВключил <anonymousIdentification enabled="true" /> на сайте