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