/*
* 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.");
}
}