001 package net.sf.cpsolver.studentsct.check;
002
003 import java.text.DecimalFormat;
004
005 import net.sf.cpsolver.studentsct.StudentSectioningModel;
006 import net.sf.cpsolver.studentsct.model.Config;
007 import net.sf.cpsolver.studentsct.model.Offering;
008 import net.sf.cpsolver.studentsct.model.Section;
009 import net.sf.cpsolver.studentsct.model.Subpart;
010
011 /**
012 * This class looks and reports cases when a section limit is exceeded.
013 *
014 * <br>
015 * <br>
016 *
017 * Usage: if (new SectionLimitCheck(model).check()) ...
018 *
019 * <br>
020 * <br>
021 *
022 * @version StudentSct 1.2 (Student Sectioning)<br>
023 * Copyright (C) 2007 - 2010 Tomas Muller<br>
024 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
025 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
026 * <br>
027 * This library is free software; you can redistribute it and/or modify
028 * it under the terms of the GNU Lesser General Public License as
029 * published by the Free Software Foundation; either version 3 of the
030 * License, or (at your option) any later version. <br>
031 * <br>
032 * This library is distributed in the hope that it will be useful, but
033 * WITHOUT ANY WARRANTY; without even the implied warranty of
034 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
035 * Lesser General Public License for more details. <br>
036 * <br>
037 * You should have received a copy of the GNU Lesser General Public
038 * License along with this library; if not see
039 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
040 */
041 public class SectionLimitCheck {
042 private static org.apache.log4j.Logger sLog = org.apache.log4j.Logger.getLogger(SectionLimitCheck.class);
043 private static DecimalFormat sDF = new DecimalFormat("0.000");
044 private StudentSectioningModel iModel;
045
046 /**
047 * Constructor
048 *
049 * @param model
050 * student sectioning model
051 */
052 public SectionLimitCheck(StudentSectioningModel model) {
053 iModel = model;
054 }
055
056 /** Return student sectioning model */
057 public StudentSectioningModel getModel() {
058 return iModel;
059 }
060
061 /**
062 * Check for sections that have more students enrolled than it is allowed,
063 * i.e., the sum of requests weights is above the section limit
064 *
065 * @return false, if there is such a case
066 */
067 public boolean check() {
068 sLog.info("Checking section limits...");
069 boolean ret = true;
070 for (Offering offering : getModel().getOfferings()) {
071 for (Config config : offering.getConfigs()) {
072 for (Subpart subpart : config.getSubparts()) {
073 for (Section section : subpart.getSections()) {
074 if (section.getLimit() < 0)
075 continue;
076 double used = section.getEnrollmentWeight(null);
077 if (used - section.getMaxEnrollmentWeight() > section.getLimit()) {
078 sLog.error("Section " + section.getName() + " exceeds its limit " + sDF.format(used) + ">"
079 + section.getLimit() + " for more than one student (W:"
080 + section.getMaxEnrollmentWeight() + ")");
081 ret = false;
082 } else if (Math.round(used) > section.getLimit()) {
083 sLog.debug("Section " + section.getName() + " exceeds its limit " + sDF.format(used) + ">"
084 + section.getLimit() + " for less than one student (W:"
085 + section.getMaxEnrollmentWeight() + ")");
086 }
087 }
088 }
089 }
090 }
091 return ret;
092 }
093
094 }