001 package net.sf.cpsolver.exam.neighbours;
002
003 import java.text.DecimalFormat;
004
005 import org.apache.log4j.Logger;
006
007 import net.sf.cpsolver.exam.model.ExamModel;
008 import net.sf.cpsolver.exam.model.ExamPlacement;
009 import net.sf.cpsolver.ifs.model.SimpleNeighbour;
010 /**
011 * Extension of {@link SimpleNeighbour}. The only difference is that
012 * the value ({@link SimpleNeighbour#value()}) is decreased by 1000 if the
013 * selected variable has no current assignment.
014 * <br><br>
015 *
016 * @version
017 * ExamTT 1.1 (Examination Timetabling)<br>
018 * Copyright (C) 2008 Tomáš Müller<br>
019 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
020 * Lazenska 391, 76314 Zlin, Czech Republic<br>
021 * <br>
022 * This library is free software; you can redistribute it and/or
023 * modify it under the terms of the GNU Lesser General Public
024 * License as published by the Free Software Foundation; either
025 * version 2.1 of the License, or (at your option) any later version.
026 * <br><br>
027 * This library is distributed in the hope that it will be useful,
028 * but WITHOUT ANY WARRANTY; without even the implied warranty of
029 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
030 * Lesser General Public License for more details.
031 * <br><br>
032 * You should have received a copy of the GNU Lesser General Public
033 * License along with this library; if not, write to the Free Software
034 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
035 */
036 public class ExamSimpleNeighbour extends SimpleNeighbour {
037 private static Logger sLog = Logger.getLogger(ExamSimpleNeighbour.class);
038 private static boolean sCheck = false;
039 private double iValue = 0;
040 private double iDx;
041
042 public ExamSimpleNeighbour(ExamPlacement placement) {
043 super(placement.variable(),placement);
044 iValue = placement.toDouble();
045 if (placement.variable().getAssignment()!=null)
046 iValue -= placement.variable().getAssignment().toDouble();
047 else
048 iValue -= 1000;
049 if (sCheck) {
050 iDx = placement.toDouble();
051 if (placement.variable().getAssignment()!=null)
052 iDx -= placement.variable().getAssignment().toDouble();
053 }
054 }
055
056 public void assign(long iteration) {
057 if (sCheck) {
058 double beforeVal = getVariable().getModel().getTotalValue();
059 double[] beforeValM = ((ExamModel)getVariable().getModel()).getTotalMultiValue();
060 String n = toString();
061 getVariable().assign(iteration, getValue());
062 double afterVal = getVariable().getModel().getTotalValue();
063 double[] afterValM = ((ExamModel)getVariable().getModel()).getTotalMultiValue();
064 /*int before = getVariable().getModel().nrUnassignedVariables();
065 int after = getVariable().getModel().nrUnassignedVariables();
066 if (after>before) {
067 sLog.error("-- assignment mischmatch (delta:"+(after-before)+")");
068 sLog.error(" -- neighbour: "+n);
069 }*/
070 if (Math.abs(afterVal-beforeVal-iDx)>=0.0000001) {
071 sLog.error("-- value mischmatch (delta:"+(afterVal-beforeVal)+", value:"+iDx+")");
072 sLog.error(" -- neighbour: "+n);
073 sLog.error(" -- solution: "+toString(afterValM, beforeValM));
074 }
075 } else {
076 getVariable().assign(iteration, getValue());
077 }
078 }
079
080
081 protected static String toString(double[] x) {
082 DecimalFormat df = new DecimalFormat("0.00");
083 StringBuffer s = new StringBuffer();
084 for (int i=0;i<x.length;i++) {
085 if (i>0) s.append(",");
086 s.append(df.format(x[i]));
087 }
088 return "["+s.toString()+"]";
089 }
090
091 protected static String toString(double[] x, double[] y) {
092 DecimalFormat df = new DecimalFormat("0.00");
093 StringBuffer s = new StringBuffer();
094 for (int i=0;i<x.length;i++) {
095 if (i>0) s.append(",");
096 s.append(df.format(x[i]-y[i]));
097 }
098 return "["+s.toString()+"]";
099 }
100
101 public String toString() {
102 return
103 getVariable().getAssignment()+
104 " -> "+
105 getValue().toString()+
106 " / "+" (value:"+value()+")";
107 }
108
109 public double value() {
110 return iValue;
111 }
112 }