added support for multicore Quine McCluskey, disabled at the moment

This commit is contained in:
hneemann 2017-03-05 12:53:41 +01:00
parent c157bee3a7
commit 3f1f0b2fb0
3 changed files with 77 additions and 25 deletions

View File

@ -6,10 +6,7 @@ import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelector;
import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelectorDefault; import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelectorDefault;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.Iterator;
import java.util.TreeSet;
import static de.neemann.digital.analyse.expression.Operation.or; import static de.neemann.digital.analyse.expression.Operation.or;
@ -21,7 +18,7 @@ import static de.neemann.digital.analyse.expression.Operation.or;
public class QuineMcCluskey { public class QuineMcCluskey {
private final TableRows rows; private final TableRows rows;
private final ArrayList<Variable> variables; private final List<Variable> variables;
private final ArrayList<TableRow> primes; private final ArrayList<TableRow> primes;
/** /**
@ -29,13 +26,13 @@ public class QuineMcCluskey {
* *
* @param variables the variables to use * @param variables the variables to use
*/ */
public QuineMcCluskey(ArrayList<Variable> variables) { public QuineMcCluskey(List<Variable> variables) {
this.variables = variables; this.variables = variables;
this.rows = new TableRows(); this.rows = new TableRows();
this.primes = new ArrayList<>(); this.primes = new ArrayList<>();
} }
private QuineMcCluskey(ArrayList<Variable> variables, TableRows rows, ArrayList<TableRow> primes) { private QuineMcCluskey(List<Variable> variables, TableRows rows, ArrayList<TableRow> primes) {
this.variables = variables; this.variables = variables;
this.rows = rows; this.rows = rows;
this.primes = primes; this.primes = primes;
@ -242,7 +239,7 @@ public class QuineMcCluskey {
* @param variables the variables to use to build the expression * @param variables the variables to use to build the expression
* @return the expression * @return the expression
*/ */
public static Expression addAnd(Expression e, Iterable<TableRow> rows, ArrayList<Variable> variables) { public static Expression addAnd(Expression e, Iterable<TableRow> rows, List<Variable> variables) {
for (TableRow r : rows) { for (TableRow r : rows) {
Expression n = r.getExpression(variables); Expression n = r.getExpression(variables);
if (e == null) if (e == null)

View File

@ -6,9 +6,9 @@ import de.neemann.digital.analyse.expression.Constant;
import de.neemann.digital.analyse.expression.Expression; import de.neemann.digital.analyse.expression.Expression;
import de.neemann.digital.analyse.expression.Variable; import de.neemann.digital.analyse.expression.Variable;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.TreeSet; import java.util.TreeSet;
import static de.neemann.digital.analyse.expression.Not.not; import static de.neemann.digital.analyse.expression.Not.not;
@ -196,7 +196,7 @@ public class TableRow implements Comparable<TableRow> {
* @param vars the variables to use * @param vars the variables to use
* @return the expression * @return the expression
*/ */
public Expression getExpression(ArrayList<Variable> vars) { public Expression getExpression(List<Variable> vars) {
Expression e = null; Expression e = null;
for (int i = 0; i < size(); i++) { for (int i = 0; i < size(); i++) {
Expression term = null; Expression term = null;

View File

@ -11,6 +11,11 @@ import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelector;
import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelectorDefault; import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelectorDefault;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/** /**
* Used to generate the expressions belonging to the given truth table * Used to generate the expressions belonging to the given truth table
@ -37,23 +42,73 @@ public class ExpressionCreator {
* @throws FormatterException FormatterException * @throws FormatterException FormatterException
*/ */
public void create(ExpressionListener listener) throws ExpressionException, FormatterException { public void create(ExpressionListener listener) throws ExpressionException, FormatterException {
ArrayList<Variable> vars = theTable.getVars(); final List<Variable> vars = Collections.unmodifiableList(theTable.getVars());
for (int table = 0; table < theTable.getResultCount(); table++) { long time = System.currentTimeMillis();
PrimeSelector ps = new PrimeSelectorDefault(); if (theTable.getResultCount() > 100) {
Expression e = new QuineMcCluskey(vars) ExecutorService ex = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() / 2);
.fillTableWith(theTable.getResult(table)) ThreadSaveExpressionListener threadListener = new ThreadSaveExpressionListener(listener);
.simplify(ps) for (int table = 0; table < theTable.getResultCount(); table++) {
.getExpression(); final QuineMcCluskey qmc = new QuineMcCluskey(vars)
.fillTableWith(theTable.getResult(table));
if (ps.getAllSolutions() != null) { final String resultName = theTable.getResultName(table);
for (ArrayList<TableRow> i : ps.getAllSolutions()) { final int t = table;
listener.resultFound(theTable.getResultName(table), QuineMcCluskey.addAnd(null, i, vars)); ex.submit(() -> {
} try {
} else { System.out.println("start " + t);
listener.resultFound(theTable.getResultName(table), e); calcColumn(threadListener, qmc, resultName, vars);
System.out.println("end " + t);
} catch (ExpressionException | FormatterException e) {
e.printStackTrace();
}
});
} }
ex.shutdown();
try {
ex.awaitTermination(100, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadListener.close();
} else {
for (int table = 0; table < theTable.getResultCount(); table++) {
QuineMcCluskey qmc = new QuineMcCluskey(vars)
.fillTableWith(theTable.getResult(table));
calcColumn(listener, qmc, theTable.getResultName(table), vars);
}
listener.close();
} }
listener.close(); time = System.currentTimeMillis() - time;
System.out.println("time: " + time / 1000.0 + " sec");
} }
private static void calcColumn(ExpressionListener listener, QuineMcCluskey qmc, String name, List<Variable> vars) throws ExpressionException, FormatterException {
PrimeSelector ps = new PrimeSelectorDefault();
Expression e = qmc.simplify(ps).getExpression();
if (ps.getAllSolutions() != null) {
for (ArrayList<TableRow> i : ps.getAllSolutions()) {
listener.resultFound(name, QuineMcCluskey.addAnd(null, i, vars));
}
} else {
listener.resultFound(name, e);
}
}
private final static class ThreadSaveExpressionListener implements ExpressionListener {
private final ExpressionListener listener;
private ThreadSaveExpressionListener(ExpressionListener listener) {
this.listener = listener;
}
@Override
public synchronized void resultFound(String name, Expression expression) throws FormatterException, ExpressionException {
listener.resultFound(name, expression);
}
@Override
public synchronized void close() throws FormatterException, ExpressionException {
listener.close();
}
}
} }