/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package evaluation;
import csp.backends.TailorSolver;
import expressions.FuzzyVariableExpression;
import expressions.FuzzyBinaryExpression;
import expressions.FuzzyConstantExpression;
import expressions.FuzzyUnaryExpression;
import expressions.FuzzyExpression;
import java.util.*;
import util.*;
import fuzzysat.*;
import operators.*;
import java.io.*;
import finiteReduction.*;
/**
*
* @author sschocka
*/
public class RandomProblemGenerator {
static Random rand = new Random();
public static double STEP_VAR = 0.125;
public static double STEP_CONST = 0.25;
public static int nrDegrees = (int) Math.round(1 / STEP_CONST);
public static void main(String[] args) {
TailorSolver.PPLEVELNUMBER = TailorSolver.PPLEVEL.GAC;
TailorSolver.VARORDERNUMBER = TailorSolver.VARORDER.SDF;
for (int nrVariables = 25; nrVariables <= 100; nrVariables += 25) {
for (int nrVarsPerClause = 5; nrVarsPerClause <= 5; nrVarsPerClause++) {
for (int nrConstraints = 100; nrConstraints <= 100; nrConstraints += 10) {
for (int pMinimum = 0; pMinimum <= 10; pMinimum+=2) {
// int nrConstraints = nrVariables/2;
int nrSatisfiableConstraints = (int) (nrConstraints - 10);
System.out.println("nrVariables = " + nrVariables);
System.out.println("vars-per-clause = " + nrVarsPerClause);
System.out.println("nrConstraints = " + nrConstraints);
generateMixedProblems(nrConstraints, nrVariables, 0.5, pMinimum, nrVarsPerClause);
// try {
// Thread.sleep(300000);
// }
// catch (Exception e) {
// }
}
}
}
}
}
public static void generateMixedProblems(int nrConstraints, int nrVariables,
double pNegation, int pMinimum, int nrVarsPerClause) {
String dirName = "dataset/random/" + nrConstraints + "-" + nrVariables + "-" + nrVarsPerClause + "-" + pMinimum + "/";
File dir = new File(dirName);
if (!dir.exists())
dir.mkdir();
int nrNonTrivial = 0;
while (nrNonTrivial < 50) {
List<FuzzyLiteral> problem = getMixedRandomSemiSatisfiableConstraints(nrConstraints, nrVariables, pNegation, pMinimum * 0.1, nrVarsPerClause);
List<FuzzyClause> constraints = new ArrayList();
for (FuzzyLiteral lit : problem)
constraints.add(new FuzzyClause(lit));
boolean changed = true;
Map<String, Double> trivialAssignments = new HashMap();
while (changed) {
DomainFinder.simplify(constraints);
changed = DomainFinder.eliminateTriviallySatisfiableClauses(constraints, trivialAssignments);
}
// if (constraints.size() > 1 && CompleteMinionSolver.findSubmodel(constraints, 1, nrDegrees, 300) == null) {
// writeConstraintsToFile(problem, new File(dirName + "problem" + nrNonTrivial + ".txt"));
// nrNonTrivial++;
// }
// if (constraints.size() > 1) {
// try {
// Thread.sleep(1000);
// }
// catch (Exception e) {
// }
// }
if(constraints.size() > 1){
writeConstraintsToFile(problem, new File(dirName + "problem" + nrNonTrivial + ".txt"));
nrNonTrivial++;
}
}
}
public static void generateHardProblems(int nrConstraints, int nrVariables,
double pNegation, int nrVarsPerClause, int nrSatisfiableConstraints) {
String dirName = "dataset/randomHard/" + nrConstraints + "-" + nrVariables + "-" + nrVarsPerClause + "-" + pNegation + "-" + nrSatisfiableConstraints + "/";
File dir = new File(dirName);
if (!dir.exists())
dir.mkdir();
for (int i = 0; i < 50; i++) {
File f = new File(dirName + "problem" + i + ".txt");
if (!f.exists()) {
// System.out.println("check 1");
List<FuzzyLiteral> problem = getRandomConstraintsHard(nrConstraints, nrVariables, pNegation, nrVarsPerClause);
List<FuzzyClause> constraints = new ArrayList();
for (FuzzyLiteral lit : problem)
constraints.add(new FuzzyClause(lit));
boolean changed = true;
Map<String, Double> trivialAssignments = new HashMap();
while (changed) {
DomainFinder.simplify(constraints);
changed = DomainFinder.eliminateTriviallySatisfiableClauses(constraints, trivialAssignments);
}
// System.out.println("check 2");
if (CompleteChocoSolver.findSubmodel(constraints, 1, nrDegrees) != null) {
// System.out.println("+");
i--;
}
else if (constraints.size() == 1 && constraints.get(0).getVariables().size() == 0) {
// System.out.println("-");
i--;
}
else {
System.out.println(i + " generated");
writeConstraintsToFile(problem, f);
}
}
}
}
public static List<FuzzyClause> readConstraintsFromFile(File f) {
try {
List<FuzzyClause> l = new ArrayList();
BufferedReader in = new BufferedReader(new FileReader(f));
String line = in.readLine();
while (line != null && !line.equals("")) {
String[] s = line.split(";");
double lowerbound = Double.parseDouble(s[0]);
double upperbound = Double.parseDouble(s[1]);
FuzzyExpression exp = parseExpression(s[2]);
l.add(new FuzzyClause(new FuzzyLiteral(lowerbound, upperbound, exp)));
line = in.readLine();
}
in.close();
return l;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static FuzzyExpression parseExpression(String str) {
str = str.replaceAll("\\(", " ").replaceAll("\\)", "").replaceAll(",", " ");
String[] w = str.split(" ");
Pair<FuzzyExpression, Integer> p = parseExpression(w, 0);
if (p.b != w.length)
System.err.println("WARNING: ILLEGAL FUZZY EXPRESSION 1 (parseExpression/RandomProblemGenerator");
return p.a;
}
public static Pair<FuzzyExpression, Integer> parseExpression(String[] w, int startIndex) {
String head = w[startIndex];
if (head.equals("TW") || head.equals("IW") || head.equals("SW") || head.equals("SM") || head.equals("TM")) {
Pair<FuzzyExpression, Integer> exp1 = parseExpression(w, startIndex + 1);
Pair<FuzzyExpression, Integer> exp2 = parseExpression(w, exp1.b);
if (head.equals("TW"))
return new Pair(new FuzzyBinaryExpression(exp1.a, exp2.a, new TW()), exp2.b);
else if (head.equals("IW"))
return new Pair(new FuzzyBinaryExpression(exp1.a, exp2.a, new IW()), exp2.b);
else if (head.equals("SW"))
return new Pair(new FuzzyBinaryExpression(exp1.a, exp2.a, new SW()), exp2.b);
else if (head.equals("TM"))
return new Pair(new FuzzyBinaryExpression(exp1.a, exp2.a, new TM()), exp2.b);
else if (head.equals("SM"))
return new Pair(new FuzzyBinaryExpression(exp1.a, exp2.a, new SM()), exp2.b);
else {
System.err.println("WARNING: ILLEGAL FUZZY EXPRESSION 2 (parseExpression/RandomProblemGenerator");
return null;
}
}
else if (head.equals("N")) {
Pair<FuzzyExpression, Integer> exp1 = parseExpression(w, startIndex + 1);
return new Pair(new FuzzyUnaryExpression(exp1.a, new N()), exp1.b);
}
else if (head.equals("NM")) {
Pair<FuzzyExpression, Integer> exp1 = parseExpression(w, startIndex + 1);
return new Pair(new FuzzyUnaryExpression(exp1.a, new NM()), exp1.b);
}
else if (!Character.isDigit(head.charAt(0)))
return new Pair(new FuzzyVariableExpression(head), startIndex + 1);
else
return new Pair(new FuzzyConstantExpression(Double.parseDouble(head)), startIndex + 1);
}
public static void writeConstraintsToFile(List<FuzzyLiteral> constraints, File f) {
try {
PrintWriter out = new PrintWriter(new FileWriter(f));
for (int i = 0; i < constraints.size(); i++) {
FuzzyLiteral fl = constraints.get(i);
out.println(fl.getLowerBound() + ";" + fl.getUpperBound() + ";" + fl.getExpression().toString());
}
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
public static List<FuzzyLiteral> getRandomSatisfiableConstraints(int numberOfConstraints, int numberOfVariables,
double pBinary, double pUnary, double pVar,
int maxDepth) {
double pConst = Math.max(0, 1 - pBinary - pUnary - pVar);
Map<String, Double> interpretation = new HashMap();
List<String> variables = new ArrayList();
for (int i = 0; i < numberOfVariables; i++) {
// int m = (int) (1.0 / STEP_VAR);
// double val = ((double) rand.nextInt(m + 1)) / ((double) m);
double val = rand.nextDouble();
interpretation.put("v" + i, val);
variables.add("v" + i);
}
List<FuzzyLiteral> res = new ArrayList();
for (int i = 0; i < numberOfConstraints; i++) {
FuzzyExpression exp = getRandomExpression(variables, pBinary, pUnary, pVar, pConst, maxDepth);
double value = exp.eval(interpretation);
// double upperbound = ceil(value + rand.nextDouble()*(1-value));
// double lowerbound = floor(rand.nextDouble()*value);
double upperbound = ceil(value);
double lowerbound = floor(value);
res.add(new FuzzyLiteral(lowerbound, upperbound, exp));
}
return res;
}
public static List<FuzzyLiteral> getRandomSatisfiableConstraints2(int numberOfConstraints, int numberOfVariables,
double pNegation, int nrVariablesPerClause) {
Map<String, Double> interpretation = new HashMap();
List<String> variables = new ArrayList();
for (int i = 0; i < numberOfVariables; i++) {
// int m = (int) (1.0 / STEP_VAR);
// double val = ((double) rand.nextInt(m + 1)) / ((double) m);
double val = rand.nextDouble();
interpretation.put("v" + i, val);
variables.add("v" + i);
}
List<FuzzyLiteral> res = new ArrayList();
for (int i = 0; i < numberOfConstraints; i++) {
FuzzyExpression exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
//PAT: door onderstaande twee lijnen in commentaar te zetten krijgen we
//ook meerdere voorkomens van een var in 1 clause.
// while (exp.getVariables().size() != nrVariablesPerClause)
// exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
double value = exp.eval(interpretation);
// double upperbound = ceil(value + rand.nextDouble()*(1-value));
// double lowerbound = floor(rand.nextDouble()*value);
double upperbound;
double lowerbound;
if (rand.nextDouble() < 0.5) {
upperbound = ceil(value);
lowerbound = 0;
}
else {
upperbound = 1;
lowerbound = floor(value);
}
res.add(new FuzzyLiteral(lowerbound, upperbound, exp));
}
return res;
}
public static List<FuzzyLiteral> getRandomSatisfiableConstraints3(int numberOfConstraints, int numberOfVariables,
double pNegation, int nrVariablesPerClause) {
Map<String, Double> interpretation = new HashMap();
List<String> variables = new ArrayList();
for (int i = 0; i < numberOfVariables; i++) {
// int m = (int) (1.0 / STEP_VAR);
// double val = ((double) rand.nextInt(m + 1)) / ((double) m);
double val = rand.nextDouble();
interpretation.put("v" + i, val);
variables.add("v" + i);
}
List<FuzzyLiteral> res = new ArrayList();
for (int i = 0; i < numberOfConstraints; i++) {
FuzzyExpression exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
// while (exp.getVariables().size() != nrVariablesPerClause)
// exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
//PAT: door de twee bovenstaande lijnen in commentaar te zetten, krijg je ook clauses waar een bepaalde var meer dan 1 keer kan voorkomen
double value = exp.eval(interpretation);
// double upperbound = ceil(value + rand.nextDouble()*(1-value));
// double lowerbound = floor(rand.nextDouble()*value);
double upperbound;
double lowerbound;
upperbound = ceil(value);
lowerbound = floor(value);
res.add(new FuzzyLiteral(lowerbound, upperbound, exp));
}
return res;
}
public static List<FuzzyLiteral> getRandomConstraintsEasy(int numberOfConstraints, int numberOfVariables,
double pNegation, int nrVariablesPerClause) {
List<String> variables = new ArrayList();
for (int i = 0; i < numberOfVariables; i++)
variables.add("v" + i);
List<FuzzyLiteral> res = new ArrayList();
for (int i = 0; i < numberOfConstraints; i++) {
FuzzyExpression exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
while (exp.getVariables().size() != nrVariablesPerClause)
exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
double value = rand.nextDouble();
double upperbound = 1;
double lowerbound = ceil(value);
res.add(new FuzzyLiteral(lowerbound, upperbound, exp));
}
return res;
}
public static List<FuzzyLiteral> getRandomSemiSatisfiableConstraints(int numberOfConstraints, int numberOfVariables,
double pNegation, int nrVariablesPerClause,
int nrSatisfiableConstraints) {
Map<String, Double> interpretation = new HashMap();
List<String> variables = new ArrayList();
for (int i = 0; i < numberOfVariables; i++) {
double val = rand.nextDouble();
interpretation.put("v" + i, val);
variables.add("v" + i);
}
List<FuzzyLiteral> res = new ArrayList();
for (int i = 0; i < numberOfConstraints; i++) {
FuzzyExpression exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
while (exp.getVariables().size() != nrVariablesPerClause)
exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
double upperbound = 1;
double lowerbound = 0;
if (i < nrSatisfiableConstraints)
lowerbound = floor(exp.eval(interpretation));
else
lowerbound = ceil(rand.nextDouble());
res.add(new FuzzyLiteral(lowerbound, upperbound, exp));
}
return res;
}
public static List<FuzzyLiteral> getRandomSemiSatisfiableConstraints2(int numberOfConstraints, int numberOfVariables,
double pNegation, int nrVariablesPerClause) {
Map<String, Double> interpretation1 = new HashMap();
Map<String, Double> interpretation2 = new HashMap();
List<String> variables = new ArrayList();
for (int i = 0; i < numberOfVariables; i++) {
double val = rand.nextDouble();
interpretation1.put("v" + i, val);
val = rand.nextDouble();
interpretation2.put("v" + i, val);
variables.add("v" + i);
}
List<FuzzyLiteral> res = new ArrayList();
for (int i = 0; i < numberOfConstraints; i++) {
FuzzyExpression exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
while (exp.getVariables().size() != nrVariablesPerClause)
exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
double upperbound = 1;
double lowerbound;
if (rand.nextDouble() < 0.5)
lowerbound = floor(exp.eval(interpretation1));
else
lowerbound = floor(exp.eval(interpretation2));
res.add(new FuzzyLiteral(lowerbound, upperbound, exp));
}
return res;
}
public static List<FuzzyLiteral> getMixedRandomSemiSatisfiableConstraints(int numberOfConstraints, int numberOfVariables,
double pNegation, double pMinimum, int nrVariablesPerClause) {
Map<String, Double> interpretation1 = new HashMap();
Map<String, Double> interpretation2 = new HashMap();
List<String> variables = new ArrayList();
for (int i = 0; i < numberOfVariables; i++) {
double val = rand.nextDouble();
interpretation1.put("v" + i, val);
val = rand.nextDouble();
interpretation2.put("v" + i, val);
variables.add("v" + i);
}
List<FuzzyLiteral> res = new ArrayList();
for (int i = 0; i < numberOfConstraints; i++) {
FuzzyExpression exp = getRandomMixedExpression(variables, pNegation, pMinimum, nrVariablesPerClause);
while (exp.getVariables().size() != nrVariablesPerClause)
exp = getRandomMixedExpression(variables, pNegation, pMinimum, nrVariablesPerClause);
double upperbound = 1;
double lowerbound;
if (rand.nextDouble() < 0.5)
lowerbound = floor(exp.eval(interpretation1));
else
lowerbound = floor(exp.eval(interpretation2));
res.add(new FuzzyLiteral(lowerbound, upperbound, exp));
}
return res;
}
public static List<FuzzyLiteral> getRandomConstraintsHard(int numberOfConstraints, int numberOfVariables,
double pNegation, int nrVariablesPerClause) {
List<String> variables = new ArrayList();
for (int i = 0; i < numberOfVariables; i++)
variables.add("v" + i);
List<FuzzyLiteral> res = new ArrayList();
for (int i = 0; i < numberOfConstraints; i++) {
FuzzyExpression exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
while (exp.getVariables().size() != nrVariablesPerClause)
exp = getRandomExpression2(variables, pNegation, nrVariablesPerClause);
double value1 = rand.nextDouble();
double value2 = rand.nextDouble();
// double upperbound = ceil(value + rand.nextDouble()*(1-value));
// double lowerbound = floor(rand.nextDouble()*value);
double upperbound;
double lowerbound;
upperbound = ceil(Math.max(value1, value2));
lowerbound = floor(Math.min(value1, value2));
res.add(new FuzzyLiteral(lowerbound, upperbound, exp));
}
return res;
}
private static double floor(double val) {
double step = STEP_CONST;
double k = Math.floor(val / step);
return k * step;
}
private static double ceil(double val) {
double step = STEP_CONST;
double k = Math.ceil(val / step);
return k * step;
}
private static FuzzyExpression getRandomExpression(List<String> variables, double pBinary, double pUnary,
double pVar, double pConst, int maxDepth) {
double p;
if (maxDepth <= 0)
p = pBinary + pUnary + (pVar + pConst) * rand.nextDouble();
else
p = rand.nextDouble();
if (p < pBinary) {
FuzzyExpression arg1 = getRandomExpression(variables, pBinary, pUnary, pVar, pConst, maxDepth - 1);
FuzzyExpression arg2 = getRandomExpression(variables, pBinary, pUnary, pVar, pConst, maxDepth - 1);
double p2 = rand.nextDouble();
if (p2 < 0.33)
return new FuzzyBinaryExpression(arg1, arg2, new TW());
else if (p2 < 0.66)
return new FuzzyBinaryExpression(arg1, arg2, new IW());
else
return new FuzzyBinaryExpression(arg1, arg2, new SW());
}
else if (p < pBinary + pUnary) {
FuzzyExpression arg1 = getRandomExpression(variables, pBinary, pUnary, pVar, pConst, maxDepth - 1);
return new FuzzyUnaryExpression(arg1, new N());
}
else if (p < pBinary + pUnary + pVar)
return new FuzzyVariableExpression(variables.get(rand.nextInt(variables.size())));
else {
int m = (int) (1.0 / STEP_CONST);
double val = ((double) rand.nextInt(m + 1)) / ((double) m);
return new FuzzyConstantExpression(val);
}
}
private static FuzzyExpression getRandomExpression2(List<String> variables, double pNegation, int nrVariables) {
return getRandomExpression2(variables, pNegation, nrVariables, false);
}
private static FuzzyExpression getRandomExpression2(List<String> variables, double pNegation, int nrVariables, boolean isNegated) {
if (!isNegated && rand.nextDouble() < pNegation)
return new FuzzyUnaryExpression(getRandomExpression2(variables, pNegation, nrVariables, true), new N());
else if (nrVariables == 1) {
return new FuzzyVariableExpression(variables.get(rand.nextInt(variables.size())));
}
else {
int nr1 = 1 + rand.nextInt(nrVariables - 1);
int nr2 = nrVariables - nr1;
FuzzyExpression arg1 = getRandomExpression2(variables, pNegation, nr1, false);
FuzzyExpression arg2 = getRandomExpression2(variables, pNegation, nr2, false);
// double p2 = rand.nextDouble();
// if (p2 < 0.33)
return new FuzzyBinaryExpression(arg1, arg2, new TW());
// else if (p2 < 0.66)
// return new FuzzyBinaryExpression(arg1, arg2, new IW());
// else
// return new FuzzyBinaryExpression(arg1, arg2, new SW());
}
}
private static FuzzyExpression getRandomMixedExpression(List<String> variables, double pNegation, double pMinimum, int nrVariables) {
return getRandomMixedExpression(variables, pNegation, pMinimum, nrVariables, false);
}
private static FuzzyExpression getRandomMixedExpression(List<String> variables, double pNegation, double pMinimum, int nrVariables, boolean isNegated) {
if (!isNegated && rand.nextDouble() < pNegation)
return new FuzzyUnaryExpression(getRandomMixedExpression(variables, pNegation, pMinimum, nrVariables, true), new N());
else if (nrVariables == 1) {
return new FuzzyVariableExpression(variables.get(rand.nextInt(variables.size())));
}
else {
int nr1 = 1 + rand.nextInt(nrVariables - 1);
int nr2 = nrVariables - nr1;
FuzzyExpression arg1 = getRandomMixedExpression(variables, pNegation, pMinimum, nr1, false);
FuzzyExpression arg2 = getRandomMixedExpression(variables, pNegation, pMinimum, nr2, false);
double p2 = rand.nextDouble();
if (p2 < pMinimum)
return new FuzzyBinaryExpression(arg1, arg2, new TM());
else
return new FuzzyBinaryExpression(arg1, arg2, new TW());
}
}
}