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