001package org.cpsolver.studentsct.check; 002 003import java.util.HashMap; 004 005import org.cpsolver.coursett.model.TimeLocation; 006import org.cpsolver.ifs.assignment.Assignment; 007import org.cpsolver.studentsct.StudentSectioningModel; 008import org.cpsolver.studentsct.model.Enrollment; 009import org.cpsolver.studentsct.model.Request; 010import org.cpsolver.studentsct.model.SctAssignment; 011import org.cpsolver.studentsct.model.Student; 012 013 014/** 015 * This class looks and reports cases when a student is enrolled into two 016 * sections that are overlapping in time. 017 * 018 * <br> 019 * <br> 020 * 021 * Usage: if (new OverlapCheck(model).check()) ... 022 * 023 * <br> 024 * <br> 025 * 026 * @version StudentSct 1.3 (Student Sectioning)<br> 027 * Copyright (C) 2007 - 2014 Tomáš Müller<br> 028 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 029 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 030 * <br> 031 * This library is free software; you can redistribute it and/or modify 032 * it under the terms of the GNU Lesser General Public License as 033 * published by the Free Software Foundation; either version 3 of the 034 * License, or (at your option) any later version. <br> 035 * <br> 036 * This library is distributed in the hope that it will be useful, but 037 * WITHOUT ANY WARRANTY; without even the implied warranty of 038 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 039 * Lesser General Public License for more details. <br> 040 * <br> 041 * You should have received a copy of the GNU Lesser General Public 042 * License along with this library; if not see 043 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 044 */ 045public class OverlapCheck { 046 private static org.apache.logging.log4j.Logger sLog = org.apache.logging.log4j.LogManager.getLogger(OverlapCheck.class); 047 private StudentSectioningModel iModel; 048 049 /** 050 * Constructor 051 * 052 * @param model 053 * student sectioning model 054 */ 055 public OverlapCheck(StudentSectioningModel model) { 056 iModel = model; 057 } 058 059 /** Return student sectioning model 060 * @return problem model 061 **/ 062 public StudentSectioningModel getModel() { 063 return iModel; 064 } 065 066 /** 067 * Check for overlapping sections that are attended by the same student 068 * @param a current assignment 069 * @return false, if there is such a case 070 */ 071 public boolean check(Assignment<Request, Enrollment> a) { 072 sLog.info("Checking for overlaps..."); 073 boolean ret = true; 074 for (Student student : getModel().getStudents()) { 075 HashMap<TimeLocation, SctAssignment> times = new HashMap<TimeLocation, SctAssignment>(); 076 for (Request request : student.getRequests()) { 077 Enrollment enrollment = a.getValue(request); 078 if (enrollment == null) 079 continue; 080 for (SctAssignment assignment : enrollment.getAssignments()) { 081 if (assignment.getTime() == null) 082 continue; 083 for (TimeLocation time: times.keySet()) { 084 if (time.hasIntersection(assignment.getTime())) { 085 sLog.error("Student " + student + " assignment " + assignment + " overlaps with " 086 + times.get(time)); 087 ret = false; 088 } 089 } 090 times.put(assignment.getTime(), assignment); 091 } 092 } 093 } 094 return ret; 095 } 096 097}