Package fuzzysat

Source Code of fuzzysat.CPBeamSolver

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package fuzzysat;

import evaluation.RandomProblemGenerator;
import evaluation.Visualiser;
import java.util.*;
import expressions.*;
import operators.*;
import util.*;

/**
*
* @author patriciavictor
*
* This solver combines basic techniques from constraint propagation (CP) with
* beam search, a heuristic search algorithm that explores a graph by expanding
* the most promising nodes in a limited set (=the beam).  Each level in the
* newBeam represents a variable that must be expanded.  The domain of each variable
* is an interval.
*/
public class CPBeamSolver implements FuzzySATSolver {

    static Random rand = new Random();
    List<FuzzyClause> constraints;
    String[] variables;
    Map<String, Double> interpretation; //the final interpretation (maps variables to membership degrees)
    Map<String, Double> lower_interpr; // the current interpretation (maps variables to intervals)
    Map<String, Double> upper_interpr;
    int beamHeuristic; //method to select the best children (see BeamPart.java)
    int beamwidth; //width of the beam (number of nodes to expand at each level)
    int splitfactor; //degree of expansion: determines how many subintervals are generated for each node in newBeam
    int varHeuristic; //heuristic for selecting the next variable to expand
    int maxFinalSolutionTries; //maximum number of tries to find a value for the variable after BeamSearch (see getFinalSolution)
    double epsilon; //required accuracy.  Standard=0.0001.  The smaller the value, the more accurate the results.
    double pRandomValueForVar; //value between 0 and 1 that determines how often random values are tried as possible solution (see continueBeam)
    int maxBeamTries; //maximum number of tries for beam search
    BeamPartComparator comp; //comparator for the parts in the beam (based on beamHeuristic)

    /**
     *
     * @param constraints
     * @param beamHeuristic number to select the heuristic for the beam (see BeamPart.java)
     * @param beamwidth
     * @param splitfactor
     * @param pRandomValueForVar value between 0 and 1 that determines how often values are tried as possible solution
     * @param maxBeamTries max number of tries for beam search
     * @param varHeuristic number to select the heuristic for the next variable for expansion.
     * 1=degree heuristic: choose the var which occurs most in constraints which have the most unexpanded vars
     * 3=most independent var
     * 4=random
     */
    public CPBeamSolver(List<FuzzyClause> constraints, int beamHeuristic, int beamwidth, int splitfactor, int varHeuristic, int maxFinalSolutionTries, double epsilon, double pRandomValueForVar, int maxBeamTries) {
        this.constraints = constraints;
        lower_interpr = new HashMap<String, Double>();
        upper_interpr = new HashMap<String, Double>();
        Set<String> vars = new HashSet();
        for (FuzzyClause fl : constraints) {
            vars.addAll(fl.getAllVariables());
        }
        variables = vars.toArray(new String[0]);
        for (String var : variables) {
            lower_interpr.put(var, 0.0);
            upper_interpr.put(var, 1.0);
        }
        this.beamHeuristic = beamHeuristic;
        this.beamwidth = beamwidth;
        this.splitfactor = splitfactor;
        this.varHeuristic = varHeuristic;
        interpretation = new HashMap<String, Double>();
        this.maxFinalSolutionTries = maxFinalSolutionTries;
        this.epsilon = epsilon;
        this.pRandomValueForVar = pRandomValueForVar;
        this.maxBeamTries = maxBeamTries;
        comp = new BeamPartComparator(beamHeuristic, constraints);
    }

