From 3f1f0b2fb01c520423c1c7632e615383331c54dc Mon Sep 17 00:00:00 2001 From: hneemann Date: Sun, 5 Mar 2017 12:53:41 +0100 Subject: [PATCH] added support for multicore Quine McCluskey, disabled at the moment --- .../analyse/quinemc/QuineMcCluskey.java | 13 ++- .../digital/analyse/quinemc/TableRow.java | 4 +- .../components/table/ExpressionCreator.java | 85 +++++++++++++++---- 3 files changed, 77 insertions(+), 25 deletions(-) diff --git a/src/main/java/de/neemann/digital/analyse/quinemc/QuineMcCluskey.java b/src/main/java/de/neemann/digital/analyse/quinemc/QuineMcCluskey.java index 1abc3bd72..f6c73190a 100644 --- a/src/main/java/de/neemann/digital/analyse/quinemc/QuineMcCluskey.java +++ b/src/main/java/de/neemann/digital/analyse/quinemc/QuineMcCluskey.java @@ -6,10 +6,7 @@ import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelector; import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelectorDefault; import de.neemann.digital.lang.Lang; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.TreeSet; +import java.util.*; 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 { private final TableRows rows; - private final ArrayList variables; + private final List variables; private final ArrayList primes; /** @@ -29,13 +26,13 @@ public class QuineMcCluskey { * * @param variables the variables to use */ - public QuineMcCluskey(ArrayList variables) { + public QuineMcCluskey(List variables) { this.variables = variables; this.rows = new TableRows(); this.primes = new ArrayList<>(); } - private QuineMcCluskey(ArrayList variables, TableRows rows, ArrayList primes) { + private QuineMcCluskey(List variables, TableRows rows, ArrayList primes) { this.variables = variables; this.rows = rows; this.primes = primes; @@ -242,7 +239,7 @@ public class QuineMcCluskey { * @param variables the variables to use to build the expression * @return the expression */ - public static Expression addAnd(Expression e, Iterable rows, ArrayList variables) { + public static Expression addAnd(Expression e, Iterable rows, List variables) { for (TableRow r : rows) { Expression n = r.getExpression(variables); if (e == null) diff --git a/src/main/java/de/neemann/digital/analyse/quinemc/TableRow.java b/src/main/java/de/neemann/digital/analyse/quinemc/TableRow.java index 32a7f3ee2..adb9c8541 100644 --- a/src/main/java/de/neemann/digital/analyse/quinemc/TableRow.java +++ b/src/main/java/de/neemann/digital/analyse/quinemc/TableRow.java @@ -6,9 +6,9 @@ import de.neemann.digital.analyse.expression.Constant; import de.neemann.digital.analyse.expression.Expression; import de.neemann.digital.analyse.expression.Variable; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.TreeSet; import static de.neemann.digital.analyse.expression.Not.not; @@ -196,7 +196,7 @@ public class TableRow implements Comparable { * @param vars the variables to use * @return the expression */ - public Expression getExpression(ArrayList vars) { + public Expression getExpression(List vars) { Expression e = null; for (int i = 0; i < size(); i++) { Expression term = null; diff --git a/src/main/java/de/neemann/digital/gui/components/table/ExpressionCreator.java b/src/main/java/de/neemann/digital/gui/components/table/ExpressionCreator.java index 595b68556..97fabf89c 100644 --- a/src/main/java/de/neemann/digital/gui/components/table/ExpressionCreator.java +++ b/src/main/java/de/neemann/digital/gui/components/table/ExpressionCreator.java @@ -11,6 +11,11 @@ import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelector; import de.neemann.digital.analyse.quinemc.primeselector.PrimeSelectorDefault; 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 @@ -37,23 +42,73 @@ public class ExpressionCreator { * @throws FormatterException FormatterException */ public void create(ExpressionListener listener) throws ExpressionException, FormatterException { - ArrayList vars = theTable.getVars(); - for (int table = 0; table < theTable.getResultCount(); table++) { - PrimeSelector ps = new PrimeSelectorDefault(); - Expression e = new QuineMcCluskey(vars) - .fillTableWith(theTable.getResult(table)) - .simplify(ps) - .getExpression(); - - if (ps.getAllSolutions() != null) { - for (ArrayList i : ps.getAllSolutions()) { - listener.resultFound(theTable.getResultName(table), QuineMcCluskey.addAnd(null, i, vars)); - } - } else { - listener.resultFound(theTable.getResultName(table), e); + final List vars = Collections.unmodifiableList(theTable.getVars()); + long time = System.currentTimeMillis(); + if (theTable.getResultCount() > 100) { + ExecutorService ex = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() / 2); + ThreadSaveExpressionListener threadListener = new ThreadSaveExpressionListener(listener); + for (int table = 0; table < theTable.getResultCount(); table++) { + final QuineMcCluskey qmc = new QuineMcCluskey(vars) + .fillTableWith(theTable.getResult(table)); + final String resultName = theTable.getResultName(table); + final int t = table; + ex.submit(() -> { + try { + System.out.println("start " + t); + 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 vars) throws ExpressionException, FormatterException { + PrimeSelector ps = new PrimeSelectorDefault(); + Expression e = qmc.simplify(ps).getExpression(); + + if (ps.getAllSolutions() != null) { + for (ArrayList 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(); + } + } }