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 * @version StudentSct 1.3 (Student Sectioning)<br> 021 * Copyright (C) 2014 Tomáš Müller<br> 022 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 023 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 024 * <br> 025 * This library is free software; you can redistribute it and/or modify 026 * it under the terms of the GNU Lesser General Public License as 027 * published by the Free Software Foundation; either version 3 of the 028 * License, or (at your option) any later version. <br> 029 * <br> 030 * This library is distributed in the hope that it will be useful, but 031 * WITHOUT ANY WARRANTY; without even the implied warranty of 032 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 033 * Lesser General Public License for more details. <br> 034 * <br> 035 * You should have received a copy of the GNU Lesser General Public 036 * License along with this library; if not see <a 037 * href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>. 038 * 039 */ 040public class FractionallyOverExpected extends PercentageOverExpected { 041 private Double iMaximum = null; 042 043 public FractionallyOverExpected(DataProperties config) { 044 super(config); 045 iMaximum = config.getPropertyDouble("OverExpected.Maximum", iMaximum); 046 } 047 048 public FractionallyOverExpected(Double percentage, Double maximum) { 049 super(percentage); 050 iMaximum = maximum; 051 } 052 053 public FractionallyOverExpected(Double percentage) { 054 this(percentage, 1.0); 055 } 056 057 public FractionallyOverExpected() { 058 this(null, 1.0); 059 } 060 061 /** 062 * Maximum, null if not set 063 * @return maximum 064 */ 065 public Double getMaximum() { 066 return iMaximum; 067 } 068 069 /** 070 * Maximum, section limit if not set 071 * @param section given section 072 * @return maximum 073 */ 074 public double getMaximum(Section section) { 075 return iMaximum == null || iMaximum <= 0.0 ? getLimit(section) : iMaximum; 076 } 077 078 @Override 079 public double getOverExpected(Assignment<Request, Enrollment> assignment, Section section, Request request) { 080 if (section.getLimit() <= 0) 081 return 0.0; // ignore unlimited & not available 082 083 double expected = round(getPercentage() * section.getSpaceExpected()); 084 double enrolled = getEnrollment(assignment, section, request) + request.getWeight(); 085 double limit = getLimit(section); 086 int subparts = section.getSubpart().getConfig().getSubparts().size(); 087 double max = getMaximum(section); 088 089 return expected + enrolled > limit ? (Math.min(max, expected + enrolled - limit) / max) / subparts : 0.0; 090 } 091 092 @Override 093 public String toString() { 094 return "frac(" + getPercentage() + "," + getMaximum() + ")"; 095 } 096 097}