/// <summary> /// Generates a random neighbour and applies it to the current state /// </summary> /// <returns>The neighbour that was applied</returns> public Neighbour <S> ApplyRandomNeighbour() { Neighbour <S> neighbour = GetRandomNeighbour(); ApplyNeighbour(neighbour); return(neighbour); }
/// <summary> /// Starts searching for an optimal solution /// </summary> /// <param name="initialState">The start state from where to search</param> /// <param name="bestStateSoFar">Reference where the result (and updates) are supposed to be stored</param> public void Search(S initialState, ref string bestStateSoFar) { S state = initialState; double bestTotalScore = initialState.Score; double previousScore = bestTotalScore; double temperature = StartTemperature; int iterations = 0; while (MaxTimeAllowed > Timer.Elapsed.TotalSeconds) { iterations++; // Get a random neighbour and apply it Neighbour <D> neighbour = state.GetRandomNeighbour(); state.ApplyNeighbour(neighbour); double newScore = state.Score; // Update the scores and best solution if necessary if (newScore <= previousScore) { if (newScore < bestTotalScore) { bestStateSoFar = state.Data.ToString(); bestTotalScore = newScore; } previousScore = newScore; } else { // There is a chance the neighbour is reverted double chance = Math.Exp((previousScore - newScore) / temperature); double random = Random.NextDouble(); if (random > chance) { state.RevertNeighbour(neighbour); } else { previousScore = newScore; } } // Reset the temperature if the threshold has been reached if (temperature < ResetTemperatureThreshold) { temperature = StartTemperature; } // Multiply the temperature if needed if (iterations % MultiplyTemperaturePerIterations == 0) { temperature *= TemperatureMultiplier; } } }
public Neighbour <RecursiveTree <Node> > GetRandomNeighbour(RecursiveTree <Node> data) { List <Neighbour <RecursiveTree <Node> > > neighbourlist = new List <Neighbour <RecursiveTree <Node> > >(); // Create a random MoveUpNeighbour Neighbour <RecursiveTree <Node> > move = MoveUpNeighbourSpace.GetRandomNeighbour(data); neighbourlist.Add(move); // Generate Splits amount of random SplitNeighbours for (int i = 0; i < Splits; i++) { Neighbour <RecursiveTree <Node> > split = SplitNeighbourSpace.GetRandomNeighbour(data); neighbourlist.Add(split); } // Return the list with the single Move and multiple SplitNeighbours return(new MultipleNeighbourNeighbour <RecursiveTree <Node> >(neighbourlist)); }
/// <summary> /// Reverts a neighbour /// </summary> /// <param name="neighbour">The neighbour to revert</param> public virtual void RevertNeighbour(Neighbour <S> neighbour) { neighbour.Revert(); //Score -= neighbour.Delta(); // TODO: use the delta again }
/// <summary> /// Applies a neighbour /// </summary> /// <param name="neighbour">The neigbour to apply</param> public virtual void ApplyNeighbour(Neighbour <S> neighbour) { neighbour.Apply(); //Score += neighbour.Delta(); // TODO: use the delta again }