001 package net.sf.cpsolver.exam.criteria; 002 003 import java.util.Map; 004 import java.util.Set; 005 006 import net.sf.cpsolver.exam.model.Exam; 007 import net.sf.cpsolver.exam.model.ExamModel; 008 import net.sf.cpsolver.exam.model.ExamPlacement; 009 import net.sf.cpsolver.ifs.solver.Solver; 010 import net.sf.cpsolver.ifs.util.DataProperties; 011 012 /** 013 * Front load penalty. I.e., large exam is discouraged to be placed on or after a 014 * certain period. 015 * <br><br> 016 * <b>largeSize</b>: An exam is considered large, if its size is greater or equal to 017 * this number. Value -1 means all exams are small. It can be set by problem 018 * property Exams.LargeSize, or in the input xml file, property largeSize. 019 * <br><br> 020 * <b>largePeriod</b>: Period index (number of periods multiplied by this number) for front load 021 * criteria for large exams. Can be set by problem property 022 * Exams.LargePeriod, or in the input xml file, property largePeriod. 023 * <br><br> 024 * Weight of the front load criterion, i.e., a weight for assigning a large exam 025 * after large period can be set by problem property Exams.LargeWeight, or 026 * in the input xml file, property largeWeight. 027 * 028 * <br> 029 * 030 * @version ExamTT 1.2 (Examination Timetabling)<br> 031 * Copyright (C) 2008 - 2012 Tomas Muller<br> 032 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 033 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 034 * <br> 035 * This library is free software; you can redistribute it and/or modify 036 * it under the terms of the GNU Lesser General Public License as 037 * published by the Free Software Foundation; either version 3 of the 038 * License, or (at your option) any later version. <br> 039 * <br> 040 * This library is distributed in the hope that it will be useful, but 041 * WITHOUT ANY WARRANTY; without even the implied warranty of 042 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 043 * Lesser General Public License for more details. <br> 044 * <br> 045 * You should have received a copy of the GNU Lesser General Public 046 * License along with this library; if not see 047 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 048 */ 049 public class LargeExamsPenalty extends ExamCriterion { 050 private int iLargeSize = -1; 051 private double iLargePeriod = 0.67; 052 053 @Override 054 public String getWeightName() { 055 return "Exams.LargeWeight"; 056 } 057 058 @Override 059 public String getXmlWeightName() { 060 return "largeWeight"; 061 } 062 063 @Override 064 public void getXmlParameters(Map<String, String> params) { 065 params.put(getXmlWeightName(), String.valueOf(getWeight())); 066 params.put("largeSize", String.valueOf(getLargeSize())); 067 params.put("largePeriod", String.valueOf(getLargePeriod())); 068 } 069 070 @Override 071 public void setXmlParameters(Map<String, String> params) { 072 try { 073 setWeight(Double.valueOf(params.get(getXmlWeightName()))); 074 } catch (NumberFormatException e) {} catch (NullPointerException e) {} 075 try { 076 setLargeSize(Integer.valueOf(params.get("largeSize"))); 077 } catch (NumberFormatException e) {} catch (NullPointerException e) {} 078 try { 079 setLargePeriod(Double.valueOf(params.get("largePeriod"))); 080 } catch (NumberFormatException e) {} catch (NullPointerException e) {} 081 } 082 083 @Override 084 public double getWeightDefault(DataProperties config) { 085 return 1.0; 086 } 087 088 @Override 089 public boolean init(Solver<Exam, ExamPlacement> solver) { 090 boolean ret = super.init(solver); 091 iLargeSize = solver.getProperties().getPropertyInt("Exams.LargeSize", iLargeSize); 092 iLargePeriod = solver.getProperties().getPropertyDouble("Exams.LargePeriod", iLargePeriod); 093 return ret; 094 } 095 096 /** 097 * An exam is considered large, if its size is greater or equal to this 098 * large size. Value -1 means all exams are small. Can be set by problem 099 * property Exams.LargeSize, or in the input xml file, property largeSize) 100 **/ 101 public int getLargeSize() { 102 return iLargeSize; 103 } 104 105 /** 106 * An exam is considered large, if its size is greater or equal to this 107 * large size. Value -1 means all exams are small. Can be set by problem 108 * property Exams.LargeSize, or in the input xml file, property largeSize) 109 **/ 110 public void setLargeSize(int largeSize) { 111 iLargeSize = largeSize; 112 } 113 114 /** 115 * Period index (number of periods multiplied by this number) for front load 116 * criteria for large exams. Can be set by problem property 117 * Exams.LargePeriod, or in the input xml file, property largePeriod) 118 **/ 119 public double getLargePeriod() { 120 return iLargePeriod; 121 } 122 123 /** 124 * Period index (number of periods multiplied by this number) for front load 125 * criteria for large exams. Can be set by problem property 126 * Exams.LargePeriod, or in the input xml file, property largePeriod) 127 **/ 128 public void setLargePeriod(double largePeriod) { 129 iLargePeriod = largePeriod; 130 } 131 132 133 public int getLargePeriodIndex() { 134 return (int) Math.round(((ExamModel)getModel()).getPeriods().size() * iLargePeriod); 135 } 136 137 @Override 138 public double getValue(ExamPlacement value, Set<ExamPlacement> conflicts) { 139 Exam exam = value.variable(); 140 if (getLargeSize() < 0 || exam.getSize() < getLargeSize()) return 0; 141 return (value.getPeriod().getIndex() < getLargePeriodIndex() ? 0 : 1); 142 } 143 144 @Override 145 protected void computeBounds() { 146 iBounds = new double[] { 0.0, 0.0 }; 147 for (Exam exam : getModel().variables()) { 148 if (getLargeSize() >= 0 && exam.getSize() >= getLargeSize()) 149 iBounds[1] += 1.0; 150 } 151 } 152 153 @Override 154 public String toString() { 155 return "LP:" + sDoubleFormat.format(getWeightedValue()); 156 } 157 }