public OutputData Solve(InputData input, Settings settings, BackgroundWorker worker) { Random rand = new Random(); OutputData result = new OutputData(); //for (int i = 0; i < 200; i++) //{ // IterationBlock block = new IterationBlock // { // ProgressionCount = rand.Next(10), // RegressionCount = rand.Next(10) // }; // for (int j = 0; j < 10; j++) // { // block.Values.Add(new Iteration(j) // { // Cost = Math.Sin(i * (double)j * 10) // }); // } // worker.ReportProgress(0, block); // result.Iterations.Add(block); // if (worker.CancellationPending == true) // { // return null; // } // System.Threading.Thread.Sleep(50); //} //result.TotalCost = 10; //result.Solution = new List<int> { 4, 5, 6, 3, 2, 1, 0, 6, 5, 4, 3, 3, 4, 234, 234, 32, 34, 4, 43, 4 }; return result; }
public OutputData Solve(InputData input, Settings settings, BackgroundWorker worker) { // TODO // Gdy problem zadany bez stacji (fuel cap = 0), to coś sie psuje OutputData result = new OutputData(); Operation operation = null; switch (settings.Operation) { case OperationType.Operation1: operation = Operation1; break; case OperationType.Operation2: operation = Operation2; break; } List<double> iterationBlockCosts = new List<double>(); double currentCost = 0; double newCost = 0; double subtract = 0; int numIterations = settings.NumIterations; double temperature = settings.StartingTemperature; List<int> currentSolution = null; List<int> currentSolutionWithPetrolPlaces = new List<int>(); if (input.FuelCapacity > 0) { int counter = 0; do { if (counter > Math.Pow(input.NumPlaces, 2)) { result.State = OutputState.NoSolution; return result; } currentSolution = GetStartingSolution(input); currentSolution.CopyListTo(currentSolutionWithPetrolPlaces); counter++; } while (!PutPetrolPlaces(input, currentSolutionWithPetrolPlaces)); } else { currentSolution = GetStartingSolution(input); currentSolution.CopyListTo(currentSolutionWithPetrolPlaces); } List<int> newSolution = new List<int>(new int[currentSolution.Count]); List<int> newSolutionWithPetrolPlaces = new List<int>(); currentSolution.CopyListTo(newSolution); int currentSolutionCountMinusOne = currentSolutionWithPetrolPlaces.Count() - 1; for (int i = 0; i < currentSolutionCountMinusOne; i++) { //CurrentCost = CurrentCost + input.Places[CurrentSolution[i]][CurrentSolution[i + 1]]; currentCost += input.Places[currentSolutionWithPetrolPlaces[i]][currentSolutionWithPetrolPlaces[i + 1]]; } while (temperature > settings.EndingTemperature) { IterationBlock block = new IterationBlock(); double minCost = currentCost, maxCost = currentCost; for (int i = 0; i < numIterations; i++) { if (input.FuelCapacity > 0) { do { operation(currentSolution, newSolution); newSolution.CopyListTo(newSolutionWithPetrolPlaces); } while (!PutPetrolPlaces(input, newSolutionWithPetrolPlaces)); } else { operation(currentSolution, newSolution); newSolution.CopyListTo(newSolutionWithPetrolPlaces); } newCost = 0; int newSolutionCountMinusOne = newSolutionWithPetrolPlaces.Count() - 1; for (int j = 0; j < newSolutionCountMinusOne; j++) { newCost += input.Places[newSolutionWithPetrolPlaces[j]][newSolutionWithPetrolPlaces[j + 1]]; } subtract = newCost - currentCost; double randomik = rand.NextDouble(); double zmienna = Math.Exp((-1) * (subtract / temperature)); if (subtract <= 0 || subtract > 0 && zmienna > randomik) { currentCost = newCost; if (currentCost > maxCost) maxCost = currentCost; else if (currentCost < minCost) minCost = currentCost; newSolution.CopyListTo(currentSolution); newSolutionWithPetrolPlaces.CopyListTo(currentSolutionWithPetrolPlaces); if (subtract <= 0) block.ProgressionCount++; else block.RegressionCount++; } //block.Values.Add(currentCost); iterationBlockCosts.Add(currentCost); if (iterationBlockCosts.Count == (int)(numIterations / settings.PointsPerIterationBlock)) { block.Values.Add(iterationBlockCosts.ReduceCollectionToValue(x => x.Average())); iterationBlockCosts.Clear(); } if (worker.CancellationPending == true) { result.State = OutputState.Cancelled; return result; } } temperature *= settings.CoolingCoefficient; block.CurrentTemperature = temperature; numIterations = (int)((double)numIterations * settings.NumIterationsMultiplier); //block.Values = iterationBlockCosts.ReduceCollection( // settings.PointsPerIterationBlock, // x => x.Average()).ToList(); block.Minimum = minCost; block.Maximum = maxCost; iterationBlockCosts.Clear(); worker.ReportProgress(0, block); result.Iterations.Add(block); } result.Solution = currentSolutionWithPetrolPlaces; result.TotalCost = currentCost; result.State = OutputState.Done; return result; }
public SolutionData(InputData input, OutputData output) { Input = input; Output = output; }
//private IEnumerable<double> ReduceCollection(IEnumerable<double> collection, int desiredCount, Func<IEnumerable<double>,double> reducer) //{ // List<double> result = new List<double>(); // int elementsPerBlock = collection.Count() / desiredCount; // int count = 0; // List<double> container = new List<double>(); // while (count < collection.Count()) // { // //double sum = 0; // int i = 0; // for (i = 0; i < elementsPerBlock && count < collection.Count(); i++, count++) // { // //sum += collection.ElementAt(count) // container.Add(collection.ElementAt(count)); // } // //result.Add(sum / (double)i); // result.Add(reducer(container)); // container.Clear(); // } // return result; //} private void PlotOutput(OutputData outputData) { for (int count = 0; count < outputData.Iterations.Count; count++) { IterationBlock iterationBlock = outputData.Iterations[count]; OxyPlot.Series.ScatterSeries costSeries = VM.GraphPlotModel.Series[0] as OxyPlot.Series.ScatterSeries; OxyPlot.Series.StairStepSeries progressionSeries = VM.GraphPlotModel.Series[1] as OxyPlot.Series.StairStepSeries; OxyPlot.Series.StairStepSeries regressionSeries = VM.GraphPlotModel.Series[2] as OxyPlot.Series.StairStepSeries; //List<double> costs = iterationBlock.Values.Select(x => x.Cost).ToList(); //List<double> reducedCosts = ReduceCollection(costs, DISPLAYED_COSTS_PER_BLOCK, x => x.Average()).ToList(); for (int i = 0; i < iterationBlock.Values.Count; i++) { costSeries.Points.Add(new ScatterPoint( /*iteration.IterationNumber*/ (double)count + (double)i / (double)iterationBlock.Values.Count, iterationBlock.Values[i], LINES_THICKNESS)); } progressionSeries.Points.Add(new ScatterPoint(count, iterationBlock.ProgressionCount)); regressionSeries.Points.Add(new ScatterPoint(count, iterationBlock.RegressionCount)); VM.TotalProgressions += iterationBlock.ProgressionCount; VM.TotalRegressions += iterationBlock.RegressionCount; } VM.GraphPlotModel.RefreshPlot(false); }