001 package ifs.example.csp;
002
003 import ifs.util.*;
004 import ifs.model.*;
005 import java.util.*;
006
007 /**
008 * Random Binary CSP with uniform distribution.
009 * <br><br>
010 * A random CSP is defined by a four-tuple (n, d, p1, p2), where n denotes the number of variables and d denotes the
011 * domain size of each variable, p1 and p2 are two probabilities. They are used to generate randomly the binary
012 * constraints among the variables. p1 represents the probability that a constraint exists between two different
013 * variables and p2 represents the probability that a pair of values in the domains of two variables connected by a
014 * constraint are incompatible.
015 * <br><br>
016 * We use a so called model B of Random CSP (n, d, n1, n2) where n1 = p1*n*(n-1)/2 pairs of variables are randomly
017 * and uniformly selected and binary constraints are posted between them. For each constraint, n2 = p1*d^2 randomly
018 * and uniformly selected pairs of values are picked as incompatible.
019 *
020 * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
021 * @version 1.0
022 */
023 public class CSPModel extends Model {
024
025 /**
026 * Constructor
027 * @param nrVariables number of variables in the problem
028 * @param nrValues number of values of each variable
029 * @param nrConstraints number of constraints in the problem
030 * @param nrCompatiblePairs number of compatible pairs of values for every constraint
031 * @param seed seed for random number generator (use {@link System#currentTimeMillis} if not bother)
032 */
033 public CSPModel(int nrVariables, int nrValues, int nrConstraints, int nrCompatiblePairs, long seed) {
034 generate(nrVariables, nrValues, nrConstraints, nrCompatiblePairs, seed);
035 }
036
037 private void swap(Variable[][] allPairs, int first, int second) {
038 Variable[] a = allPairs[first];
039 allPairs[first]=allPairs[second];
040 allPairs[second]=a;
041 }
042
043 private void buildBinaryConstraintGraph(Random rnd) {
044 int numberOfAllPairs = variables().size()*(variables().size()-1)/2;
045 Variable[][] allPairs = new Variable[numberOfAllPairs][];
046 int idx=0;
047 for (Enumeration i1=variables().elements();i1.hasMoreElements();) {
048 Variable v1 = (Variable)i1.nextElement();
049 for (Enumeration i2=variables().elements();i2.hasMoreElements();) {
050 Variable v2 = (Variable)i2.nextElement();
051 if (v1.getId()>=v2.getId()) continue;
052 allPairs[idx++]=new Variable[] {v1,v2};
053 }
054 }
055 idx = 0;
056 for (Enumeration i1=constraints().elements();i1.hasMoreElements();) {
057 CSPBinaryConstraint c = (CSPBinaryConstraint) i1.nextElement();
058 swap(allPairs, idx, idx+(int)(rnd.nextDouble()*(numberOfAllPairs-idx)));
059 c.addVariable(allPairs[idx][0]);
060 c.addVariable(allPairs[idx][1]);
061 c.init(rnd);
062 idx++;
063 }
064 }
065
066 private void generate(int nrVariables, int nrValues, int nrConstraints, int nrCompatiblePairs, long seed) {
067 Random rnd = new Random(seed);
068
069 for (int i=0;i<nrVariables;i++) {
070 CSPVariable var = new CSPVariable(i+1,nrValues);
071 addVariable(var);
072 }
073
074 for (int i=0;i<nrConstraints;i++) {
075 CSPBinaryConstraint c = new CSPBinaryConstraint(i+1,nrCompatiblePairs);
076 addConstraint(c);
077 }
078
079 buildBinaryConstraintGraph(rnd);
080 }
081 }