    /*
     * Return a model for the constraints if possible, null otherwise
     *
     */
    public Map<String, Double> findFuzzyModel() {
        AccuracyAbstract.setAccuracy(epsilon);
        //pre: remove trivially satisfiable clauses
        Set<String> positiveVariables = new HashSet();
        Set<String> negativeVariables = new HashSet();
        for (FuzzyClause fc : constraints) {
            if (fc.getDisjuncts().size() > 1) {
                throw new UnsupportedOperationException();
            }
            positiveVariables.addAll(fc.getPositiveVariables());
            negativeVariables.addAll(fc.getNegativeVariables());
        }

        Set<String> intersection = new HashSet();
        intersection.addAll(positiveVariables);
        intersection.retainAll(negativeVariables);
        positiveVariables.removeAll(intersection);
        negativeVariables.removeAll(intersection);
        for (int i = 0; i < constraints.size(); i++) {
            FuzzyClause fc = constraints.get(i);
            List<Literal> disjuncts = fc.getDisjuncts();
            for (int j = 0; j < disjuncts.size(); j++) {
                Literal li = disjuncts.get(j);
                if (li.alwaysSatisfiable(positiveVariables, negativeVariables)) {
                    constraints.remove(i);
                    i--;
                    break;
                }
            }
        }

        for (FuzzyClause newcon : constraints) {
            newcon.normalise();
        }

        //1. initial CP
        //toBasicConstraints(); + algoIP1(); Deze methodes zijn te traag.
        boolean inconsistency = cp();//De versie van steven
        if (inconsistency) {
            System.out.println("no solution");
            return null;
        }

        //2. beam search algorithm combined with CP
        System.out.println("begin beam with beamwidth= " + beamwidth + " and splitting= " + splitfactor + " and randomvalue= " + pRandomValueForVar + " and maxBeamRounds= " + maxBeamTries + " and maxFinalSolutionRounds= " + maxFinalSolutionTries);
        int numberOfTries = 0;
        boolean noSolution = true;
        while (numberOfTries < maxBeamTries && noSolution) {
            noSolution = false;
            numberOfTries++;
            HashSet<BeamPart> possibleSolutions = beamSearch();
            if (possibleSolutions == null) {
                noSolution = true;
                System.out.println("eind beam ronde NULL " + numberOfTries);
            } else {
                System.out.println("eind beam ronde " + numberOfTries);
                System.out.println("===========================");
                System.out.println("aantal delen in finale beam: " + possibleSolutions.size());

                //3. selection of interpretation
                if (possibleSolutions.size() == 0) {
                    noSolution = true;
                } else {
                    Pair<Map<String, Double>, Map<String, Double>> result = null;
                    for (BeamPart part : possibleSolutions) {
                        //solution not yet found
                        lower_interpr = part.getLowerBounds();
                        upper_interpr = part.getUpperBounds();
                        HashSet<String> variablesForFinalSolution = new HashSet<String>();
                        for (String v : variables) {
                            variablesForFinalSolution.add(v);
                        }
                        result = getFinalSolution(lower_interpr, upper_interpr, variablesForFinalSolution);
                        if (result != null) {
                            break;
                        }
                    }
                    System.out.println("number of beam round tries: " + numberOfTries);
                    if (result != null) {
                        System.out.println("solution: ");
                        for (String var : interpretation.keySet()) {
                            System.out.println(var + "=" + interpretation.get(var));
                        }
                        AccuracyAbstract.restoreAccuracy();
                        return interpretation;
                    } else {
                        noSolution = true;
                    }
                }
            }
        }
        AccuracyAbstract.restoreAccuracy();
        if (noSolution) {
            System.out.println("no solution found");
            return null;
        } else {
            return interpretation;
        }
    }

    /**
     * Beam search algorithm, with beamwidth and beamHeuristic.
     * @return Parts of the search newBeam that might contain solutions.
     */
    public HashSet<BeamPart> beamSearch() {
        HashSet<String> varsToBeExpanded = new HashSet<String>();
        for (String v : variables) {
            varsToBeExpanded.add(v);
        }
        String v = chooseNextVar(varsToBeExpanded);
        BeamPart p = new BeamPart(new HashMap<String, Double>(lower_interpr), new HashMap<String, Double>(upper_interpr), v, comp);
        p.expandNode(splitfactor, beamwidth, constraints, beamHeuristic);
        TreeSet tree = (TreeSet<BeamPart>) p.getChildren();
        HashSet<BeamPart> beam = new HashSet<BeamPart>();
        if (tree.size() <= beamwidth) {
            beam.addAll(tree);
        } else {
            for (int i = 1; i <= beamwidth; i++) {
                beam.add((BeamPart) tree.pollFirst());
            }
        }
        if (beam.size() != 0) {
            beam = continueBeam(beam, varsToBeExpanded);
        } else {
            beam = null;
        }
        return beam;
    }

