public QuadAssignment GenerateNeighbor(ISimAnSolution baseSolution) { if (!(baseSolution is QuadAssignment qaSol)) { return(null); } // generate a copy of the existing assignment QuadAssignment neighbor = new QuadAssignment(); foreach (var item in qaSol.AssignmentSolution) { neighbor.AssignmentSolution.Add(item.Key, item.Value); } // exchange one pair of unit-location assignments int unit1 = _rnd.Next(0, QuadAssignment.MaterialFlow.GetLength(0)); int unit2 = _rnd.Next(0, QuadAssignment.MaterialFlow.GetLength(0)); int assignment1 = qaSol.AssignmentSolution[unit1]; int assignment2 = qaSol.AssignmentSolution[unit2]; neighbor.AssignmentSolution[unit1] = assignment2; neighbor.AssignmentSolution[unit2] = assignment1; // calculate objective value and return neighbor neighbor.CalculateFitness(); return(neighbor); }
public void OptimizeAssignment(double[,] materialFlow, double[,] distances) { QuadAssignment.MaterialFlow = materialFlow; QuadAssignment.Distances = distances; if (materialFlow.GetLength(0) > distances.GetLength(0)) { throw new ArgumentException($"Not enough locations to assign all units!"); } //setup the heuristic optimization SimAnHeurParams saParams = new SimAnHeurParams(defaultStepSize: 5, defaultCoolDown: 0.95, startTemp: 35); saParams.GenerateNeighborSolution = this.GenerateNeighbor; saParams.MaxIter = (int)Math.Pow(10, 4); //optimize ISimAnSolution startSolution = GenerateStartSolution(); SimAnHeuristic heuristic = new SimAnHeuristic(saParams, startSolution); SimAnOutput output = heuristic.Minimize(); Console.WriteLine("**************"); Console.WriteLine(output.ToString()); Console.WriteLine("**************"); foreach (var item in (output.BestSolution as QuadAssignment).AssignmentSolution) { Console.WriteLine($" Unit {item.Key} assigned to location {item.Value}."); } Console.WriteLine("**************"); }
internal SimAnOutput(ISimAnSolution finalSol, List <double> temperatureFitness, List <double> iterFitness, double initSolVal) { BestSolution = finalSol; TemperatureFitnessLevels = temperatureFitness; IterationFitnessLevels = iterFitness; Iterations = iterFitness.Count; InitialObjective = initSolVal; }
public SimAnOutput Minimize() { bool stop = false; _bestSolution = _startSolution; ISimAnSolution currentSolution = _startSolution; double deltaFitness, curTemp = _params.StartTemp; int iter = 0, iterCoolDown; iterCoolDown = iter + _params.CoolDownStepSize(curTemp); int accepted = 0; List <double> temperatureFitnessLevels = new List <double>(); List <double> iterationFitnessLevels = new List <double>() { currentSolution.Fitness }; while (!stop) { //generate neighbor solution ISimAnSolution neighbor = _params.GenerateNeighborSolution(currentSolution); deltaFitness = neighbor.Fitness - currentSolution.Fitness; //acceptance test if (AcceptNeighbor(deltaFitness, curTemp)) { currentSolution = neighbor; accepted += 1; } //improvement test if (currentSolution.Fitness < _bestSolution.Fitness) { _bestSolution = currentSolution; } iterationFitnessLevels.Add(currentSolution.Fitness); iter++; //cooldown by annealing schedule if (iter == iterCoolDown) { //record statistics for this temp-level (plateau) temperatureFitnessLevels.Add(_bestSolution.Fitness); //update temperature and set next cooldown iteration curTemp = _params.CoolDown(curTemp); iterCoolDown += _params.CoolDownStepSize(curTemp); //test abort criterion stop = StopSearchAfterPlateau(accepted, temperatureFitnessLevels); //reset number of accepted solutions within plateau accepted = 0; } stop = stop | iter > _params.MaxIter; } return(new SimAnOutput(_bestSolution, temperatureFitnessLevels, iterationFitnessLevels, _startSolution.Fitness)); }
public SimAnHeuristic(SimAnHeurParams p, ISimAnSolution startSol, int randomSeed = 1) { if (p == null) { throw new ArgumentNullException(nameof(p)); } if (p.CoolDown == null) { throw new ArgumentNullException(nameof(p), "CoolDown of the SimAnHeurParams is null."); } if (p.CoolDownStepSize == null) { throw new ArgumentNullException(nameof(p), "CoolDownStepSize of the SimAnHeurParams is null."); } if (p.GenerateNeighborSolution == null) { throw new ArgumentNullException(nameof(p), "GenerateNeighborSolution of the SimAnHeurParams is null."); } _params = p; _startSolution = startSol; _rnd = new Random(randomSeed); }