001 package net.sf.cpsolver.ifs.example.csp; 002 003 import java.util.*; 004 005 import net.sf.cpsolver.ifs.model.*; 006 007 /** 008 * CSP binary constraint. 009 * <br><br> 010 * This class only implements the generation of a binary CSP constraint and the consistency check. 011 * 012 * @version 013 * IFS 1.1 (Iterative Forward Search)<br> 014 * Copyright (C) 2006 Tomáš Müller<br> 015 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 016 * Lazenska 391, 76314 Zlin, Czech Republic<br> 017 * <br> 018 * This library is free software; you can redistribute it and/or 019 * modify it under the terms of the GNU Lesser General Public 020 * License as published by the Free Software Foundation; either 021 * version 2.1 of the License, or (at your option) any later version. 022 * <br><br> 023 * This library is distributed in the hope that it will be useful, 024 * but WITHOUT ANY WARRANTY; without even the implied warranty of 025 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 026 * Lesser General Public License for more details. 027 * <br><br> 028 * You should have received a copy of the GNU Lesser General Public 029 * License along with this library; if not, write to the Free Software 030 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 031 */ 032 public class CSPBinaryConstraint extends BinaryConstraint { 033 private boolean iIsConsistent[][] = null; 034 private int iNrCompatiblePairs; 035 036 /** Constructor 037 * @param nrCompatiblePairs number of compatible pairs of values in the constraint 038 */ 039 public CSPBinaryConstraint(int id, int nrCompatiblePairs) { 040 super(); 041 iId = id; 042 iNrCompatiblePairs = nrCompatiblePairs; 043 } 044 045 private void swap(int[][] allPairs, int first, int second) { 046 int[] a = allPairs[first]; 047 allPairs[first] = allPairs[second]; 048 allPairs[second] = a; 049 } 050 051 /** 052 * Initializes the constraint. Randomly generates the given number of compatible pairs of values. 053 * @param rndNumGen random number generator 054 */ 055 public void init(Random rndNumGen) { 056 int numberOfAllPairs = first().values().size() * second().values().size(); 057 int[][] allPairs = new int[numberOfAllPairs][]; 058 int idx = 0; 059 060 iIsConsistent = new boolean[first().values().size()][second().values().size()]; 061 062 for (Enumeration i1=first().values().elements(); 063 i1.hasMoreElements();) { 064 CSPValue v1 = (CSPValue)i1.nextElement(); 065 for (Enumeration i2=second().values().elements(); 066 i2.hasMoreElements();) { 067 CSPValue v2 = (CSPValue)i2.nextElement(); 068 iIsConsistent[(int)v1.toDouble()][(int)v2.toDouble()] = false; 069 allPairs[idx++] = new int[] {(int)v1.toDouble(), (int)v2.toDouble()}; 070 } 071 } 072 073 for (int i=0; i<iNrCompatiblePairs; i++) { 074 swap(allPairs, i, i+(int)(rndNumGen.nextDouble()*(numberOfAllPairs-i))); 075 iIsConsistent[allPairs[i][0]][allPairs[i][1]] = true; 076 } 077 } 078 079 /** 080 * True if the pair of given values is compatible. 081 */ 082 public boolean isConsistent(Value value1, Value value2) { 083 if (value1==null || value2==null) return true; 084 if (isFirst(value1.variable())) { 085 return iIsConsistent[(int)value1.toDouble()][(int)value2.toDouble()]; 086 } else { 087 return iIsConsistent[(int)value2.toDouble()][(int)value1.toDouble()]; 088 } 089 } 090 091 /** 092 * Add the other variable to the set of conflicts, if it is not compatible with the given value. 093 */ 094 public void computeConflicts(Value aValue, Set conflicts) { 095 if (isFirst(aValue.variable())) { 096 if (!isConsistent(aValue, second().getAssignment())) { 097 conflicts.add(second().getAssignment()); 098 } 099 } else { 100 if (!isConsistent(first().getAssignment(), aValue)) { 101 conflicts.add(first().getAssignment()); 102 } 103 } 104 } 105 106 public String getName() { return "C"+getId(); } 107 }