001package org.cpsolver.ifs.assignment; 002 003import java.util.Collection; 004import java.util.HashMap; 005import java.util.Map; 006import java.util.concurrent.locks.Lock; 007 008import org.cpsolver.ifs.assignment.context.AssignmentContextHolder; 009import org.cpsolver.ifs.assignment.context.DefaultParallelAssignmentContextHolder; 010import org.cpsolver.ifs.model.Model; 011import org.cpsolver.ifs.model.Value; 012import org.cpsolver.ifs.model.Variable; 013import org.cpsolver.ifs.solution.Solution; 014import org.cpsolver.ifs.solver.ParallelSolver; 015 016 017/** 018 * An assignment using the {@link Variable#getAssignments()} to store values of all the 019 * variables of the model. Besides of that, a set of assigned variables is kept in memory. 020 * Each extra contains an array of values, indexed by {@link Assignment#getIndex()}. 021 * Useful for a small, fixed number of assignments. Used by the {@link ParallelSolver}, 022 * where there is one assignment for each thread. 023 * 024 * @see Assignment 025 * @see ParallelSolver 026 * 027 * @version IFS 1.3 (Iterative Forward Search)<br> 028 * Copyright (C) 2014 Tomáš Müller<br> 029 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 030 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 031 * <br> 032 * This library is free software; you can redistribute it and/or modify 033 * it under the terms of the GNU Lesser General Public License as 034 * published by the Free Software Foundation; either version 3 of the 035 * License, or (at your option) any later version. <br> 036 * <br> 037 * This library is distributed in the hope that it will be useful, but 038 * WITHOUT ANY WARRANTY; without even the implied warranty of 039 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 040 * Lesser General Public License for more details. <br> 041 * <br> 042 * You should have received a copy of the GNU Lesser General Public 043 * License along with this library; if not see <a href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>. 044 * @param <V> Variable 045 * @param <T> Value 046 **/ 047public class DefaultParallelAssignment <V extends Variable<V, T>, T extends Value<V, T>> extends AssignmentAbstract<V, T> { 048 private Map<V, Long> iAssignedVariables = new HashMap<V, Long>(); 049 private int iIndex; 050 051 public DefaultParallelAssignment(int threadIndex) { 052 super(new DefaultParallelAssignmentContextHolder<V, T>(threadIndex)); 053 iIndex = threadIndex; 054 } 055 056 public DefaultParallelAssignment() { 057 this(0); 058 } 059 060 public DefaultParallelAssignment(int threadIndex, Model<V, T> model, Assignment<V, T> assignment) { 061 this(threadIndex); 062 for (V variable: model.variables()) 063 setValueInternal(0, variable, assignment != null ? assignment.getValue(variable) : null); 064 } 065 066 public DefaultParallelAssignment(AssignmentContextHolder<V, T> contexts, int threadIndex, Solution<V, T> solution) { 067 super(contexts); 068 iIndex = threadIndex; 069 Lock lock = solution.getLock().readLock(); 070 lock.lock(); 071 try { 072 for (V variable: solution.getModel().variables()) 073 setValueInternal(0, variable, solution.getAssignment().getValue(variable)); 074 } finally { 075 lock.unlock(); 076 } 077 } 078 079 @Override 080 public long getIteration(V variable) { 081 Long it = iAssignedVariables.get(variable); 082 return (it == null ? 0 : it.longValue()); 083 } 084 085 @Override 086 public Collection<V> assignedVariables() { 087 return iAssignedVariables.keySet(); 088 } 089 090 @Override 091 @SuppressWarnings({ "deprecation", "unchecked" }) 092 protected T getValueInternal(V variable) { 093 return (T) variable.getAssignments()[iIndex]; 094 } 095 096 @Override 097 @SuppressWarnings("deprecation") 098 protected void setValueInternal(long iteration, V variable, T value) { 099 variable.getAssignments()[iIndex] = value; 100 if (value == null) 101 iAssignedVariables.remove(variable); 102 else 103 iAssignedVariables.put(variable, iteration); 104 } 105 106 @Override 107 public int getIndex() { 108 return iIndex; 109 } 110}