    /**
     * Performs beam search on the set beam.  When completed,
     * beam contains possible solutions, each with their own domains.
     * @param beam Set of nodes (beamparts) to be expanded
     * @param varsToBeExpanded Set of remaining vars
     * @return returns the final beam
     */
    public HashSet<BeamPart> continueBeam(HashSet<BeamPart> beam, HashSet<String> varsToBeExpanded) {
        String v = chooseNextVar(varsToBeExpanded);
        if (v != null) {
            TreeSet newBeam = new TreeSet(comp);
            for (BeamPart part : beam) {
                if (rand.nextDouble() < pRandomValueForVar) {
                    //guess interpretation
                    HashMap<String, Double> randominterpr = new HashMap<String, Double>();
                    for (String var : variables) {
                        double original_lower = part.getLowerBounds().get(var);
                        double original_upper = part.getUpperBounds().get(var);
                        double value = original_lower + rand.nextDouble() * (original_upper - original_lower);
                        randominterpr.put(var, value);
                    }
                    boolean inconsistency = false;
                    for (FuzzyClause fc : constraints) {
                        if (!fc.isSatisfied(randominterpr)) {
                            inconsistency = true;
                            break;
                        }
                    }
                    if (!inconsistency) {
                        HashSet<BeamPart> setje = new HashSet<BeamPart>();
                        setje.add(new BeamPart(randominterpr, randominterpr, null, comp));
                        return setje;
                    }
                }
                part.setName(v);
                part.expandNode(splitfactor, beamwidth, constraints, beamHeuristic);
                TreeSet<BeamPart> children = (TreeSet<BeamPart>) part.getChildren();
                for (BeamPart child : children) {
                    if (newBeam.size() < beamwidth) {
                        newBeam.add(child);
                    } else {
                        BeamPart last = (BeamPart) newBeam.last();
                        if (child.heuristic(beamHeuristic, constraints) < last.heuristic(beamHeuristic, constraints)) {
                            newBeam.remove(last);
                            newBeam.add(child);
                        }
                    }
                }
            }
            if (newBeam.size() != 0) {
                return continueBeam(new HashSet<BeamPart>(newBeam), varsToBeExpanded);
            } else {
                return null;
            }
        } else {
            //if v==null: all variables are expanded
            return beam;
        }
    }

    /**
     * Determines values within the reduced domains for each variable (saved in attribute interpretation).
     * @param l current lower bounds
     * @param u current upper bounds
     * @param vars list of variables for which random value must still be chosen
     * @return updated upper and lower bounds (which are equal), or null if solution is not obtained after maxFinalSolutionTries tries.
     */
    public Pair<Map<String, Double>, Map<String, Double>> getFinalSolution(Map<String, Double> l, Map<String, Double> u, HashSet<String> vars) {
        if (vars.isEmpty()) {
            return new Pair(l, u);
        } else {
            int count = 1;
            String nextvar = selectVarSmallestInterval(l, u, vars);
            vars.remove(nextvar);
            boolean lastvar = vars.isEmpty();
            double original_lower = l.get(nextvar);
            double original_upper = u.get(nextvar);
            boolean onlyOnePossibleValue = false; //no need to pick random values, there is just one right value
            boolean inconsistency = true;
            Map<String, Double> copy_lower = null;
            Map<String, Double> copy_upper = null;
            while (!onlyOnePossibleValue && inconsistency && count <= maxFinalSolutionTries) {
                copy_lower = new HashMap<String, Double>(l);
                copy_upper = new HashMap<String, Double>(u);
                inconsistency = false;
                onlyOnePossibleValue = (java.lang.Math.abs(original_lower - original_upper) < AccuracyAbstract.accuracy);
                double valueForNextvar = (onlyOnePossibleValue ? original_lower : (original_lower + rand.nextDouble() * (original_upper - original_lower)));
                copy_lower.put(nextvar, valueForNextvar);
                copy_upper.put(nextvar, valueForNextvar);
               // l.put(nextvar, valueForNextvar);
                //u.put(nextvar, valueForNextvar);
                interpretation.put(nextvar, valueForNextvar);
                Boolean changed = true;
                if (lastvar) {
                    for (FuzzyClause fc : constraints) {
                        if (!fc.isSatisfied(interpretation)) {
                            inconsistency = true;
                            break;
                        }
                    }
                } else {
                    while (changed) {
                        changed = false;
                        for (FuzzyClause fc : constraints) {
                            if (fc.numberOfDisjuncts() == 1) {
                                Literal lit = fc.getDisjunct(0);
                                if (lit instanceof FuzzyLiteral) {
                                    Boolean changed1 = ((FuzzyLiteral) lit).improveBounds(copy_lower, copy_upper);
                                    if (changed1 == null) {
                                        inconsistency = true;
                                        break;
                                    } else {
                                        changed = changed || changed1;
                                    }
                                }
                            }
                        }
                        if (inconsistency) {
                            break; //and try another random value
                        }
                    }
                }
                count++;
            }
            if (!inconsistency) {
               return getFinalSolution(new HashMap<String, Double>(copy_lower), new HashMap<String, Double>(copy_upper), vars);
                // return getFinalSolution(new HashMap<String, Double>(l), new HashMap<String, Double>(u), vars);
            } else {
                return null;
            }
        }
    }

