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