001package org.cpsolver.ifs.model; 002 003import java.util.HashMap; 004import java.util.Map; 005import java.util.Set; 006 007import org.cpsolver.ifs.assignment.Assignment; 008 009 010/** 011 * A neighbour consisting of a change (either assignment or unassignment) of a 012 * single variable. 013 * 014 * @see org.cpsolver.ifs.heuristics.NeighbourSelection 015 * 016 * @version IFS 1.3 (Iterative Forward Search)<br> 017 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 018 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 019 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 020 * <br> 021 * This library is free software; you can redistribute it and/or modify 022 * it under the terms of the GNU Lesser General Public License as 023 * published by the Free Software Foundation; either version 3 of the 024 * License, or (at your option) any later version. <br> 025 * <br> 026 * This library is distributed in the hope that it will be useful, but 027 * WITHOUT ANY WARRANTY; without even the implied warranty of 028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 029 * Lesser General Public License for more details. <br> 030 * <br> 031 * You should have received a copy of the GNU Lesser General Public 032 * License along with this library; if not see 033 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 034 * 035 * @param <V> Variable 036 * @param <T> Value 037 */ 038public class SimpleNeighbour<V extends Variable<V, T>, T extends Value<V, T>> implements Neighbour<V, T> { 039 private V iVariable = null; 040 private T iValue = null; 041 private Set<T> iConflicts = null; 042 043 /** 044 * Model 045 * 046 * @param variable 047 * variable to be assigned 048 * @param value 049 * value to be assigned to the given variable, null if the 050 * variable should be unassigned 051 */ 052 public SimpleNeighbour(V variable, T value) { 053 iVariable = variable; 054 iValue = value; 055 } 056 057 public SimpleNeighbour(V variable, T value, Set<T> conflicts) { 058 iVariable = variable; 059 iValue = value; 060 iConflicts = conflicts; 061 } 062 063 /** Selected variable 064 * @return a variable 065 **/ 066 public V getVariable() { 067 return iVariable; 068 } 069 070 /** Selected value 071 * @return a value, null if the variable is to be unassigned 072 **/ 073 public T getValue() { 074 return iValue; 075 } 076 077 /** Perform assignment */ 078 @Override 079 public void assign(Assignment<V, T> assignment, long iteration) { 080 if (iVariable == null) 081 return; 082 if (iValue != null) 083 assignment.assign(iteration, iValue); 084 else 085 assignment.unassign(iteration, iVariable); 086 } 087 088 /** Improvement in the solution value if this neighbour is accepted. */ 089 @Override 090 public double value(Assignment<V, T> assignment) { 091 T old = assignment.getValue(iVariable); 092 double val = (iValue == null ? 0 : iValue.toDouble(assignment)) - (iVariable == null || old == null ? 0 : old.toDouble(assignment)); 093 if (iConflicts != null) 094 for (T conflict: iConflicts) 095 val -= conflict.toDouble(assignment); 096 return val; 097 } 098 099 @Override 100 public String toString() { 101 return iVariable.getName() + " := " + (iValue == null ? "null" : iValue.getName()); 102 } 103 104 @Override 105 public Map<V, T> assignments() { 106 HashMap<V, T> ret = new HashMap<V, T>(); 107 if (iVariable != null) 108 ret.put(iVariable, iValue); 109 if (iConflicts != null) 110 for (T conflict: iConflicts) 111 ret.put(conflict.variable(), null); 112 return ret; 113 } 114}