Ошибка в алгоритме метод ветвей и границ

443
29 мая 2017, 22:57

Добрый день! Ошибка в алгоритме, метод ветвей и границ. На некоторых графах работает, на некоторых нет - программа зависает рабочий вариант:

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());
READ ALSO
Разделения С# скрипта

Разделения С# скрипта

Помогите пожалуйста разбить скрипт на 3 части Run, Jump и всё оставшиеся

341
Обработка MouseDown событий на тачпаде

Обработка MouseDown событий на тачпаде

Возьму некоторые обозначения прежде чем начну вопрос:

266
Использование NetworkStream.BeginRead

Использование NetworkStream.BeginRead

Здравствуйте, пишу класс сервера, который мог бы обрабатывать несколько подключенийДо этого никогда не писал

445
Как такое получается что в ASP.NET MVC AnonymousID = null

Как такое получается что в ASP.NET MVC AnonymousID = null

Делаю модуль на сайте, который выводит пользователей на сайте за последние 24 часаВключил <anonymousIdentification enabled="true" /> на сайте

227