private bool isLocalSearchNodeStateOK(ArrayList nodesForOptimisationOfOneCourse, int workingNodeForCombination, int nodeLSLastPos, ArrayList freeTSListForCourse) { try { int newTestPos = (int)freeTSListForCourse[nodeLSLastPos]; for (int n = 0; n < workingNodeForCombination; n++) { ALessonNode alnoPrev = (ALessonNode)nodesForOptimisationOfOneCourse[n]; int previousPos = (int)freeTSListForCourse[alnoPrev.MyLSPos]; int numOfTS = NUM_OF_INCLUDED_DAYS_PER_WEEK * NUM_OF_INCLUDED_TERMS_PER_DAY; if ((previousPos % numOfTS) == (newTestPos % numOfTS)) { return(false); } } ALessonNode alno = (ALessonNode)nodesForOptimisationOfOneCourse[workingNodeForCombination]; alno.CurrPosition = newTestPos; } catch (Exception ex) { MessageBox.Show(ex.Message + "\n" + ex.Source + "\n" + ex.StackTrace + "\n" + workingNodeForCombination + "\n" + nodeLSLastPos); } return(true); }
private bool checkCanGoTogether_AC_HT_ALN(ACourse acht, ALessonNode afixedln) { bool canGoTogether = true; if (afixedln.MyACourse.MyAEduProgram == acht.MyAEduProgram) { if (acht.GroupName == null || acht.GroupName == "")//aln is not group { canGoTogether = false; } else//aln is group { if (afixedln.MyACourse.GroupName == null || afixedln.MyACourse.GroupName == "")//afixedln is not group { canGoTogether = false; } else//afixedln is group { if (afixedln.MyACourse.GroupName == acht.GroupName) { canGoTogether = false; } } } } if (canGoTogether) { if (afixedln.MyACourse.ACoursesHT.Count > 0) { foreach (ACourse ac_afixedln_ht in afixedln.MyACourse.ACoursesHT) { if (ac_afixedln_ht.MyAEduProgram == acht.MyAEduProgram) // the same edu program { if (acht.GroupName == null || acht.GroupName == "") //ac is not group { canGoTogether = false; } else//ac is group { if (ac_afixedln_ht.GroupName == null || ac_afixedln_ht.GroupName == "")//afixedln is not group { canGoTogether = false; } else//afixedln is group { if (ac_afixedln_ht.GroupName == acht.GroupName) { canGoTogether = false; } } } } } } } return(canGoTogether); }
private void setNewLocalBestSolution(ArrayList partialSolution) { for (int pos = _fixedTSCount; pos < partialSolution.Count; pos++) { ALessonNode aln = (ALessonNode)partialSolution[pos]; aln.PositionInLocalBestSolution = aln.CurrPosition; //aln.MyPredecessorInLocalBestSolution = aln.MyCurrentPredecessor; } }
private void removeUnpossibleWholeTSFromACourse(ALessonNode afixedln, bool[] acMyBoolPossTSTemp) { int tsBaseIndex = (afixedln.CurrPosition - 1) % _numOfTimeSlotsPerRoom + 1; for (int k = 0; k < _numOfRooms; k++) { int tsToRemove = k * _numOfTimeSlotsPerRoom + tsBaseIndex; acMyBoolPossTSTemp[tsToRemove - 1] = false; } }
private void setNewGlobalBestSolution(double bestLocalValue, ArrayList partialSolution) { BEST_GLOBAL_SOLUTION_VALUE = bestLocalValue; for (int pos = _fixedTSCount; pos < partialSolution.Count; pos++) { ALessonNode aln = (ALessonNode)partialSolution[pos]; aln.PositionInGlobalBestSolution = aln.PositionInLocalBestSolution; //aln.MyPredecessorInGlobalBestSolution = aln.MyPredecessorInLocalBestSolution; } }
private void resetPartialSolution(ArrayList partialSolution) { int partialSolutionCount = partialSolution.Count; for (int pos = _fixedTSCount; pos < partialSolutionCount; pos++) { ALessonNode alnreset = (ALessonNode)partialSolution[pos]; alnreset.CurrPosition = 0; } int removeCount = partialSolution.Count - _fixedTSCount; partialSolution.RemoveRange(_fixedTSCount, removeCount); }
private double doPartialOptmisation(double bestLocalValue, ArrayList theSolution, int theSolutionCount) { try { ArrayList theSolutionCopy = new ArrayList(); foreach (ALessonNode aln in theSolution) { aln.CurrPosition = aln.PositionInLocalBestSolution; theSolutionCopy.Add(aln); } ArrayList coursesForLSOptimisationList = new ArrayList(); //int randNumOfCourses = (int)_randomObj.Next(1, 3); int randNumOfCourses = 1; //temp //Console.WriteLine("BROJ PREDMETA: "+randNumOfCourses); int cNumTotal = randNumOfCourses; //!? int cNum = 0; //double rand = _randomObj.Next(0, 1000); //rand = rand / 1000; //if (rand < 0.5) { while (true) { int m = theSolutionCount - _fixedTSCount; int randValue = (int)_randomObj.Next(0, m); int alnIndexForMove = _fixedTSCount + randValue; ALessonNode alnInMove = (ALessonNode)theSolutionCopy[alnIndexForMove]; ACourse aCourse = (ACourse)alnInMove.MyACourse; if (!coursesForLSOptimisationList.Contains(aCourse)) { coursesForLSOptimisationList.Add(aCourse); cNum++; if (cNum == cNumTotal) { break; } } } } /*else * { * ArrayList testCList = new ArrayList(); * double maxLSVal = 0; * ACourse maxCourse = null; * foreach (ACourse testCourse in _allACourses) * { * testCList.Clear(); * testCList.Add(testCourse); * double testLSSolutionValue = this.calculateLSLocalSolutionValue(testCList); * if (testLSSolutionValue >= maxLSVal) * { * maxLSVal = testLSSolutionValue; * maxCourse = testCourse; * } * * } * * coursesForLSOptimisationList.Add(maxCourse); * }*/ double startLSLocalSolutionValue = this.calculateLSLocalSolutionValue(coursesForLSOptimisationList); double bestLSLocalSolutionValue = startLSLocalSolutionValue; if (bestLSLocalSolutionValue > 0) { int coursesInOptCount = coursesForLSOptimisationList.Count; object[] boolCoursePossTSAtStart = new object[coursesInOptCount]; foreach (ACourse aCourseInLS in coursesForLSOptimisationList) { foreach (ALessonNode alnor in aCourseInLS.MyAllLessonNodesForAllocation) { theSolutionCopy.Remove(alnor); } } int currCourseIndex = 0; bool[] acMyBoolPossTSAtStart = null; foreach (ACourse aCourseInLS in coursesForLSOptimisationList) { acMyBoolPossTSAtStart = (bool[])aCourseInLS.MyBoolPosTS.Clone(); this.filterMeRegardingCurrentPartialSolution(aCourseInLS, theSolutionCopy, acMyBoolPossTSAtStart); boolCoursePossTSAtStart[currCourseIndex] = acMyBoolPossTSAtStart; currCourseIndex++; } currCourseIndex = 0; ArrayList smallPartSolution = new ArrayList(); ArrayList freeTSListCourseFirstVisit = new ArrayList(); ArrayList[] courseFreeTSList = new ArrayList[coursesInOptCount]; bool isCourseBacktracking = false; while (true)//START of BIG loop { ACourse aCourseInLS = (ACourse)coursesForLSOptimisationList[currCourseIndex]; ArrayList nodesForOptimisationOfOneCourse = new ArrayList(); foreach (ALessonNode alno in aCourseInLS.MyAllLessonNodesForAllocation) { nodesForOptimisationOfOneCourse.Add(alno); } ArrayList freeTSListForCourse; int nodesForOptimisationOfOneCourseCount = nodesForOptimisationOfOneCourse.Count; int freeTSListForCourseCount; int workingNodeForCombination; if (isCourseBacktracking) { workingNodeForCombination = nodesForOptimisationOfOneCourseCount - 1; freeTSListForCourse = courseFreeTSList[currCourseIndex]; isCourseBacktracking = false; } else { //CLONE()??? bool[] acMyBoolPossTSTempTT2 = (bool[])boolCoursePossTSAtStart[currCourseIndex];//???? bool[] acMyBoolPossTSTemp = new bool[acMyBoolPossTSTempTT2.GetLength(0)]; int q = 0; foreach (bool bl in acMyBoolPossTSTempTT2) { acMyBoolPossTSTemp[q] = bl; q++; } if (currCourseIndex > 0) { this.filterMeRegardingCurrentPartialSolution(aCourseInLS, smallPartSolution, acMyBoolPossTSTemp); } freeTSListForCourse = new ArrayList(); int ts = 1; foreach (bool possTS in acMyBoolPossTSTemp) { if (possTS) { freeTSListForCourse.Add(ts); } ts++; } this.resetLSCourseNodesPositions(aCourseInLS); courseFreeTSList[currCourseIndex] = freeTSListForCourse; workingNodeForCombination = 0; } freeTSListForCourseCount = freeTSListForCourse.Count; while (true)//start of SMALL lop (inside nodes of one course) { ALessonNode alno = (ALessonNode)nodesForOptimisationOfOneCourse[workingNodeForCombination]; alno.MyLSPos++; if (alno.MyLSPos > (freeTSListForCourseCount - 1)) //exit from list of possible TS { if (workingNodeForCombination > 0) //backtracking { workingNodeForCombination--; } else//prvi node od predmeta { if (currCourseIndex == 0) { //calculateCurrentFULLSolutionValue //return from COMPLETE method foreach (ACourse theC in coursesForLSOptimisationList) { foreach (ALessonNode aln in theC.MyAllLessonNodesForAllocation) { aln.CurrPosition = aln.PositionInLocalBestSolution; //aln.PositionInLocalBestSolution = aln.CurrPosition; theSolutionCopy.Add(aln); } } double currSolutionValue = this.calculateCurrentSolutionValue(theSolutionCopy); if (currSolutionValue < bestLocalValue) { bestLocalValue = currSolutionValue; } return(bestLocalValue); } else { currCourseIndex--; isCourseBacktracking = true; break; } } } else//ok { if (isLocalSearchNodeStateOK(nodesForOptimisationOfOneCourse, workingNodeForCombination, alno.MyLSPos, freeTSListForCourse)) { if (workingNodeForCombination == nodesForOptimisationOfOneCourseCount - 1)//ZADNJI NODE { foreach (ALessonNode aln5 in nodesForOptimisationOfOneCourse) { smallPartSolution.Add(aln5); } if (currCourseIndex == (coursesInOptCount - 1))//last course { //have new combination //check ls solution value double lsSolutionValue = this.calculateLSLocalSolutionValue(coursesForLSOptimisationList); if (lsSolutionValue < bestLSLocalSolutionValue) { bestLSLocalSolutionValue = lsSolutionValue; foreach (ACourse theC in coursesForLSOptimisationList) { foreach (ALessonNode aln in theC.MyAllLessonNodesForAllocation) { aln.PositionInLocalBestSolution = aln.CurrPosition; } } if (lsSolutionValue == 0) { foreach (ALessonNode aln1 in smallPartSolution) { theSolutionCopy.Add(aln1); } foreach (ALessonNode aln2 in smallPartSolution) { theSolutionCopy.Remove(aln2); } smallPartSolution.Clear(); return(bestLocalValue - (startLSLocalSolutionValue - bestLSLocalSolutionValue)); } } else { smallPartSolution.Clear(); } } else { currCourseIndex++; break; } } else//not last node { ALessonNode alnoNext = (ALessonNode)nodesForOptimisationOfOneCourse[workingNodeForCombination + 1]; alnoNext.MyLSPos = alno.MyLSPos; workingNodeForCombination++; } } } } //end of small loop } //END of BIG loop } else { //Console.WriteLine("It's already zero"); } }catch (Exception ex) { MessageBox.Show(ex.Message + "\n" + ex.Source + "\n" + ex.StackTrace); } return(bestLocalValue); }
public void findBestSolution(BackgroundWorker worker, DoWorkEventArgs e) { BEST_GLOBAL_SOLUTION_VALUE = 1000000; double bestLocalValue = 1000000; DateTime startTime = DateTime.Now; //Console.WriteLine(startTime); //Console.WriteLine(startTime.Add(new TimeSpan(0, _timeSpanMin,0))); ArrayList partialSolution = _allFixedTS; _fixedTSCount = partialSolution.Count; _solutionFoundTotalCounter = 0; int pheromoneUpdateStepCounter = 0; for (int kk = 0; kk < 500000; kk++) { if (worker.CancellationPending) { e.Cancel = true; } else { /*if(DateTime.Now>startTime.Add(new TimeSpan(0, 0, _timeSpanMin))){ * break; * }*/ foreach (ACourse ac in _allACourses) { if (!ac.IsHTCourse) { if (ac.NumOfLessonNodesForAllocation > 0) { bool[] acMyBoolPossTSTemp = (bool[])ac.MyBoolPosTS.Clone(); this.filterMeRegardingCurrentPartialSolution(ac, partialSolution, acMyBoolPossTSTemp); foreach (ALessonNode aln in ac.MyAllLessonNodesForAllocation) { if (getNumOfPossTS(acMyBoolPossTSTemp) > 0) { int newNodePos = aln.selectNewTimeSlot(partialSolution, acMyBoolPossTSTemp, _randomObj); aln.CurrPosition = newNodePos; partialSolution.Add(aln); this.removeUnpossibleWholeTSFromACourse(aln, acMyBoolPossTSTemp); } else { this.resetPartialSolution(partialSolution); goto exitloop; } } } } }//end of _allCourses loop _solutionFoundTotalCounter++; pheromoneUpdateStepCounter++; double currSolutionValue = this.calculateCurrentSolutionValue(partialSolution); if (currSolutionValue < bestLocalValue) { bestLocalValue = currSolutionValue; this.setNewLocalBestSolution(partialSolution); } // } //// exitloop: if (pheromoneUpdateStepCounter == PHEROMONE_UPDATE_STEP) { //local search //Console.WriteLine("Local best BEFORE locale search: " + bestLocalValue); double lsBestLocalValue = this.doLocalSearch(worker, e, bestLocalValue, partialSolution); //Console.WriteLine("Local best AFTER locale search: " + lsBestLocalValue); //if (bestLocalValue != lsBestLocalValue) Console.WriteLine("Optimised - improved for: " + (bestLocalValue-lsBestLocalValue)); bestLocalValue = lsBestLocalValue;///!!! //if (bestLocalValue!=100) Console.WriteLine("Local best AFTER locale search: " + bestLocalValue); // //choose how to make pheromone update double probabilityForUpdateWithLocalBest = _gama * (System.Convert.ToDouble(bestLocalValue) / System.Convert.ToDouble(BEST_GLOBAL_SOLUTION_VALUE)); double randValue = _randomObj.Next(0, 1000); randValue = randValue / 1000; //Console.WriteLine(probabilityForUpdateWithLocalBest); if (randValue < probabilityForUpdateWithLocalBest) { //Console.WriteLine("GLOBAL best=" + BEST_GLOBAL_SOLUTION_VALUE + " LOCAL best" + bestLocalValue + " Update with best LOCAL: probForLocal=" + probabilityForUpdateWithLocalBest + " random=" + randValue); //update pheromone tables with local best solution //Console.WriteLine("update LOCAL BEST"); for (int pos = _fixedTSCount; pos < partialSolution.Count; pos++) { ALessonNode aln = (ALessonNode)partialSolution[pos]; //aln.updatePheromoneTable(aln.PositionInLocalBestSolution,false,(double) (100 / bestLocalValue)); double updVal = Math.Abs(50 * (1.2 - (bestLocalValue / BEST_GLOBAL_SOLUTION_VALUE))); aln.updatePheromoneTable(aln.PositionInLocalBestSolution, false, updVal); } } else { //Console.WriteLine("GLOBAL best=" + BEST_GLOBAL_SOLUTION_VALUE + " LOCAL best" + bestLocalValue + " Update with best GLOBAL: probForLocal=" + probabilityForUpdateWithLocalBest + " random=" + randValue); //update pheromone tables with GLOBAL BEST solution //Console.WriteLine("update GLOBAL BEST"); for (int pos = _fixedTSCount; pos < partialSolution.Count; pos++) { ALessonNode aln = (ALessonNode)partialSolution[pos]; //aln.updatePheromoneTable(aln.PositionInGlobalBestSolution, true, (double)(100 / BEST_GLOBAL_SOLUTION_VALUE)); double updVal = Math.Abs(50 * (1.2 - (bestLocalValue / BEST_GLOBAL_SOLUTION_VALUE))); aln.updatePheromoneTable(aln.PositionInGlobalBestSolution, true, updVal); } } //Console.WriteLine(bestLocalValue + " " + BEST_GLOBAL_SOLUTION_VALUE); if (bestLocalValue < BEST_GLOBAL_SOLUTION_VALUE) { this.setNewGlobalBestSolution(bestLocalValue, partialSolution); BGSV_CHANGE_COUNTER = 0; } else { BGSV_CHANGE_COUNTER++; } pheromoneUpdateStepCounter = 0; bestLocalValue = 1000000; double[] s = new double[2]; s[0] = _solutionFoundTotalCounter; s[1] = BEST_GLOBAL_SOLUTION_VALUE; worker.ReportProgress(10, s); if (BEST_GLOBAL_SOLUTION_VALUE == 0) { break; } //Console.WriteLine(BEST_GLOBAL_SOLUTION_VALUE); } this.resetPartialSolution(partialSolution); } if (_solutionFoundTotalCounter == 0) { MessageBox.Show("Извините, но решение не найдено"); } else { //MessageBox.Show("At least one feasible solution found"); } }