private void appendProblems(DVRPProblemInstance instance, int i, DVRPPartialProblemInstance schema, ref List <DVRPPartialProblemInstance> partialProblemInstances) { int k = Math.Max(1, instance.VehicleNumber * (i + 1) - instance.Visits.Count); int e = instance.VehicleNumber - 1; while (k <= e) { var ignoredList = new List <int> { k }; if (k != e) { ignoredList.Add(e); } var newProblem = new DVRPPartialProblemInstance(); solutionCopyTo(schema, ref newProblem); newProblem.IgnoredSets = ignoredList.ToArray(); partialProblemInstances.Add(newProblem); k++; e--; } }
private void minimizeSolution(DVRPProblemInstance instance, ref DVRPPartialProblemInstance solution, List <int>[] currVisits) { double newCost = 0f; var newSolution = new List <int> [instance.VehicleNumber]; for (var j = 0; j < instance.VehicleNumber; j++) { newSolution[j] = new List <int>(); for (int e = 0; e < currVisits[j].Count; e++) { newSolution[j].Add(currVisits[j][e]); } var cvref = newSolution[j].ToArray(); var currCost = minimizePermutation(instance, ref cvref); if (currCost < 0f) { return; } newCost += currCost; } if (newCost < solution.PartialResult) { solution.VisitIds = new int[instance.VehicleNumber][]; for (int u = 0; u < instance.VehicleNumber; u++) { solution.VisitIds[u] = newSolution[u].ToArray(); } solution.PartialResult = newCost; solution.SolutionResult = SolutionResult.Successful; } }
private void generatePartialProblems(DVRPProblemInstance instance, int i, ref List <DVRPPartialProblemInstance> partialProblemInstances) { if (i == 0) { var schema = new DVRPPartialProblemInstance() { MinimalSetCount = 0, PartialResult = double.MaxValue, SolutionResult = SolutionResult.Impossible }; appendProblems(instance, i, schema, ref partialProblemInstances); return; } var schemas = solvePossibleMinCountSets(instance, i); foreach (var schema in schemas) { if (instance.VehicleNumber * i == instance.Visits.Count) { var partial = new DVRPPartialProblemInstance(); solutionCopyTo(schema, ref partial); partial.IgnoredSets = new[] { instance.VehicleNumber }; partialProblemInstances.Add(partial); } else { appendProblems(instance, i, schema, ref partialProblemInstances); } } }
private void solvePossibleMinCountSetsRec(DVRPProblemInstance instance, int i, int set, int j, ref List <DVRPPartialProblemInstance> solutions, List <int>[] currVisits, int[] lastIds) { if (j > i) { throw new Exception("Something went wrong"); } if (j == i) { if (set < instance.VehicleNumber - 1) { solvePossibleMinCountSetsRec(instance, i, set + 1, 0, ref solutions, currVisits, lastIds); return; } else { var newSol = new DVRPPartialProblemInstance(); newSol.PartialResult = double.MaxValue; newSol.SolutionResult = SolutionResult.Impossible; newSol.MinimalSetCount = i; //uzyskaliśmy podział, przepisanie do szkieletu zadania newSol.VisitIds = new int[currVisits.Length][]; for (var k = 0; k < currVisits.Length; k++) { newSol.VisitIds[k] = new int[currVisits[k].Count]; for (var s = 0; s < currVisits[k].Count; s++) { newSol.VisitIds[k][s] = currVisits[k][s]; } } solutions.Add(newSol); return; } } for (var k = 0; k < lastIds.Length; k++) { if (lastIds[k] != -1) { if ((set > 0 && j == 0 && currVisits[set - 1].Last() > lastIds[k]) || (!(set == 0 && j == 0) && (instance.Visits[k].Id < currVisits[0][0] || (currVisits[set].Count > 0 && currVisits[set].Last() > instance.Visits[k].Id) || (currVisits[0].Count > 0 && currVisits[0][0] > instance.Visits[k].Id)))) { continue; } var id = lastIds[k]; currVisits[set].Add(id); lastIds[k] = -1; solvePossibleMinCountSetsRec(instance, i, set, j + 1, ref solutions, currVisits, lastIds); lastIds[k] = id; currVisits[set].Remove(id); } } }
private void generateSetsRec(DVRPProblemInstance instance, ref DVRPPartialProblemInstance solution, int i, List <int>[] currVisits, int clast, int cunign, int[] unignoredSets, int[] lastIds, int minSet, int unignoredCount) { if (clast < unignoredCount - cunign) { return; } if (clast == 0 && cunign < unignoredCount) { return; } if (clast == 0) { minimizeSolution(instance, ref solution, currVisits); return; } for (var k = minSet; k < unignoredSets.Length; k++) { if (currVisits[unignoredSets[k]].Count == i && cunign == unignoredCount) { continue; } if (k > 0 && currVisits[unignoredSets[k - 1]].Count == i) { return; } for (var t = 0; t < lastIds.Length; t++) { if (lastIds[t] == -1) { continue; } if (currVisits[unignoredSets[k]].Count > i && currVisits[unignoredSets[k]].Last() > lastIds[t]) { continue; } if (k > 0 && currVisits[unignoredSets[k - 1]][0] > lastIds[t]) { break; } var add = currVisits[unignoredSets[k]].Count == i ? (byte)1 : (byte)0; currVisits[unignoredSets[k]].Add(lastIds[t]); var tmp = lastIds[t]; lastIds[t] = -1; generateSetsRec(instance, ref solution, i, currVisits, clast - 1, cunign + add, unignoredSets, lastIds, k, unignoredCount); lastIds[t] = tmp; currVisits[unignoredSets[k]].Remove(lastIds[t]); } } }
private void solveInParallel(DVRPProblemInstance instance, ref DVRPPartialProblemInstance finalSolution) { var solQueue = new ConcurrentQueue <DVRPPartialProblemInstance>(); //dwa wątki - lub jeden List <Thread> threads = new List <Thread>(); foreach (var number in finalSolution.IgnoredSets) { var currSolution = new DVRPPartialProblemInstance(); int i = finalSolution.MinimalSetCount; solutionCopyTo(finalSolution, ref currSolution); currSolution.IgnoredSets = new[] { number }; var thread = new Thread(t => { if (i == 0) { //different behaviour (generate sets in loop) solveForZero(instance, ref currSolution, number); } else if (i * instance.VehicleNumber == instance.Visits.Count) { instantMinimization(instance, ref currSolution); } //nothing to do, but generate sets: else { generateIgnoredSets(instance, ref currSolution, i, number); } solQueue.Enqueue(currSolution); }); threads.Add(thread); thread.Start(); } foreach (var thread in threads) { thread.Join(); } int k = 0; int min = 0; foreach (var sol in solQueue) { if (sol.PartialResult < finalSolution.PartialResult) { min = k; } k++; } solutionCopyTo(solQueue.ElementAt(min), ref finalSolution); }
private void solveForZeroRec(DVRPProblemInstance instance, ref DVRPPartialProblemInstance solution, List <int>[] currVisits, int[] lastIds, int i, int number, int visitsToAssign, int setsToAssign, int minSet, int assigned) { if (setsToAssign > visitsToAssign) { return; } if (visitsToAssign == 0) { minimizeSolution(instance, ref solution, currVisits); return; } for (var k = minSet; k < number; k++) { assigned = 0; if (k > 0 && currVisits[k - 1].Count == i) { return; } if (setsToAssign == visitsToAssign && currVisits[k].Count != i) { continue; } for (var t = assigned; t < lastIds.Length; t++) { if (lastIds[t] == -1) { continue; } if (currVisits[k].Count > i && currVisits[k].Last() > lastIds[t]) { continue; } if (k > 0 && currVisits[k - 1][0] > lastIds[t]) { break; } var add = currVisits[k].Count == i ? (byte)1 : (byte)0; currVisits[k].Add(lastIds[t]); var tmp = lastIds[t]; lastIds[t] = -1; solveForZeroRec(instance, ref solution, currVisits, lastIds, i, number, visitsToAssign - 1, setsToAssign - add, k, t); lastIds[t] = tmp; currVisits[k].Remove(lastIds[t]); } } }
private void instantMinimization(DVRPProblemInstance instance, ref DVRPPartialProblemInstance solution) { double newCost = 0f; for (var j = 0; j < instance.VehicleNumber; j++) { var cvref = solution.VisitIds[j]; var currCost = minimizePermutation(instance, ref cvref); if (currCost < 0f) { var s = solutionImpossible(); solutionCopyTo(s, ref solution); return; } newCost += currCost; } solution.PartialResult = newCost; solution.SolutionResult = SolutionResult.Successful; }
private void generateIgnoredSetsRec(DVRPProblemInstance instance, ref DVRPPartialProblemInstance solution, int i, int ignoredCount, int[] ignoredSets, int howmany) { if (howmany == ignoredCount) { generateSets(instance, i, ref solution, ignoredSets); } else { for (var j = 0; j < instance.VehicleNumber; j++) { if (howmany > 0 && ignoredSets[howmany - 1] > j) { return; } ignoredSets[howmany] = j; generateIgnoredSetsRec(instance, ref solution, i, ignoredCount, ignoredSets, howmany + 1); } } }
private void solutionCopyTo(DVRPPartialProblemInstance a, ref DVRPPartialProblemInstance b) { if (a.IgnoredSets != null) { b.IgnoredSets = new int[a.IgnoredSets.Length]; a.IgnoredSets.CopyTo(b.IgnoredSets, 0); } b.MinimalSetCount = a.MinimalSetCount; b.SolutionResult = a.SolutionResult; b.PartialResult = a.PartialResult; if (a.VisitIds == null) { return; } b.VisitIds = new int[a.VisitIds.GetLength(0)][]; for (int i = 0; i < a.VisitIds.GetLength(0); i++) { b.VisitIds[i] = new int[a.VisitIds[i].Length]; a.VisitIds[i].CopyTo(b.VisitIds[i], 0); } }
private void solveForZero(DVRPProblemInstance instance, ref DVRPPartialProblemInstance currSolution, int number) { var clast = instance.Visits.Count; var currVisits = new List <int> [instance.VehicleNumber]; for (int e = 0; e < instance.VehicleNumber; e++) { currVisits[e] = new List <int>(); } var lastIds = new int[instance.Visits.Count]; for (var s = 0; s < instance.Visits.Count; s++) { lastIds[s] = instance.Visits[s].Id; } solveForZeroRec(instance, ref currSolution, currVisits, lastIds, currSolution.MinimalSetCount, number, clast, number, 0, 0); }
/// <summary> /// /// </summary> /// <param name="instance">instance</param> /// <param name="i">minimal set count</param> /// <param name="solution">reference with visit ids permuted</param> /// <param name="ignoredCount">number of sets to ignore</param> private void generateSets(DVRPProblemInstance instance, int i, ref DVRPPartialProblemInstance solution, int[] ignoredSets) { //dodawaj klientów z nawrotami do zbiorów currVisits takich, że nie należą do y-greków //uważaj na powtórzenia var clast = instance.Visits.Count - i * instance.VehicleNumber; var cval = 0; var unignoredSets = Enumerable.Range(0, instance.VehicleNumber) .Where(x => !ignoredSets.Contains(x)).ToArray(); var currVisits = new List <int> [instance.VehicleNumber]; for (int e = 0; e < instance.VehicleNumber; e++) { currVisits[e] = new List <int>(); for (int f = 0; f < solution.VisitIds[e].Length; f++) { currVisits[e].Add(solution.VisitIds[e][f]); } } var lastIds = new int[instance.Visits.Count]; for (var s = 0; s < instance.Visits.Count; s++) { if (currVisits.Any(x => x.Contains(instance.Visits[s].Id))) { lastIds[s] = -1; } else { lastIds[s] = instance.Visits[s].Id; } } generateSetsRec(instance, ref solution, i, currVisits, clast, cval, unignoredSets, lastIds, 0, unignoredSets.Count()); }
private void generateIgnoredSets(DVRPProblemInstance instance, ref DVRPPartialProblemInstance solution, int i, int ignoredCount) { int[] ignoredSets = Enumerable.Repeat(-1, instance.VehicleNumber).ToArray(); generateIgnoredSetsRec(instance, ref solution, i, ignoredCount, ignoredSets, 0); }