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 int before = getVariable().getModel().nrUnassignedVariables(); 059 double beforeVal = getVariable().getModel().getTotalValue(); 060 double[] beforeValM = ((ExamModel)getVariable().getModel()).getTotalMultiValue(); 061 String n = toString(); 062 getVariable().assign(iteration, getValue()); 063 int after = getVariable().getModel().nrUnassignedVariables(); 064 double afterVal = getVariable().getModel().getTotalValue(); 065 double[] afterValM = ((ExamModel)getVariable().getModel()).getTotalMultiValue(); 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 }