001package org.cpsolver.ifs.constant; 002 003 004import java.util.ArrayList; 005import java.util.List; 006 007import org.cpsolver.ifs.assignment.Assignment; 008import org.cpsolver.ifs.model.Model; 009import org.cpsolver.ifs.model.Value; 010import org.cpsolver.ifs.model.Variable; 011 012 013/** 014 * Extension of the model with constant variables. 015 * 016 * Such variables are excluded from the solver process, however, they can be 017 * included in constraints. Such model can allow us to build a solution on top 018 * of another solution (e.g., committed classes in the course timetabling). 019 * 020 * Constant variable has to implement interface {@link ConstantVariable}, 021 * returning {@link ConstantVariable#isConstant()} true. 022 * 023 * @author Tomáš Müller 024 * @version IFS 1.3 (Iterative Forward Search)<br> 025 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 026 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 027 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 028 * <br> 029 * This library is free software; you can redistribute it and/or modify 030 * it under the terms of the GNU Lesser General Public License as 031 * published by the Free Software Foundation; either version 3 of the 032 * License, or (at your option) any later version. <br> 033 * <br> 034 * This library is distributed in the hope that it will be useful, but 035 * WITHOUT ANY WARRANTY; without even the implied warranty of 036 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 037 * Lesser General Public License for more details. <br> 038 * <br> 039 * You should have received a copy of the GNU Lesser General Public 040 * License along with this library; if not see <a href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>. 041 * 042 * @param <V> Variable 043 * @param <T> Value 044 */ 045public class ConstantModel<V extends Variable<V, T>, T extends Value<V, T>> extends Model<V, T> { 046 private List<V> iConstantVariables = null; 047 048 /** List of constant variables 049 * @return all constants 050 **/ 051 public List<V> constantVariables() { 052 return iConstantVariables; 053 } 054 055 /** True, if the model contains at least one constant variable. 056 * @return true, if there is at least one constant in this model 057 **/ 058 public boolean hasConstantVariables() { 059 return iConstantVariables != null && !iConstantVariables.isEmpty(); 060 } 061 062 /** True, if the given variable is constant. 063 * @param variable given variable 064 * @return true if constant 065 **/ 066 public boolean isConstant(V variable) { 067 return (iConstantVariables != null && variable instanceof ConstantVariable && ((ConstantVariable<?>) variable).isConstant()); 068 } 069 070 /** Adds a variable to the model */ 071 @Override 072 public void addVariable(V variable) { 073 if (variable instanceof ConstantVariable && ((ConstantVariable<?>) variable).isConstant()) { 074 if (iConstantVariables == null) 075 iConstantVariables = new ArrayList<V>(); 076 variable.setModel(this); 077 iConstantVariables.add(variable); 078 } else 079 super.addVariable(variable); 080 } 081 082 /** Removes a variable from the model */ 083 @Override 084 public void removeVariable(V variable) { 085 if (isConstant(variable)) { 086 variable.setModel(null); 087 iConstantVariables.remove(variable); 088 } else 089 super.removeVariable(variable); 090 } 091 092 /** 093 * Called before a value is assigned to its variable. Constant variables are 094 * excluded from (re)assignment. 095 */ 096 @Override 097 public void beforeAssigned(Assignment<V, T> assignment, long iteration, T value) { 098 if (!isConstant(value.variable())) 099 super.beforeAssigned(assignment, iteration, value); 100 } 101 102 /** 103 * Called before a value is unassigned from its variable. Constant variables 104 * are excluded from (re)assignment. 105 */ 106 @Override 107 public void beforeUnassigned(Assignment<V, T> assignment, long iteration, T value) { 108 if (!isConstant(value.variable())) 109 super.beforeUnassigned(assignment, iteration, value); 110 } 111 112 /** 113 * Called after a value is assigned to its variable. Constant variables are 114 * excluded from (re)assignment. 115 */ 116 @Override 117 public void afterAssigned(Assignment<V, T> assignment, long iteration, T value) { 118 if (!isConstant(value.variable())) 119 super.afterAssigned(assignment, iteration, value); 120 } 121 122 /** 123 * Called after a value is unassigned from its variable. Constant variables 124 * are excluded from (re)assignment. 125 */ 126 @Override 127 public void afterUnassigned(Assignment<V, T> assignment, long iteration, T value) { 128 if (!isConstant(value.variable())) 129 super.afterUnassigned(assignment, iteration, value); 130 } 131}