private void CopyData() { newStudentActivityGroups = new Dictionary <Tuple <ulong, ulong>, ulong>(); newStudentGroups = new Dictionary <ulong, List <ulong> >(); newLimits = new Dictionary <ulong, int[]>(); newStudentStates = new List <StudentCurrentState>(); newStudentSwaps = new Dictionary <ulong, int[]>(); foreach (var state in Container.NewStudentStates) { StudentCurrentState state_ = new StudentCurrentState(state.StudentId, state.ActivityId, state.SwapWeight, state.CurrentGroupId, state.NewGroupId, state.SwapCnt); newStudentStates.Add(state_); } foreach (var group in Container.StudentActivityGroups) { newStudentActivityGroups[Tuple.Create(group.Key.Item1, group.Key.Item2)] = group.Value; } foreach (var group in Container.StudentGroups) { newStudentGroups[group.Key] = group.Value; } foreach (var limit in Container.Limits) { newLimits[limit.Key] = limit.Value; } foreach (var swap in Container.StudentSwaps) { newStudentSwaps[swap.Key] = swap.Value; } }
public void MakeNewStudentStates(List <StudentCurrentState> _studentStates) { var _newStudentStates = new List <StudentCurrentState>(); foreach (var state in _studentStates) { if (state.SwapCnt > 0 && state.NewGroupId != 0) { StudentCurrentState newState = new StudentCurrentState(state.StudentId, state.ActivityId, state.SwapWeight, state.NewGroupId, 0, state.SwapCnt); _newStudentStates.Add(newState); } else { _newStudentStates.Add(state); } } Container.NewStudentStates = _newStudentStates; }
static void Main(string[] args) { //initial settings int timeout = 3600; int greedyTimeout = 15; string awardActivity = "1,2,4"; int awardStudent = 1; int minMaxPenalty = 1; string studentsFileName = @"C:\Instances\1\student[1].csv"; string requestsFileName = @"C:\Instances\1\requests[1].csv"; string overlapsFileName = @"C:\Instances\1\overlaps[1].csv"; string limitsFileName = @"C:\Instances\1\limits[1].csv"; for (var i = 0; i < args.Length - 1; ++i) { switch (args[i]) { case "-timeout": timeout = int.Parse(args[++i]); break; case "-award-activity": awardActivity = args[++i]; break; case "-award-student": awardStudent = int.Parse(args[++i]); break; case "-minmax-penalty": minMaxPenalty = int.Parse(args[++i]); break; case "-students-file": studentsFileName = args[++i]; break; case "-requests-file": requestsFileName = args[++i]; break; case "-overlaps-file": overlapsFileName = args[++i]; break; case "-limits-file": limitsFileName = args[++i]; break; default: Console.WriteLine("Please enter valid number of arguments."); return; } } Stopwatch sw = new Stopwatch(); sw.Start(); using (var reader = new StreamReader(studentsFileName)) { var headerLine = reader.ReadLine(); List <StudentCurrentState> _studentStates = new List <StudentCurrentState>(); Dictionary <ulong, List <ulong> > _studentGroups = new Dictionary <ulong, List <ulong> >(); Dictionary <Tuple <ulong, ulong>, ulong> _studentActivityGroups = new Dictionary <Tuple <ulong, ulong>, ulong>(); while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); List <int> attributes = new List <int>(); foreach (var value in values) { if (int.TryParse(value, out var num) == false) { Console.WriteLine("Error while reading Student File."); return; } else { attributes.Add(num); } } StudentCurrentState studentState = new StudentCurrentState((ulong)attributes[0], (ulong)attributes[1], attributes[2], (ulong)attributes[3], (ulong)attributes[4]); _studentStates.Add(studentState); if (_studentGroups.ContainsKey((ulong)attributes[0])) { _studentGroups[(ulong)attributes[0]].Add((ulong)attributes[(3)]); } else { _studentGroups[(ulong)attributes[0]] = new List <ulong> { (ulong)attributes[(3)] }; } _studentActivityGroups[Tuple.Create((ulong)attributes[0], (ulong)attributes[1])] = (ulong)attributes[3]; } Container.StudentStates = _studentStates; Container.StudentGroups = _studentGroups; Container.StudentActivityGroups = _studentActivityGroups; } using (var reader = new StreamReader(requestsFileName)) { var headerLine = reader.ReadLine(); List <Request> _requests = new List <Request>(); Dictionary <ulong, int[]> _groupRequests = new Dictionary <ulong, int[]>(); Dictionary <Tuple <ulong, ulong>, List <ulong> > _studentActivityRequestedGroups = new Dictionary <Tuple <ulong, ulong>, List <ulong> >(); while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); List <int> attributes = new List <int>(); foreach (var value in values) { if (int.TryParse(value, out var num) == false) { Console.WriteLine("Error while reading Requests File."); return; } else { attributes.Add(num); } } if (Container.StudentActivityGroups.ContainsKey(Tuple.Create((ulong)attributes[0], (ulong)attributes[1]))) { Request request = new Request((ulong)attributes[0], (ulong)attributes[1], (ulong)attributes[2]); _requests.Add(request); if (_groupRequests.ContainsKey((ulong)attributes[2])) { _groupRequests[(ulong)attributes[2]][0] += 1; } else { _groupRequests[(ulong)attributes[2]] = new int[] { 1, 0 }; } if (_studentActivityRequestedGroups.ContainsKey(Tuple.Create((ulong)attributes[0], (ulong)attributes[1]))) { _studentActivityRequestedGroups[Tuple.Create((ulong)attributes[0], (ulong)attributes[1])].Add((ulong)attributes[2]); } else { _studentActivityRequestedGroups[Tuple.Create((ulong)attributes[0], (ulong)attributes[1])] = new List <ulong> { (ulong)attributes[2] }; } } } Dictionary <ulong, int[]> _studentSwaps = new Dictionary <ulong, int[]>(); var keys = _studentActivityRequestedGroups.Keys.ToList(); var keysGrouped = keys.GroupBy(x => x.Item1) .Select(x => new { studentId = x.Key, Count = x.Count() }); foreach (var student in keysGrouped) { if (_studentSwaps.ContainsKey(student.studentId)) { _studentSwaps[(student.studentId)][0] = student.Count; } else { _studentSwaps[student.studentId] = new int[] { student.Count, 0 }; } } Container.Requests = _requests; Container.StudentSwaps = _studentSwaps; Container.StudentActivityRequestedGroups = _studentActivityRequestedGroups; Container.GroupRequests = _groupRequests; } using (var reader = new StreamReader(overlapsFileName)) { Dictionary <ulong, List <ulong> > _overlaps = new Dictionary <ulong, List <ulong> >(); var headerLine = reader.ReadLine(); while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); List <int> attributes = new List <int>(); foreach (var value in values) { if (int.TryParse(value, out var num) == false) { Console.WriteLine("Error while reading Overlaps File."); return; } else { attributes.Add(num); } } for (int i = 0; i < 2; i++) { if (_overlaps.ContainsKey((ulong)attributes[i])) { _overlaps[(ulong)attributes[i]].Add((ulong)attributes[(i + 1) % 2]); } else { _overlaps[(ulong)attributes[i]] = new List <ulong> { (ulong)attributes[(i + 1) % 2] }; } } } Container.Overlaps = _overlaps; } using (var reader = new StreamReader(limitsFileName)) { Dictionary <ulong, int[]> _limits = new Dictionary <ulong, int[]>(); var headerLine = reader.ReadLine(); while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); List <int> attributes = new List <int>(); foreach (var value in values) { if (int.TryParse(value, out var num) == false) { Console.WriteLine("Error while reading Limits File."); return; } else { attributes.Add(num); } } //cnt, min, min_p, max, max_p _limits[(ulong)attributes[0]] = new int[] { attributes[1], attributes[2], attributes[3], attributes[4], attributes[5] }; if (Container.GroupRequests.ContainsKey((ulong)attributes[0])) { if (attributes[1] < attributes[3]) { Container.GroupRequests[(ulong)attributes[0]][1] = attributes[3] - attributes[1]; } } } Container.Limits = _limits; } var rand = new Random(); Container.NumberOfEvaluations = 0; Container.Evaluation = 0; bool doGreedy = true; Greedy greedy = new Greedy(); greedy.Initialize(awardActivity, awardStudent, minMaxPenalty, rand); sw.Stop(); var elapsed = sw.Elapsed.TotalSeconds; sw.Start(); List <int> _swapWeigh = new List <int>(); bool tabuImproved = false; while (elapsed < timeout) { while (doGreedy) { greedy.ReadRequests(); var eval = greedy.ReturnEvaluation(); if (eval > Container.Evaluation || Container.Evaluation == 0) { Container.Evaluation = eval; Console.WriteLine("Greedy, Current solution points = {0}", eval); } sw.Stop(); elapsed = sw.Elapsed.TotalSeconds; sw.Start(); if (elapsed > greedyTimeout) { doGreedy = false; } } Console.WriteLine("Final Greedy, Current solution points = {0}", Container.Evaluation); greedy.MakeNewStudentStates(Container.StudentStates); var _swapWeights = greedy.swapWeights; TabuSearch tabu = new TabuSearch(_swapWeights); tabu.Initialize(awardActivity, awardStudent, minMaxPenalty, rand); sw.Stop(); elapsed = sw.Elapsed.TotalSeconds; sw.Start(); while (elapsed < timeout) { tabu.DoSearch(); var tabuEvaluation = tabu.ReturnEvaluation(); if (tabuEvaluation > Container.Evaluation) { tabu.MakeNewStudentStates(tabu.newStudentStates); tabu.CopyToContainer(); Container.Evaluation = tabuEvaluation; _swapWeights = tabu.swapWeights; tabuImproved = true; } else { tabu.swapWeights = _swapWeights; } sw.Stop(); elapsed = sw.Elapsed.TotalSeconds; sw.Start(); _swapWeigh = _swapWeights; } } sw.Stop(); if (tabuImproved == true) { CopyNewStatesToStates(); } string newFileName = @"newStudent.csv"; using (var reader = new StreamReader(studentsFileName)) { using (var writer = new StreamWriter(newFileName)) { var headerLine = reader.ReadLine(); writer.WriteLine(headerLine); while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); var studentId = ulong.Parse(values[0]); var activityId = ulong.Parse(values[1]); var oldGroupId = ulong.Parse(values[3]); var newGroupId = Container.StudentStates.Where(s => s.StudentId == studentId && s.ActivityId == activityId && s.CurrentGroupId == oldGroupId).FirstOrDefault().NewGroupId; values[4] = newGroupId.ToString(); if (newGroupId == 0) { values[4] = values[3]; } writer.WriteLine(String.Join(",", values)); } } } File.Replace(newFileName, studentsFileName, null); File.Delete(newFileName); Console.WriteLine("Final evaluation: {0}", Container.Evaluation); Console.WriteLine("Number of evaluations: {0}", Container.NumberOfEvaluations); }