001package net.sf.cpsolver.studentsct.check;
002
003import java.text.DecimalFormat;
004
005import net.sf.cpsolver.studentsct.StudentSectioningModel;
006import net.sf.cpsolver.studentsct.model.Config;
007import net.sf.cpsolver.studentsct.model.Offering;
008import net.sf.cpsolver.studentsct.model.Section;
009import 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 Tomáš Müller<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 */
041public 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}