001package org.cpsolver.exam.criteria.additional; 002 003import java.util.Map; 004import java.util.Set; 005 006import org.cpsolver.exam.criteria.ExamCriterion; 007import org.cpsolver.exam.model.Exam; 008import org.cpsolver.exam.model.ExamPlacement; 009import org.cpsolver.exam.model.ExamRoomPlacement; 010import org.cpsolver.ifs.assignment.Assignment; 011import org.cpsolver.ifs.util.DataProperties; 012 013 014/** 015 * Experimental criterion measuring average distance (in meters) to the 016 * strongly preferred room (or rooms) of the examination. The idea is to 017 * prefer rooms that are close to the strongly preference room (if there is 018 * a strongly preferred room but it is not available). 019 * <br><br> 020 * A weight of the average distance between the assigned room(s) and the 021 * strongly preferred room or rooms can be set using 022 * Exams.DistanceToStronglyPreferredRoomWeight property. 023 * <br><br> 024 * To enable this criterion add this class name to Exams.AdditionalCriteria 025 * parameter. For instance:<br> 026 * Exams.AdditionalCriteria=org.cpsolver.exam.criteria.additional.DistanceToStronglyPreferredRoom 027 * 028 * <br> 029 * 030 * @author Tomáš Müller 031 * @version ExamTT 1.3 (Examination Timetabling)<br> 032 * Copyright (C) 2008 - 2014 Tomáš Müller<br> 033 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 034 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 035 * <br> 036 * This library is free software; you can redistribute it and/or modify 037 * it under the terms of the GNU Lesser General Public License as 038 * published by the Free Software Foundation; either version 3 of the 039 * License, or (at your option) any later version. <br> 040 * <br> 041 * This library is distributed in the hope that it will be useful, but 042 * WITHOUT ANY WARRANTY; without even the implied warranty of 043 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 044 * Lesser General Public License for more details. <br> 045 * <br> 046 * You should have received a copy of the GNU Lesser General Public 047 * License along with this library; if not see 048 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 049 */ 050public class DistanceToStronglyPreferredRoom extends ExamCriterion { 051 052 @Override 053 public String getWeightName() { 054 return "Exams.DistanceToStronglyPreferredRoomWeight"; 055 } 056 057 @Override 058 public String getXmlWeightName() { 059 return "distanceToStronglyPreferredRoomWeight"; 060 } 061 062 @Override 063 public double getWeightDefault(DataProperties config) { 064 return 0.001; 065 } 066 067 @Override 068 public double getValue(Assignment<Exam, ExamPlacement> assignment, ExamPlacement value, Set<ExamPlacement> conflicts) { 069 Average ret = new Average(); 070 for (ExamRoomPlacement assigned: value.getRoomPlacements()) { 071 for (ExamRoomPlacement preferred: value.variable().getPreferredRoomPlacements()) 072 ret.add(assigned.getDistanceInMeters(preferred)); 073 } 074 return ret.average(); 075 } 076 077 @Override 078 public String toString(Assignment<Exam, ExamPlacement> assignment) { 079 return "@D:" + sDoubleFormat.format(getValue(assignment) / assignment.nrAssignedVariables()); 080 } 081 082 @Override 083 public double[] getBounds(Assignment<Exam, ExamPlacement> assignment) { 084 return new double[] { 0.0, 0.0 }; 085 } 086 087 @Override 088 public void getInfo(Assignment<Exam, ExamPlacement> assignment, Map<String, String> info) { 089 if (getValue(assignment) > 0.0) 090 info.put(getName(), sDoubleFormat.format(getValue(assignment) / assignment.nrAssignedVariables()) + " m"); 091 } 092 093 private static class Average { 094 double iValue = 0.0; 095 int iCount = 0; 096 097 private void add(double value) { 098 iValue += value; iCount ++; 099 } 100 101 public double average() { 102 return (iCount == 0 ? 0.0 : iValue / iCount); 103 } 104 } 105 106}