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 * @author Tomáš Müller 017 * @version IFS 1.3 (Iterative Forward Search)<br> 018 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 019 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 020 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 021 * <br> 022 * This library is free software; you can redistribute it and/or modify 023 * it under the terms of the GNU Lesser General Public License as 024 * published by the Free Software Foundation; either version 3 of the 025 * License, or (at your option) any later version. <br> 026 * <br> 027 * This library is distributed in the hope that it will be useful, but 028 * 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. <br> 031 * <br> 032 * You should have received a copy of the GNU Lesser General Public 033 * License along with this library; if not see 034 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 035 * 036 * @param <V> Variable 037 * @param <T> Value 038 */ 039public class SimpleNeighbour<V extends Variable<V, T>, T extends Value<V, T>> implements Neighbour<V, T> { 040 private V iVariable = null; 041 private T iValue = null; 042 private Set<T> iConflicts = null; 043 044 /** 045 * Model 046 * 047 * @param variable 048 * variable to be assigned 049 * @param value 050 * value to be assigned to the given variable, null if the 051 * variable should be unassigned 052 */ 053 public SimpleNeighbour(V variable, T value) { 054 iVariable = variable; 055 iValue = value; 056 } 057 058 public SimpleNeighbour(V variable, T value, Set<T> conflicts) { 059 iVariable = variable; 060 iValue = value; 061 iConflicts = conflicts; 062 } 063 064 /** Selected variable 065 * @return a variable 066 **/ 067 public V getVariable() { 068 return iVariable; 069 } 070 071 /** Selected value 072 * @return a value, null if the variable is to be unassigned 073 **/ 074 public T getValue() { 075 return iValue; 076 } 077 078 /** Perform assignment */ 079 @Override 080 public void assign(Assignment<V, T> assignment, long iteration) { 081 if (iVariable == null) 082 return; 083 if (iConflicts != null) 084 for (T conflict: iConflicts) 085 assignment.unassign(iteration, conflict.variable()); 086 if (iValue != null) 087 assignment.assign(iteration, iValue); 088 else 089 assignment.unassign(iteration, iVariable); 090 } 091 092 /** Improvement in the solution value if this neighbour is accepted. */ 093 @Override 094 public double value(Assignment<V, T> assignment) { 095 T old = assignment.getValue(iVariable); 096 // assigning an unassigned variable is always an improving move 097 if (iValue != null && old == null && (iConflicts == null || iConflicts.isEmpty())) return -1; 098 double val = (iValue == null ? 0 : iValue.toDouble(assignment)) - (iVariable == null || old == null ? 0 : old.toDouble(assignment)); 099 if (iConflicts != null) 100 for (T conflict: iConflicts) 101 val -= conflict.toDouble(assignment); 102 return val; 103 } 104 105 @Override 106 public String toString() { 107 return iVariable.getName() + " := " + (iValue == null ? "null" : iValue.getName()); 108 } 109 110 @Override 111 public Map<V, T> assignments() { 112 HashMap<V, T> ret = new HashMap<V, T>(); 113 if (iVariable != null) 114 ret.put(iVariable, iValue); 115 if (iConflicts != null) 116 for (T conflict: iConflicts) 117 ret.put(conflict.variable(), null); 118 return ret; 119 } 120}