    /**
     * selects the variable with the smallest interval (the one with the
     * smallest number of possible solutions).
     * @param vars set of variables to choose from
     * @param lower current lower interpretations (intervals)
     * @param upper current upper interpretations (intervals)
     * @return variable in vars with smallest interval, null if no variables left
     */
    public String selectVarSmallestInterval(Map<String, Double> lower, Map<String, Double> upper, HashSet<String> vars) {
        if (vars.isEmpty()) {
            return null;
        } else {
            double length = java.lang.Double.MAX_VALUE;
            String smallestVar = null;
            for (String v : vars) {
                if (upper.get(v) - lower.get(v) < length) {
                    smallestVar = v;
                    length = upper.get(v) - lower.get(v);
                }
            }
            return smallestVar;
        }
    }

    /**
     * Determines the next best variable to expand according to attribute
     * @param vars the set of variables to choose from.
     * @return next variable to expand, null if no options left.
     */
    public String chooseNextVar(HashSet<String> vars) {
        if (vars.isEmpty()) {
            return null;
        }
        if (varHeuristic == 1) {
            //degree heuristic: choose the var which occurs most often in constraints
            List<String> bestVariables = new ArrayList();
            int bestScore = -1;
            for (String nextVar : vars) {
                int score = 0;
                for (FuzzyClause fc : constraints) {
                    if (fc.numberOfDisjuncts() == 1) {
                        Literal lit = fc.getDisjunct(0);
                        if (lit.getAllVariables().contains(nextVar)) {
                            score++;
                        }
                    }
                }
                if (score > bestScore) {
                    bestVariables = new ArrayList();
                    bestVariables.add(nextVar);
                    bestScore = score;
                } else if (bestScore == score) {
                    bestVariables.add(nextVar);
                }
            }
            if (bestVariables.size() == 0) {
                return null; // no suitable variables left
            } else {
                String res = bestVariables.get(rand.nextInt(bestVariables.size()));
                vars.remove(res);
                return res;
            }
        } else if (varHeuristic == 3) {
            //most independent variable
            List<String> bestVariables = new ArrayList();
            int bestScore = -1;
            for (String nextVar : vars) {
                int score = 0;
                for (FuzzyClause fc : constraints) {
                    if (fc.numberOfDisjuncts() == 1) {
                        Literal lit = fc.getDisjunct(0);
                        if (lit.getAllVariables().contains(nextVar)) {
                            score++;
                        }
                    }
                }
                if (bestScore < 0 || score < bestScore) {
                    bestVariables = new ArrayList();
                    bestVariables.add(nextVar);
                    bestScore = score;
                } else if (bestScore == score) {
                    bestVariables.add(nextVar);
                }
            }
            if (bestVariables.size() == 0) {
                return null; // no suitable variables left
            } else {
                String res = bestVariables.get(rand.nextInt(bestVariables.size()));
                vars.remove(res);
                return res;
            }

        } else if (varHeuristic == 2) {
            //not yet implemented
            return null;
        } else {
            //4: random
            String res = new ArrayList<String>(vars).get(rand.nextInt(vars.size()));
            vars.remove(res);
            return res;
        }
    }

