001package org.cpsolver.studentsct.online.expectations; 002 003import org.cpsolver.ifs.assignment.Assignment; 004import org.cpsolver.ifs.util.DataProperties; 005import org.cpsolver.studentsct.model.Enrollment; 006import org.cpsolver.studentsct.model.Request; 007import org.cpsolver.studentsct.model.Section; 008 009/** 010 * Over-expected space depends on how much is the class over-expected. It works 011 * like the {@link PercentageOverExpected}, however, the returned over-expected 012 * penalty is based on the over-expected space (enrollment + expectations - 013 * section limit), divided by the section limit. The over-expectations can be 014 * capped by the OverExpected.Maximum parameter (defaults to section limit).<br> 015 * <br> 016 * Unlike the {@link PercentageOverExpected}, this criterion offers the ability 017 * to prefer less over-expected sections among the sections that are 018 * over-expected. 019 * 020 * @author Tomáš Müller 021 * @version StudentSct 1.3 (Student Sectioning)<br> 022 * Copyright (C) 2014 Tomáš Müller<br> 023 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 024 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 025 * <br> 026 * This library is free software; you can redistribute it and/or modify 027 * it under the terms of the GNU Lesser General Public License as 028 * published by the Free Software Foundation; either version 3 of the 029 * License, or (at your option) any later version. <br> 030 * <br> 031 * This library is distributed in the hope that it will be useful, but 032 * WITHOUT ANY WARRANTY; without even the implied warranty of 033 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 034 * Lesser General Public License for more details. <br> 035 * <br> 036 * You should have received a copy of the GNU Lesser General Public 037 * License along with this library; if not see <a 038 * href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>. 039 * 040 */ 041public class FractionallyOverExpected extends PercentageOverExpected { 042 private Double iMaximum = null; 043 044 public FractionallyOverExpected(DataProperties config) { 045 super(config); 046 iMaximum = config.getPropertyDouble("OverExpected.Maximum", iMaximum); 047 } 048 049 public FractionallyOverExpected(Double percentage, Double maximum) { 050 super(percentage); 051 iMaximum = maximum; 052 } 053 054 public FractionallyOverExpected(Double percentage) { 055 this(percentage, 1.0); 056 } 057 058 public FractionallyOverExpected() { 059 this(null, 1.0); 060 } 061 062 /** 063 * Maximum, null if not set 064 * @return maximum 065 */ 066 public Double getMaximum() { 067 return iMaximum; 068 } 069 070 /** 071 * Maximum, section limit if not set 072 * @param section given section 073 * @return maximum 074 */ 075 public double getMaximum(Section section) { 076 return iMaximum == null || iMaximum <= 0.0 ? getLimit(section) : iMaximum; 077 } 078 079 @Override 080 public double getOverExpected(Assignment<Request, Enrollment> assignment, Section section, Request request) { 081 if (section.getLimit() <= 0) 082 return 0.0; // ignore unlimited & not available 083 084 double expected = round(getPercentage() * section.getSpaceExpected()); 085 double enrolled = getEnrollment(assignment, section, request) + request.getWeight(); 086 double limit = getLimit(section); 087 int subparts = section.getSubpart().getConfig().getSubparts().size(); 088 double max = getMaximum(section); 089 090 return expected + enrolled > limit ? (Math.min(max, expected + enrolled - limit) / max) / subparts : 0.0; 091 } 092 093 @Override 094 public String toString() { 095 return "frac(" + getPercentage() + "," + getMaximum() + ")"; 096 } 097 098}