public Multilesson(Group g, Teacher t, Subject s, IntInInterval val) { this.g = g; this.t = t; this.s = s; this.val = val; }
private DaySchedule generateDay(int day, bool isFinal) { /* * if(isFinal==true && (!(lastConfig[day] is null)) && tryConfig(lastConfig[day], day)==true) * { * System.Console.WriteLine("SKIPPPPP"); * return useConfig(lastConfig[day], day); * } */ G.reset(); // ----- setting node demands ----- G.setDemand(allTeachersNode, -(Enumerable.Range(0, groups.Count).Sum(ind => dayState[day].groupLeftLessons[ind]))); for (int g = 0; g < groups.Count; g++) { G.setDemand(groupNode[g], dayState[day].groupLeftLessons[g]); } // ----- adding edges ----- //connecting teachers to allTeachersNode for (int t = 0; t < teachers.Count; t++) { int requested = 0; for (int g = 0; g < groups.Count; g++) { foreach (int s in teacherGroup2Subjects[t, g]) { if (groups[g].subject2Teacher[s].Item2.Equals(teachers[t]) == true) { requested += dayState[day].groups[g].getSubjectWeekLim(s); } } } for (int d = day + 1; d <= workDays; d++) { requested -= dayState[d].teacherLeftLessons[t]; } int u = allTeachersNode; int v = teacherNode[t]; int l = Math.Max(requested, 0); int c = dayState[day].teacherLeftLessons[t]; //Console.WriteLine($"{teachers[t].name} -> {l} {c}"); G.addEdge(u, v, l, Math.Min(c, minLessons), true); } //connecting teachers to possible lessons for (int t = 0; t < teachers.Count; t++) { for (int g = 0; g < groups.Count; g++) { foreach (int s in teacherGroup2Subjects[t, g]) { IntInInterval scheduledLessons = new IntInInterval(0); List <Multilesson> important = multilessons[day].Where(m => m.t.Equals(teachers[t]) == true && m.g.Equals(groups[g]) == true && m.s.Equals(groups[g].subject2Teacher[s].Item1)).ToList(); foreach (Multilesson r in important) { scheduledLessons = scheduledLessons + r.val; } if (important.Count > 0) { G.addEdge(teacherNode[t], groupSubjectNode[g, s], scheduledLessons.l, scheduledLessons.r, true); } else { G.addEdge(teacherNode[t], groupSubjectNode[g, s], 0, minLessons, true); } } } } //connecting the actual higharcy structures for (int g = 0; g < groups.Count; g++) { void dfs(TreeNode x) { if (x.GetType() == typeof(SubjectTreeNode)) { int s = dayState[day].groups[g].findSubject((x as SubjectTreeNode).s); if (s == -1) { return; } if (dayState[day].groups[g].subject2Teacher[s].Item2 == null) { return; } int teacherInd = groupSubject2Teacher[g, s]; int lessonsLeft = dayState[day].groups[g].getSubjectWeekLim(s); for (int d = day + 1; d <= workDays; d++) { IEnumerable <Multilesson> important = multilessons[d].Where(m => m.g.Equals(groups[g]) == true && m.s.Equals((x as SubjectTreeNode).s) == true); int rm = 0; if (important.Any() == false) { rm = Math.Min(dayState[d].groups[g].getDayBottleneck(s), dayState[d].teacherLeftLessons[teacherInd]); rm = Math.Min(rm, dayState[d].groupLeftLessons[g]); } else { rm = important.Sum(m => m.val.r); } lessonsLeft -= rm; } int subjectLim = Math.Min(dayState[day].groups[g].getDayBottleneck(s), dayState[day].groups[g].getSubjectWeekLim(s)); int subjectDemand = 0; for (int d = day + 1; d <= workDays; d++) { subjectDemand += multilessons[d].Where(r => r.g.Equals(groups[g]) == true && r.s.Equals((x as SubjectTreeNode).s)) .Sum(r => r.val.l); } int fixatedLessons = multilessons[day].Where(r => r.g.Equals(groups[g]) == true && r.s.Equals((x as SubjectTreeNode).s)) .Sum(r => r.val.l); groupSubjectEdge[g, s] = G.addEdge(x.nodeCode, x.parent.nodeCode, Math.Max(fixatedLessons, Math.Max(0, lessonsLeft)), Math.Min(subjectLim, dayState[day].groups[g].getSubjectWeekLim(s) - subjectDemand)); return; } if (x.parent != null) { int lim = maxLessons; if (x.GetType() == typeof(LimitationTreeNode)) { lim = Math.Min(lim, dayState[day].groups[g].getLimGroupDayLim((x as LimitationTreeNode).lg)); } int lessonsLeft = groups[g].subject2Teacher.Where(t => t.Item1.limGroups.Contains((x as LimitationTreeNode).lg) == true) .Sum(t => dayState[1].groups[g].getSubjectWeekLim(groups[g].findSubject(t.Item1))); for (int d = day + 1; d <= workDays; d++) { IEnumerable <Multilesson> important = multilessons[d].Where(m => m.g.Equals(groups[g]) == true && m.s.limGroups.Contains((x as LimitationTreeNode).lg) == true); int rm = 0; if (important.Any() == false) { rm = Math.Min(dayState[d].groups[g].getLimGroupDayLim((x as LimitationTreeNode).lg), dayState[d].groupLeftLessons[g]); } else { rm = important.Sum(m => m.val.r); } lessonsLeft -= rm; } G.addEdge(x.nodeCode, x.parent.nodeCode, Math.Max(0, lessonsLeft), lim); } foreach (TreeNode y in x.children) { dfs(y); } } dfs(groupHigharchy[g]); } //connecting groups to their higharchy trees for (int g = 0; g < groups.Count; g++) { int allLeft = dayState[day].groups[g].subject2Teacher.Sum(t => dayState[day].groups[g].getSubjectWeekLim(dayState[day].groups[g].findSubject(t.Item1))); for (int d = day + 1; d <= workDays; d++) { allLeft -= dayState[d].groupLeftLessons[g]; } int fixatedLessons = multilessons[day].Where(r => r.g.Equals(groups[g]) == true).Sum(r => r.val.l); int upperBound = dayState[day].groups[g].subject2Teacher.Sum(t => dayState[day].groups[g].getSubjectWeekLim(dayState[day].groups[g].findSubject(t.Item1))); for (int d = day + 1; d <= workDays; d++) { upperBound -= Math.Min(dayState[d].groupLeftLessons[g], groups[g].minLessons); } G.addEdge(groupHigharchy[g].nodeCode, groupNode[g], Math.Max(Math.Max(groups[g].minLessons - dayState[day].groups[g].curriculum.Count, allLeft), fixatedLessons), Math.Min(dayState[day].groupLeftLessons[g], upperBound)); } //connecting groups to allTeachersNode for (int g = 0; g < groups.Count; g++) { G.addEdge(allTeachersNode, groupNode[g], 0, Math.Min(maxLessons - minLessons, maxLessons - dayState[day].groups[g].curriculum.Count)); } G.eval(); List <Tuple <int, int> >[] currConfig = new List <Tuple <int, int> > [groups.Count]; for (int g = 0; g < groups.Count; g++) { //Console.WriteLine($"---- {groups[g].name} - {g} ---"); int expectedCnt = dayState[day].groupLeftLessons[g]; List <int> teacherInds = new List <int>(); currConfig[g] = new List <Tuple <int, int> >(); for (int s = 0; s < groups[g].subject2Teacher.Count; s++) { if (groups[g].subject2Teacher[s].Item2 is null) { continue; } for (int i = 0; i < G.getEdge(groupSubjectEdge[g, s]); i++) { currConfig[g].Add(Tuple.Create(s, groupSubject2Teacher[g, s])); teacherInds.Add(groupSubject2Teacher[g, s]); //Console.WriteLine(teachers[groupSubject2Teacher[g, s]].name); if (dayState[day].updateLimits(g, s, groupSubject2Teacher[g, s], +1) == false) { Console.WriteLine($"ebalo si maikata {g}"); return(null); } } } if (dayState[day].groups[g].curriculum.Count <dayState[day].groups[g].minLessons || dayState[day].groups[g].curriculum.Count> maxLessons) { Console.WriteLine($"e de {dayState[day].groups[g].curriculum.Count} {g} || {day}"); return(null); } } Console.WriteLine("pak faida e "); DaySchedule ds = null; if (ds is null) { ScheduleCompleters.DFS.ScheduleCompleter sc = new ScheduleCompleters.DFS.ScheduleCompleter(dayState[day].groups, teachers, supergroupMultilessons[day], maxLessons); ds = sc.gen(true); if (!(ds is null)) { lastConfigSolution[day] = ds; lastConfig[day] = currConfig; } } if (ds is null) { ScheduleCompleters.GeneticAlgorithm.ScheduleCompleter sc = new ScheduleCompleters.GeneticAlgorithm.ScheduleCompleter(dayState[day].groups, teachers, supergroupMultilessons[day], maxLessons); ds = sc.gen(true); if (!(ds is null)) { lastConfigSolution[day] = ds; lastConfig[day] = currConfig; } } return(ds); }