    /**
     * Uses CP techniques to reduce the domains + detects inconsistency.
     * @return true if inconsistency arises, false otherwise
     */
    public boolean cp() {
       // HashMap<String, Double> l = new HashMap<String, Double>(lower_interpr);
        //HashMap<String, Double> u = new HashMap<String, Double>(upper_interpr);
        Boolean changed = true;
        boolean inconsistency = false;
        while (changed) {
            changed = false;
            for (FuzzyClause fc : constraints) {
                if (fc.numberOfDisjuncts() == 1) {
                    Literal lit = fc.getDisjunct(0);
                    if (lit instanceof FuzzyLiteral) {
                        Boolean changed1 = ((FuzzyLiteral) lit).improveBounds(lower_interpr, upper_interpr);
                        if (changed1 == null) {
                            inconsistency = true;
                            break;
                        } else {
                            changed = changed || changed1;
                        }

                    }
                }
            }
            if (inconsistency) {
                break;
            }

        }
        return inconsistency;
    }

    public List<FuzzyClause> getTransformedConstraints() {
        return constraints;
    }


//***********************TESTS VERGELIJKINGEN***************************************************
    public void printBoundaries() {
        System.out.println("---------------------------------------------");
        for (String var : variables) {
            //if(lower_interpr.get(var)>upper_interpr.get(var))
            System.out.println(var + ": " + lower_interpr.get(var) + "--" + upper_interpr.get(var));
        }
    }

    public void testWithRandomConstraints3() {
        //based on code sarah
        //Make Visualiser for chartcreation
        // Visualiser vis = new Visualiser("Percentage of failures with increasing number of clauses for SIMPLE constraints",
        //        "Number of clauses", "Percentage of failures");
        Visualiser visTime = new Visualiser("Mean calculation time with increasing number of clauses (max number of variables=max number of constraints",
                "Number of clauses", "Mean calculation time");
        Random rand = new Random(0);
        for (int i = 1; i <= 25; i++) {
            // for (int i = 1; i <= 96; i += 5) {
            System.out.println("klasse " + i);
            //i--> number of constraints (class from i to i+4)
            double sumBeam = 0, sumBasic = 0;
            for (int k = 1; k <=
                    100; k++) {
                //for each constraint class 100 cp cases
                int numberOfConstraints = i;//i + rand.nextInt(i + 3);
                int numberOfVariables = (i == 1 ? 1 : (1 + rand.nextInt(i - 1)));//rand.nextInt(i + 3);
                int numberOfVariablesPerClause = (i == 1 ? 1 : (1 + rand.nextInt(i - 1)));//rand.nextInt(i + 3);
                List<FuzzyLiteral> l = RandomProblemGenerator.getRandomSatisfiableConstraints3(numberOfConstraints, numberOfVariables, 0.5, numberOfVariablesPerClause);
                List<FuzzyClause> constraintslist = new ArrayList<FuzzyClause>(); //for beam version
                for (FuzzyLiteral f : l) {
                    constraintslist.add(new FuzzyClause(f));
                }

                List<FuzzyClause> constraintslist2 = new ArrayList<FuzzyClause>(); //for basic version
                for (FuzzyLiteral f : l) {
                    constraintslist2.add(new FuzzyClause(new FuzzyLiteral(f)));
                }
                //start beam
                double start = System.currentTimeMillis();
                CPBeamSolver beam = new CPBeamSolver(constraintslist, 1, 1, 1, 1, 200, 0.0001, 0.5, 100);
                beam.findFuzzyModel();
                double end = System.currentTimeMillis();
                sumBeam += (end - start);
                //start basic
                start = System.currentTimeMillis();
                CPBeamSolver basic = new CPBeamSolver(constraintslist2, 1, 1, 1, 1, 200, 0.0001, 0.5, 100);
                basic.findFuzzyModelTest();
                end = System.currentTimeMillis();
                sumBasic += (end - start);
            }
            visTime.setValue("Beam IP-1", 0.0 + i, sumBeam / 100);//((0.0 + i) / 4) + 1, sumBeam / 100);
            visTime.setValue("Basic", 0.0 + i, sumBasic / 100);//((0.0 + i) / 4) + 1, sumBasic / 100);
        }
        visTime.saveChart("FilesPat/BeamVersusBasic(NoTransformationToBasicConstraints)_NumberOfConstraints(maxVariables=maxConstraints)");
    }

