public static KnapsackConfig FixedSinglePointCrossover(KnapsackConfig sack1, KnapsackConfig sack2, bool isLeft) { int[] crossItems = new int[itemsAmount]; if (isLeft) { for (var i = 0; i < itemsAmount / 2; i++) { crossItems[i] = sack2.valueAt(i); } for (var i = itemsAmount / 2; i < itemsAmount; i++) { crossItems[i] = sack1.valueAt(i); } } else { for (var i = 0; i < itemsAmount / 2; i++) { crossItems[i] = sack1.valueAt(i); } for (var i = itemsAmount / 2; i < itemsAmount; i++) { crossItems[i] = sack2.valueAt(i); } } KnapsackConfig CrossoverResult = new KnapsackConfig(crossItems); if (!IsValid(CrossoverResult)) { CrossoverResult = MakeValid(CrossoverResult); } return(CrossoverResult); }
public static KnapsackConfig MutateHalf(KnapsackConfig sack, Random rand) { KnapsackConfig mutatedSack = new KnapsackConfig(sack); int mutationPosition = rand.Next(itemsAmount); if (rand.Next() % 2 == 0) { for (var i = 0; i < itemsAmount / 2; i++) { mutatedSack.swapValue(i); } } else { for (var i = itemsAmount / 2; i < itemsAmount; i++) { mutatedSack.swapValue(i); } } if (!IsValid(mutatedSack)) { return(MakeValid(mutatedSack)); } return(mutatedSack); }
public void MakeIteration() { if (GetKnapsackCost(configsPool[0]) == maximalKnapsackCost) { return; } List <int> positions = new List <int>(); while (positions.Count < mutationPercentage * configsInPoolAmount) { positions.Add(rand.Next(configsInPoolAmount)); positions.Distinct(); } for (int i = 0; i < configsInPoolAmount; i++) { configsPool[i] = activeMutation(configsPool[i], rand); } KnapsackConfig[] CrossoverPool = new KnapsackConfig[configsInPoolAmount * 2 - 2];//not very well, if i want to customize Crossover ,but works for (int j = 0; j < configsInPoolAmount - 1; j++) { CrossoverPool[j] = activeCrossover(configsPool[j], configsPool[j + 1], true); CrossoverPool[(CrossoverPool.Length - 1) - j] = activeCrossover(configsPool[j], configsPool[j + 1], false); } var tempConfigs = CrossoverPool .OrderByDescending(config => GetKnapsackCost(config)) .Take(Convert.ToInt32(configsInPoolAmount)) .ToArray(); configsPool = tempConfigs; var tuningCoeff = 0.01; updateConfigs(ref currentBestConfigs, tuningCoeff); updateConfigs(ref bestConfigsAllTime, tuningCoeff); }
private static KnapsackConfig MakeValid(KnapsackConfig sack) { for (var i = 0; i < sack.Length() && !IsValid(sack); i++) { sack.setValueToPassive(i); } return(sack); }
private double GetKnapsackCost(KnapsackConfig sack) { double count = 0; for (int i = 0; i < itemsAmount; i++) { if (sack.isValueActive(i)) { count += itemsCosts[i]; } } return(count); }
private void updateConfigs(ref KnapsackConfig[] currentPool, double tuningCoeff) { if (currentPool.Length >= configsPool.Length && GetKnapsackCost(currentPool[0]) * (1 - tuningCoeff) > GetKnapsackCost(configsPool[0])) { for (int i = 0; i < configsInPoolAmount; i++) { configsPool[i] = new KnapsackConfig(currentPool[i]); } return; } currentPool = currentPool .Concat(configsPool) .OrderByDescending(config => GetKnapsackCost(config)) .Distinct() .Take(bestConfigsAmount) .ToArray(); }
public static KnapsackConfig TwoPointCrossover(KnapsackConfig sack1, KnapsackConfig sack2, bool isLeft) { int firstPoint = rand.Next(itemsAmount - 1), secondPoint = rand.Next(firstPoint + 1, itemsAmount); int[] crossItems = new int[itemsAmount]; if (isLeft) { for (var i = 0; i < firstPoint; i++) { crossItems[i] = sack1.valueAt(i); } for (var i = firstPoint; i < secondPoint; i++) { crossItems[i] = sack2.valueAt(i); } for (var i = secondPoint; i < itemsAmount; i++) { crossItems[i] = sack1.valueAt(i); } } else { for (var i = 0; i < firstPoint; i++) { crossItems[i] = sack2.valueAt(i); } for (var i = firstPoint; i < secondPoint; i++) { crossItems[i] = sack1.valueAt(i); } for (var i = secondPoint; i < itemsAmount; i++) { crossItems[i] = sack2.valueAt(i); } } KnapsackConfig sack = new KnapsackConfig(crossItems); if (!IsValid(sack)) { return(MakeValid(sack)); } return(sack); }
private static bool IsValid(KnapsackConfig config) { double[] summ = new double[dimensions]; for (var i = 0; i < itemsAmount; i++) { if (config.isValueActive(i)) { for (var j = 0; j < dimensions; j++) { summ[j] += itemsSet[i, j]; if (summ[j] > restrictions[j]) { return(false); } } } //Amount of items is much bigger than number of dimensions, so we can do checks on every turn. } return(true); }
private KnapsackConfig FirstApproachGenerate() { KnapsackConfig result = new KnapsackConfig(itemsAmount); for (var i = 0; i < itemsAmount; i++) { result.setValueToActive(i); } Random rand = new Random(); while (!IsValid(result)) { int positionNumber = rand.Next(itemsAmount); while (!result.isValueActive(positionNumber)) { positionNumber = rand.Next(itemsAmount); } result.setValueToPassive(positionNumber); } return(result); }
public static KnapsackConfig SinglePointMutation(KnapsackConfig sack, Random rand) { KnapsackConfig mutatedSack = new KnapsackConfig(sack);//copy constructor int mutationPosition = rand.Next(itemsAmount); var count = 0; var iterationsToResque = 100000; while (mutatedSack.Equals(sack) && count < iterationsToResque)//TODO - not mutate empty sack { mutatedSack.swapValue(mutationPosition); if (!IsValid(mutatedSack))//somehow unrealistic { mutatedSack.swapValue(mutationPosition); mutationPosition = rand.Next(itemsAmount); } count++; } if (count == iterationsToResque) { return(MakeValid(mutatedSack)); } return(mutatedSack); }