/// <summary> /// Gets neighboured solutions from a given solution /// </summary> /// <param name="a_currentSolution">Solution to get neighboured solutions</param> /// <returns>Neighboured solutions</returns> public List <ISolution> GetNeighbourhood(ISolution a_currentSolution) { List <ISolution> neighbours = new List <ISolution>(); List <Box> possibleBoxes = Boxes; for (int i = 0; i < NEIGHBOUR_NUMBER; i++) { KnapSackSolution newSolution = new KnapSackSolution((KnapSackSolution)a_currentSolution); int index = randomGenerator.Next(0, newSolution.LoadedContent.Count); newSolution.LoadedContent.RemoveAt(index); double enableSpace = MaxWeight - newSolution.Weight; List <Box> availableBoxes = possibleBoxes.Except(newSolution.LoadedContent).Where(x => x.Weight <= enableSpace).ToList(); while (enableSpace > 0 && availableBoxes.Count != 0) { index = randomGenerator.Next(0, availableBoxes.Count); newSolution.LoadedContent.Add(availableBoxes.ElementAt(index)); enableSpace = MaxWeight - newSolution.Weight; availableBoxes = possibleBoxes.Except(newSolution.LoadedContent).Where(x => x.Weight <= enableSpace).ToList(); } neighbours.Add(newSolution); } return(neighbours); }
/// <summary> /// Adds a random box from bestActualSolution to the given solution /// </summary> /// <param name="a_solution">Solution to modify</param> protected void AddElementFromBestActualSolution(KnapSackSolution a_solution) { int index = KnapSackProblem.randomGenerator.Next(0, ((KnapSackSolution)bestActualSolution).LoadedContent.Count); Box element = ((KnapSackSolution)bestActualSolution).LoadedContent.ElementAt(index); if (!a_solution.LoadedContent.Contains(element)) { a_solution.LoadedContent.Add(element); } }
/// <summary> /// Adds random boxes to the given solution until max weight /// </summary> /// <param name="a_possibleBoxes">Possible boxes to add0/param> /// <param name="a_solution">Solution to modify</param> protected void AddElementsUntilMaxWeight(List <Box> a_possibleBoxes, KnapSackSolution a_solution) { double enableSpace = ((KnapSackProblem)problem).MaxWeight - a_solution.Weight; List <Box> availableBoxes = a_possibleBoxes.Except(a_solution.LoadedContent).Where(x => x.Weight <= enableSpace).ToList(); while (enableSpace > 0 && availableBoxes.Count != 0) { int index = KnapSackProblem.randomGenerator.Next(0, availableBoxes.Count); a_solution.LoadedContent.Add(availableBoxes.ElementAt(index)); enableSpace = ((KnapSackProblem)problem).MaxWeight - a_solution.Weight; availableBoxes = a_possibleBoxes.Except(a_solution.LoadedContent).Where(x => x.Weight <= enableSpace).ToList(); } }
// METHODES /// <summary> /// Constructs the solution element by element /// </summary> protected override void ConstructSolution() { KnapSackProblem pb = (KnapSackProblem)problem; List <Box> boxes = pb.Boxes; solution = new KnapSackSolution(); foreach (Box currentBox in boxes.OrderByDescending(x => x.Value / x.Weight)) { double spaceLeft = pb.MaxWeight - solution.Weight; if (currentBox.Weight < spaceLeft) { solution.LoadedContent.Add(currentBox); } } }
/// <summary> /// Gets a random solution to initialize the optimization problem /// </summary> /// <returns>Random solution</returns> public ISolution GetRandomSolution() { KnapSackSolution solution = new KnapSackSolution(); List <Box> possibleBoxes = Boxes; double enableSpace = MaxWeight; List <Box> availableBoxes = possibleBoxes.Where(x => x.Weight <= enableSpace).ToList(); while (enableSpace > 0 && availableBoxes.Count != 0) { int index = randomGenerator.Next(0, availableBoxes.Count); solution.LoadedContent.Add(availableBoxes.ElementAt(index)); enableSpace = MaxWeight - solution.Weight; availableBoxes = possibleBoxes.Except(solution.LoadedContent).Where(x => x.Weight <= enableSpace).ToList(); } return(solution); }
/// <summary> /// Compares 2 KnapSackSolution objects, they are equals if they have same content and thus same weight and value /// </summary> /// <param name="obj">KnapSackSolution object to compare</param> /// <returns>Comparaison result</returns> public override bool Equals(object obj) { KnapSackSolution solution = (KnapSackSolution)obj; if (solution.LoadedContent.Count != loadedContent.Count || solution.Value != Value || solution.Weight != Weight) { return(false); } else { foreach (Box box in loadedContent) { if (!solution.LoadedContent.Contains(box)) { return(false); } } } return(true); }
/// <summary> /// Updates the solutions if better solutions were found /// </summary> protected override void UpdateSolutions() { List <Box> possibleBoxes = ((KnapSackProblem)problem).Boxes; foreach (ISolution genericSolution in currentSolutions) { KnapSackSolution solution = (KnapSackSolution)genericSolution; if (!solution.Equals(bestSoFarSolution)) { AddElementFromBestActualSolution(solution); AddElementFromBestSoFarSolution(solution); while (solution.Weight > ((KnapSackProblem)problem).MaxWeight) { RemoveElement(solution); } AddElementsUntilMaxWeight(possibleBoxes, solution); } } }
/// <summary> /// Creates an instance of the KnapSackSolution class with an existing KnapSackSolution instance /// </summary> /// <param name="a_solution">KnapSackSolution instance</param> public KnapSackSolution(KnapSackSolution a_solution) { loadedContent = new List <Box>(); loadedContent.AddRange(a_solution.LoadedContent); }
/// <summary> /// Removes a random box from the given solution /// </summary> /// <param name="a_solution">Solution to modify</param> protected void RemoveElement(KnapSackSolution a_solution) { int index = KnapSackProblem.randomGenerator.Next(0, a_solution.LoadedContent.Count); a_solution.LoadedContent.RemoveAt(index); }