    //====================================OUDE VERSIES EN/OF BROL=================================
    /**
     * IP-1 algorithm of "Consistency techniques for numeric CSPs" (Lhomme),
     * which tries to reduce the domains of each variable until arc B-consistency.
     * Attribute termination determines the termination procedure for the IP-1 algo,
     * is used as a trade off between the initial constraint propagation and the
     * actual beam search.
     * Note that the algorithm is adjusted (the agenda only contains constraints,
     * no variables), since improveBounds improves the bounds for all the variables
     * of a constraint (instead of only the bounds of one variable in the constraint).
     *
     */
    public void algoIP1() {
        HashSet<Literal> agenda = new HashSet<Literal>();
        for (FuzzyClause clause : constraints) {
            agenda.addAll(clause.getDisjuncts());
        }
        while (!agenda.isEmpty()) {
            HashSet<FuzzyLiteral> newset = new HashSet<FuzzyLiteral>();
            for (Iterator it = agenda.iterator(); it.hasNext();) {
                FuzzyLiteral p1 = (FuzzyLiteral) it.next();
                it.remove();
                HashSet<String> result = null; //result=revise(p1); PAT: NOG AANPASSEN.
                //revise is het oproepen van improvebounds tot geen verandering meer +
                //geeft een set van vars terug die veranderd zijn.
                //De improveBounds methodes moeten dan ook zo een set teruggeven.
                if (result == null) {
                    break;
                } else {
                    for (FuzzyClause clause : constraints) {
                        if (clause.numberOfDisjuncts() == 1) {
                            Literal lit = clause.getDisjunct(0);
                            if (lit != p1) {
                                HashSet<String> allvars = new HashSet<String>(lit.getAllVariables());
                                allvars.retainAll(result);
                                if (!allvars.isEmpty()) {
                                    newset.add((FuzzyLiteral) lit);
                                }

                            }
                        }
                    }
                }
            }
            agenda.addAll(newset);
        /*
        FuzzyLiteral p1 = (FuzzyLiteral) agenda.get(0);
        agenda.remove(0);
        HashSet<String> result = revise(p1);
        teller++;
        if (result == null) {
        break;
        } else {
        for (FuzzyClause clause : constraints) {
        for (Literal lit : clause.getDisjuncts()) {
        if (lit != p1) { //do not point to the same object
        HashSet<String> allvars = new HashSet<String>(lit.getAllVariables());
        allvars.retainAll(result);
        if (!allvars.isEmpty()) {
        // if (containsOneOf(lit.getAllVariables(), result)) {
        // if(!(((new HashSet<String>(lit.getAllVariables())).retainAll(result)).isEmpty()))
        if (!agenda.contains(lit)) {
        agenda.add((FuzzyLiteral) lit);
        }
        }
        }
        }
        }
        }
         */
        }
// System.out.println("aantal checks: " + teller);

    }

    //public HashSet<String> revise(FuzzyLiteral p) {
    //  HashSet<String> changedvars = new HashSet<String>();
    //Boolean result = p.improveBounds(lower_interpr, upper_interpr, changedvars);
    // if (result == null) {
    //   return null;
    //}

    //return changedvars;
    /*f
    if (result) {
    for (String var : p.getAllVariables()) {
    double lower_new = lower_interpr.get(var);
    double upper_new = upper_interpr.get(var);
    if (java.lang.Math.abs(lower_original.get(var) - lower_new) > termination || java.lang.Math.abs(upper_original.get(var) - upper_new) > termination) {
    changedvars.add(var);
    //since we introduce termination, it is not always possible to describe
    //the status of the domains after IP-1 (whether the problem is now
    //arc B-consistent or not)
    }
    }
    }
    return changedvars;
     */
    //}
    public boolean containsOneOf(Set<String> all, Set<String> vars) {
        boolean res = false;
        for (String var : vars) {
            if (all.contains(var)) {
                return true;
            }

        }
        return res;
    }

