001package org.cpsolver.ifs.assignment.context; 002 003import org.cpsolver.ifs.assignment.Assignment; 004import org.cpsolver.ifs.model.Model; 005import org.cpsolver.ifs.model.Value; 006import org.cpsolver.ifs.model.Variable; 007 008/** 009 * A model with an assignment context. In order to be able to hold multiple assignments in memory 010 * it is desired for all the assignment dependent data a constraint may need (to effectively enumerate 011 * problem objectives), to store these data in a separate class (implementing the 012 * {@link AssignmentConstraintContext} interface). This context is created by calling 013 * {@link ConstraintWithContext#createAssignmentContext(Assignment)} and accessed by 014 * {@link ConstraintWithContext#getContext(Assignment)}. 015 * 016 * 017 * @see AssignmentContext 018 * 019 * @author Tomáš Müller 020 * @version IFS 1.3 (Iterative Forward Search)<br> 021 * Copyright (C) 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 <a href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>. 037 * @param <V> Variable 038 * @param <T> Value 039 * @param <C> Assignment Context 040 **/ 041public abstract class ModelWithContext<V extends Variable<V, T>, T extends Value<V, T>, C extends AssignmentConstraintContext<V, T>> extends Model<V, T> implements HasAssignmentContext<V, T, C>, CanHoldContext { 042 043 private AssignmentContextReference<V, T, C> iContextReference = null; 044 private AssignmentContext[] iContext = new AssignmentContext[CanHoldContext.sMaxSize]; 045 046 /** 047 * Defines how the context of the model should be automatically updated (i.e., when {@link AssignmentConstraintContext#assigned(Assignment, Value)} and {@link AssignmentConstraintContext#unassigned(Assignment, Value)} are called). 048 */ 049 protected static enum ContextUpdateType { 050 /** Update is done before an unassignment and before an assignment. */ 051 BeforeUnassignedBeforeAssigned, 052 /** Update is done after an unassignment and before an assignment. */ 053 AfterUnassignedBeforeAssigned, 054 /** Update is done before an unassignment and after an assignment. */ 055 BeforeUnassignedAfterAssigned, 056 /** Update is done after an unassignment and after an assignment. This is the default. */ 057 AfterUnassignedAfterAssigned, 058 /** Context is to be updated manually. */ 059 NoUpdate 060 } 061 private ContextUpdateType iContextUpdateType = ContextUpdateType.BeforeUnassignedAfterAssigned; 062 063 public ModelWithContext() { 064 super(); 065 iContextReference = createReference(this); 066 } 067 068 /** 069 * Returns an assignment context associated with this model. If there is no 070 * assignment context associated with this model yet, one is created using the 071 * {@link ConstraintWithContext#createAssignmentContext(Assignment)} method. From that time on, 072 * this context is kept with the assignment and automatically updated by calling the 073 * {@link AssignmentConstraintContext#assigned(Assignment, Value)} and {@link AssignmentConstraintContext#unassigned(Assignment, Value)} 074 * whenever a variable is changed. 075 * @param assignment given assignment 076 * @return assignment context associated with this model and the given assignment 077 */ 078 @Override 079 public C getContext(Assignment<V, T> assignment) { 080 return AssignmentContextHelper.getContext(this, assignment); 081 } 082 083 @Override 084 public AssignmentContextReference<V, T, C> getAssignmentContextReference() { return iContextReference; } 085 086 @Override 087 public void setAssignmentContextReference(AssignmentContextReference<V, T, C> reference) { iContextReference = reference; } 088 089 @Override 090 public AssignmentContext[] getContext() { return iContext; } 091 092 @Override 093 public void beforeUnassigned(Assignment<V, T> assignment, long iteration, T value) { 094 super.beforeUnassigned(assignment, iteration, value); 095 switch (getContextUpdateType()) { 096 case BeforeUnassignedAfterAssigned: 097 case BeforeUnassignedBeforeAssigned: 098 getContext(assignment).unassigned(assignment, value); 099 } 100 } 101 102 @Override 103 public void afterUnassigned(Assignment<V, T> assignment, long iteration, T value) { 104 super.afterUnassigned(assignment, iteration, value); 105 switch (getContextUpdateType()) { 106 case AfterUnassignedAfterAssigned: 107 case AfterUnassignedBeforeAssigned: 108 getContext(assignment).unassigned(assignment, value); 109 } 110 } 111 112 @Override 113 public void afterAssigned(Assignment<V, T> assignment, long iteration, T value) { 114 super.afterAssigned(assignment, iteration, value); 115 switch (getContextUpdateType()) { 116 case AfterUnassignedAfterAssigned: 117 case BeforeUnassignedAfterAssigned: 118 getContext(assignment).assigned(assignment, value); 119 } 120 } 121 122 @Override 123 public void beforeAssigned(Assignment<V, T> assignment, long iteration, T value) { 124 super.beforeAssigned(assignment, iteration, value); 125 switch (getContextUpdateType()) { 126 case AfterUnassignedBeforeAssigned: 127 case BeforeUnassignedBeforeAssigned: 128 getContext(assignment).assigned(assignment, value); 129 } 130 } 131 132 public ContextUpdateType getContextUpdateType() { 133 return iContextUpdateType; 134 } 135 136 public void setContextUpdateType(ContextUpdateType iContextUpdateType) { 137 this.iContextUpdateType = iContextUpdateType; 138 } 139 140}