public static void Run() { lock (uiLock) { stop = false; } _minScore = Int32.MaxValue; _solutions.Clear(); _noEvaluated = 0; noParSess = Convert.ToInt32(_parent.NoParSess); noSessBlocks = Convert.ToInt32(_parent.NoSessBlocks); if (_initMeetings.Count > noSessBlocks * noParSess) { MessageBox.Show("More sessions than slots. Abort."); return; } _d = new MainUI.ProgressDelegate(_parent.UpdateProgress); Schedule emptySched = new Schedule(noParSess, noSessBlocks); bool earlyStop = false; // int total = BuildAndEvalSchedule(_initMeetings.Count, emptySched, ref _minScore, true, ref earlyStop); _d.BeginInvoke("Calculating number of candidate schedules...", 0M, null, null); _numC = ScheduleEngine.CalculateNoCombis(_initMeetings.Count, noParSess, noSessBlocks); _minScore = Int32.MaxValue; emptySched = new Schedule(noParSess, noSessBlocks); BuildAndEvalSchedule(_initMeetings.Count, emptySched, ref _minScore, false, ref earlyStop); _d.BeginInvoke(String.Format("{0} schedules evaluated. Lowest penalty: {1}", _noEvaluated, _minScore), 100M * (decimal)_noEvaluated / _numC, null, null); _parent.Callback(null); }
public static void Run_oud() { facAll = Faculteit(_parent.LVMeetings.Items.Count); _minScore = Int32.MaxValue; _solutions.Clear(); noParSess = Convert.ToInt32(_parent.NoParSess); noSessBlocks = Convert.ToInt32(_parent.NoSessBlocks); if (_parent.LVMeetings.Items.Count > noSessBlocks * noParSess) { MessageBox.Show("More sessions than slots. Abort."); return; } _d = new MainUI.ProgressDelegate(_parent.UpdateProgress); _d.BeginInvoke("begin", 0.0M, null, null); List <Schedule> allPerms = BuildPermutations(_initMeetings); _d.BeginInvoke("midden", 50.0M, null, null); FinishPermutations(ref allPerms); System.Diagnostics.Trace.WriteLine("we have " + allPerms.Count + " sessions"); int pi = 0, pN = allPerms.Count; foreach (Schedule pSchedule in allPerms) { int score = pSchedule.Evaluate(_penalties); if (score < _minScore) { _minScore = score; _solutions.Clear(); } if (score == _minScore) { _solutions.Add(pSchedule); } if (pi % 5000 == 0) { _d.BeginInvoke("eval", 50M + (decimal)pi * 50M / pN, null, null); } pi++; } _parent.Callback(null); _d.BeginInvoke("eind", 100.0M, null, null); }
private static int BuildAndEvalSchedule(int level, Schedule s, ref int bestScore, bool countrun, ref bool earlyStop) { if (earlyStop) { return(0); } if (level == 0) { if (_noEvaluated % 5000 == 0) { lock (uiLock) { earlyStop = stop; } } if (!countrun) { Meeting emptyMeeting = new Meeting(new MeetingSpec("<empty slot>")); for (int i = 0; i < noSessBlocks; i++) { for (int j = s.Meetings[i].Count; j < noParSess; j++) { s.Meetings[i].Add(emptyMeeting); } } int score = s.Evaluate(_penalties); if (score < bestScore) { _solutions.Clear(); bestScore = score; } _noEvaluated++; if (_noEvaluated % 5000 == 0) { _d.BeginInvoke(String.Format("{0} of {1} possible schedules evaluated, current lowest penalty: {2}", _noEvaluated, _numC, _minScore), 100M * (decimal)_noEvaluated / _numC, null, null); } if (score <= bestScore && _solutions.Count < 128) { _solutions.Add(s); } } return(1); } else { SortedDictionary <int, List <int> > cnt2idx = new SortedDictionary <int, List <int> >(); bool seen0 = false; for (int i = 0; !seen0 && i < noSessBlocks; i++) { int cnt = s.Meetings[i].Count; if (!cnt2idx.ContainsKey(cnt)) { cnt2idx.Add(cnt, new List <int>()); } cnt2idx[cnt].Add(i); seen0 = (cnt == 0); } int runs = 0; foreach (int cnt in cnt2idx.Keys) { foreach (int i in cnt2idx[cnt]) { if (s.Meetings[i].Count < noParSess) { Schedule s2 = s.Clone(); s2.Meetings[i].Add(new Meeting(_initMeetings[level - 1])); runs += BuildAndEvalSchedule(level - 1, s2, ref bestScore, countrun, ref earlyStop); } } } if (countrun && level > 10) { _d.BeginInvoke(String.Format("Counting. Level {0} counted {1} schedules", level, runs), 0M, null, null); } return(runs); } }