    /*
     * The IP-1 algorithm of Lhomme requires basic constraints, meaning
     * that a constraint cannot contain more than one occurrence of a variable.
     * This method transforms the list of constraints to basic constraints.
     */
    public void toBasicConstraints() {
        HashSet<String> allvars = new HashSet();
        for (FuzzyClause fl : constraints) {
            allvars.addAll(fl.getAllVariables());
        }

        ArrayList<FuzzyClause> newconstraints = new ArrayList<FuzzyClause>();
        for (FuzzyClause fc : constraints) {
            HashSet<String> copyvars = new HashSet<String>();
            copyvars.addAll(fc.getAllVariables());
            for (Literal lit : fc.getDisjuncts()) {
                if (lit instanceof FuzzyLiteral) {
                    FuzzyExpression expr = ((FuzzyLiteral) lit).getExpression();
                    checkMultipleOccurences(expr, allvars, copyvars, newconstraints);
                }

            }
        }
        constraints.addAll(newconstraints);
        for (FuzzyClause con : constraints) {
            con.normalise();
        }

        variables = allvars.toArray(new String[0]);
        for (String var : variables) {
            lower_interpr.put(var, 0.0);
            upper_interpr.put(var, 1.0);
        }

    }

    public void checkMultipleOccurences(FuzzyExpression expr, HashSet<String> allvars, HashSet<String> copyvars, ArrayList<FuzzyClause> newconstraints) {
        try {
            if (!(expr instanceof FuzzyConstantExpression)) {
                if (expr instanceof FuzzyUnaryExpression) {
                    checkMultipleOccurences(((FuzzyUnaryExpression) expr).getArgument(), allvars, copyvars, newconstraints);
                } else if (expr instanceof FuzzyBinaryExpression) {
                    checkMultipleOccurences(((FuzzyBinaryExpression) expr).getArgument1(), allvars, copyvars, newconstraints);
                    checkMultipleOccurences(((FuzzyBinaryExpression) expr).getArgument2(), allvars, copyvars, newconstraints);
                } else if (expr instanceof FuzzyVariableExpression) {
                    String name = ((FuzzyVariableExpression) expr).getName();
                    boolean inset = copyvars.remove(name);
                    if (!inset) {
                        //this means that the variable name has already occurred in this constraint
                        String newname = findNewVarName(allvars);
                        ((FuzzyVariableExpression) expr).changeName(newname);
                        //name must equal newname:
                        newconstraints.add(new FuzzyClause(new FuzzyLiteral(1.0, 1.0, new FuzzyBinaryExpression(new FuzzyVariableExpression(name), new FuzzyVariableExpression(newname), new IW()))));
                        newconstraints.add(new FuzzyClause(new FuzzyLiteral(1.0, 1.0, new FuzzyBinaryExpression(new FuzzyVariableExpression(newname), new FuzzyVariableExpression(name), new IW()))));
                        copyvars.add(newname);
                        allvars.add(newname);
                    }

                } else {
                    throw new Exception("checkMultipleOccurences: unsupported data type");
                }

            }
        } catch (Exception e) {
            System.out.println("Exception in CPBeamSolver: " + e);
        }

    }

