private void LogDistancesForSolution(SA_Solution solution)
 {
     for (int i = 1; i < solution.Permutation.Count; i++)
     {
         _loggerFile.WriteLine($"{ solution.Permutation[i - 1] } -> { solution.Permutation[i] }: { _distanceMatrix[solution.Permutation[i - 1], solution.Permutation[i]] }");
     }
 }
        private void confirmCalulation_Click(object sender, RoutedEventArgs e)
        {
            this._distanceMatrix = MapDataSource.DistanceMatrix.Matrix;

            if (tempValue.Value != null && maxIterationsValue.Value != null && tempDecresasingValue.Value != null && algorithmRepetitionValue.Value != null)
            {
                double?initTemp = tempValue.Value;
                double?tempDecreasingCoefficient        = tempDecresasingValue.Value;
                long?  maxRepetitionsWithoutImprovement = maxIterationsValue.Value;
                long?  algorithmRepetitions             = algorithmRepetitionValue.Value;

                resultView.Text = "(calculating)";
                resultView.InvalidateVisual();

                ClearLogger();

                _solution = RunMultipleTimes(initTemp, tempDecreasingCoefficient, maxRepetitionsWithoutImprovement, algorithmRepetitions);
                double result = _solution.FunctionValue(_distanceMatrix);
                viewMapButton.IsEnabled = true;
                resultView.Text         = result.ToString() + " km";
                resultView.InvalidateVisual();
            }
            else
            {
                resultView.Text = "Uzupełnij dane";
            }
        }
        private SA_Solution RunMultipleTimes(double?initTemp, double?tempDecreasingCoefficient, long?maxRepetitionsWithoutImprovement, long?algorithmRepetitions)
        {
            SA_Solution bestSolution = Run(initTemp, tempDecreasingCoefficient, maxRepetitionsWithoutImprovement);

            for (int i = 0; i < algorithmRepetitions - 1; ++i)
            {
                SA_Solution solution = Run(initTemp, tempDecreasingCoefficient, maxRepetitionsWithoutImprovement);
                if (solution.FunctionValue(_distanceMatrix) < bestSolution.FunctionValue(_distanceMatrix))
                {
                    bestSolution = solution;
                }
            }
            return(bestSolution);
        }
        private SA_Solution Run(double?initTemp, double?tempDecreasingCoefficient, long?maxRepetitionsWithoutImprovement)
        {
            Random random = new Random();

            SA_Solution initSolution = new SA_Solution(_distanceMatrix.GetLength(0), true, random);
            SA_Solution oldSolution  = initSolution;
            SA_Solution bestSolution = new SA_Solution(initSolution.Clone());

            double?temp      = initTemp;
            double oldResult = 0;
            double newResult = 0;

            int repetitionsWithoutImprovement = 0;

            while (repetitionsWithoutImprovement < maxRepetitionsWithoutImprovement)
            {
                SA_Solution newSolution = oldSolution.CreateNewSolutionWithSwappedTwoElements(random);
                oldResult = oldSolution.FunctionValue(_distanceMatrix);
                newResult = newSolution.FunctionValue(_distanceMatrix);

                if (newResult < bestSolution.FunctionValue(_distanceMatrix))
                {
                    bestSolution = newSolution;
                }

                if (newResult < oldResult)
                {
                    oldSolution = newSolution;
                    repetitionsWithoutImprovement = 0;
                }
                else if (random.NextDouble() < CalculateProbability(oldResult, newResult, temp))
                {
                    oldSolution = newSolution;
                    repetitionsWithoutImprovement++;
                }
                else
                {
                    repetitionsWithoutImprovement++;
                }
                temp *= tempDecreasingCoefficient;
            }

            PrepareLogger();
            _loggerFile.WriteLine("");
            LogPermutation(bestSolution.Permutation, bestSolution.FunctionValue(_distanceMatrix));
            LogDistancesForSolution(bestSolution);
            FinalizeLogger();

            return(bestSolution);
        }