    public String findNewVarName(
            HashSet<String> allvars) {
        //PAT: this is very basic, must be adjusted
        int teller = 0;
        String newname = "n" + teller;
        while (allvars.contains(newname)) {
            teller++;
            newname = "n" + teller;
        }
        return newname;
    }
    /*
    public void algoIP1() {
    ArrayList<Pair<FuzzyLiteral, String>> agenda = new ArrayList<Pair<FuzzyLiteral, String>>();
    for (FuzzyClause clause : constraints) {
    for (Literal lit : clause.getDisjuncts()) {
    for (String var : lit.getAllVariables()) {
    agenda.add(new Pair(lit, var));
    }
    }
    }
    int teller = 0;
    while (!agenda.isEmpty()) {
    Pair<FuzzyLiteral, String> p = agenda.get(0);
    agenda.remove(0);
    FuzzyLiteral p1 = p.a;
    String p2 = p.b;
    Boolean result = revise(p);
    teller++;
    if (result == null) {
    break;
    }
    if (result) {
    for (FuzzyClause clause : constraints) {
    for (Literal lit : clause.getDisjuncts()) {
    if (lit != p1) { //do not point to the same object
    Set<String> allvars = lit.getAllVariables();
    if (allvars.contains(p.b)) {
    for (String var : allvars) {
    if (!var.equals(p.b)) {
    agenda.add(new Pair(lit, var));
    }
    }
    }
    }
    }
    }
    }
    }
    System.out.println("aantal checks: " + teller);
    }

    public Boolean revise(Pair<FuzzyLiteral, String> p) {
    //System.out.println("behandelen van fuzzyliteral "+p.a.toString());
    double lower_original = lower_interpr.get(p.b);
    double upper_original = upper_interpr.get(p.b);
    Boolean result = p.a.improveBounds(lower_interpr, upper_interpr);
    if (result == null) {
    return null;
    }
    double lower_new = lower_interpr.get(p.b);
    double upper_new = upper_interpr.get(p.b);
    if (java.lang.Math.abs(lower_original - lower_new) > termination || java.lang.Math.abs(upper_original - upper_new) > termination) {
    return true;
    //since we introduce termination, it is not always possible to describe
    //the status of the domains after IP-1 (whether the problem is now
    //arc B-consistent or not)
    }
    return false;
    }
     */

    public Map<String, Double> findFuzzyModelTest() {
        //pre: remove trivially satisfiable clauses
        int originalsize = constraints.size();
        Map<String, Double> trivialAssignments = new HashMap<String, Double>();
        Set<String> positiveVariables = new HashSet();
        Set<String> negativeVariables = new HashSet();
        for (FuzzyClause fc : constraints) {
            if (fc.getDisjuncts().size() > 1) {
                throw new UnsupportedOperationException();
            }

            positiveVariables.addAll(fc.getPositiveVariables());
            negativeVariables.addAll(fc.getNegativeVariables());
        }

        Set<String> intersection = new HashSet();
        intersection.addAll(positiveVariables);
        intersection.retainAll(negativeVariables);
        positiveVariables.removeAll(intersection);
        negativeVariables.removeAll(intersection);
        for (int i = 0; i <
                constraints.size(); i++) {
            FuzzyClause fc = constraints.get(i);
            List<Literal> disjuncts = fc.getDisjuncts();
            for (int j = 0; j <
                    disjuncts.size(); j++) {
                Literal li = disjuncts.get(j);
                if (li.alwaysSatisfiable(positiveVariables, negativeVariables)) {
                    constraints.remove(i);
                    i--;

                    break;

                }


            }
        }
        //System.out.println("aantal trivial clauses removed: " + (originalsize - constraints.size()));

        //cp
        //double startTime = System.currentTimeMillis();
        //System.out.println("bounds after standard initial constraint propgation");
        //Set<String> vars = new HashSet();
        //for (FuzzyClause fl : constraints) {
        //  vars.addAll(fl.getAllVariables());
        // }
        //variables = vars.toArray(new String[0]);
        // System.out.println("variables!!!");
        //for (String var : variables) {
        //   System.out.println(var);
        //  lower_interpr.put(var, 0.0);
        //upper_interpr.put(var, 1.0);
        //}
        for (FuzzyClause newcon : constraints) {
            newcon.normalise();
        }

        cp();
        //double endTime = System.currentTimeMillis();
        //System.out.println("====time:" + (endTime - startTime) + "====");
        //for (String var : variables) {
        //  double low = lower_interpr.get(var);
        //double up = upper_interpr.get(var);
        //System.out.println(var + ": " + low + "--" + up);
        // }
        return null;
    }

    @Override
    public void setTimeout(long timeoutSec) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
TOP

Related Classes of fuzzysat.CPBeamSolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.