Download code
From LiteratePrograms
Back to Quine-McCluskey_algorithm_(Java)
Download for Windows: zip
Download for UNIX: zip, tar.gz, tar.bz2
Formula.java
1 /* Copyright (c) 2010 the authors listed at the following URL, and/or 2 the authors of referenced articles or incorporated external code: 3 http://en.literateprograms.org/Quine-McCluskey_algorithm_(Java)?action=history&offset=20090311182700 4 5 Permission is hereby granted, free of charge, to any person obtaining 6 a copy of this software and associated documentation files (the 7 "Software"), to deal in the Software without restriction, including 8 without limitation the rights to use, copy, modify, merge, publish, 9 distribute, sublicense, and/or sell copies of the Software, and to 10 permit persons to whom the Software is furnished to do so, subject to 11 the following conditions: 12 13 The above copyright notice and this permission notice shall be 14 included in all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24 Retrieved from: http://en.literateprograms.org/Quine-McCluskey_algorithm_(Java)?oldid=16251 25 */ 26 27 import java.util.*; 28 import java.io.*; 29 30 31 class Formula { 32 public Formula(List<Term> termList) { 33 this.termList = termList; 34 } 35 36 public String toString() { 37 String result = ""; 38 result += termList.size() + " terms, " + termList.get(0).getNumVars() + " variables\n"; 39 for(int i=0; i<termList.size(); i++) { 40 result += termList.get(i) + "\n"; 41 } 42 return result; 43 } 44 45 @SuppressWarnings("unchecked") 46 public void reduceToPrimeImplicants() { 47 originalTermList = new ArrayList<Term>(termList); 48 int numVars = termList.get(0).getNumVars(); 49 ArrayList<Term>[][] table = new ArrayList[numVars + 1][numVars + 1]; 50 for(int dontKnows=0; dontKnows <= numVars; dontKnows++) { 51 for(int ones=0; ones <= numVars; ones++) { 52 table[dontKnows][ones] = new ArrayList<Term>(); 53 } 54 } 55 for(int i=0; i<termList.size(); i++) { 56 int dontCares = termList.get(i).countValues(Term.DontCare); 57 int ones = termList.get(i).countValues((byte)1); 58 table[dontCares][ones].add(termList.get(i)); 59 } 60 61 for(int dontKnows=0; dontKnows <= numVars - 1; dontKnows++) { 62 for(int ones=0; ones <= numVars - 1; ones++) { 63 ArrayList<Term> left = table[dontKnows][ones]; 64 ArrayList<Term> right = table[dontKnows][ones + 1]; 65 ArrayList<Term> out = table[dontKnows+1][ones]; 66 for(int leftIdx = 0; leftIdx < left.size(); leftIdx++) { 67 for(int rightIdx = 0; rightIdx < right.size(); rightIdx++) { 68 Term combined = left.get(leftIdx).combine(right.get(rightIdx)); 69 if (combined != null) { 70 if (!out.contains(combined)) { 71 out.add(combined); 72 } 73 termList.remove(left.get(leftIdx)); 74 termList.remove(right.get(rightIdx)); 75 if (!termList.contains(combined)) { 76 termList.add(combined); 77 } 78 79 } 80 } 81 } 82 } 83 } 84 85 } 86 87 public void reducePrimeImplicantsToSubset() { 88 int numPrimeImplicants = termList.size(); 89 int numOriginalTerms = originalTermList.size(); 90 boolean[][] table = new boolean[numPrimeImplicants][numOriginalTerms]; 91 for (int impl=0; impl < numPrimeImplicants; impl++) { 92 for (int term=0; term < numOriginalTerms; term++) { 93 table[impl][term] = termList.get(impl).implies(originalTermList.get(term)); 94 } 95 } 96 97 ArrayList<Term> newTermList = new ArrayList<Term>(); 98 boolean done = false; 99 int impl; 100 while (!done) { 101 impl = extractEssentialImplicant(table); 102 if (impl != -1) { 103 newTermList.add(termList.get(impl)); 104 } else { 105 impl = extractLargestImplicant(table); 106 if (impl != -1) { 107 newTermList.add(termList.get(impl)); 108 } else { 109 done = true; 110 } 111 } 112 } 113 termList = newTermList; 114 115 originalTermList = null; 116 } 117 118 public static Formula read(Reader reader) throws IOException { 119 ArrayList<Term> terms = new ArrayList<Term>(); 120 Term term; 121 while ((term = Term.read(reader)) != null) { 122 terms.add(term); 123 } 124 return new Formula(terms); 125 } 126 127 128 private int extractEssentialImplicant(boolean[][] table) { 129 for (int term=0; term < table[0].length; term++) { 130 int lastImplFound = -1; 131 for (int impl=0; impl < table.length; impl++) { 132 if (table[impl][term]) { 133 if (lastImplFound == -1) { 134 lastImplFound = impl; 135 } else { 136 // This term has multiple implications 137 lastImplFound = -1; 138 break; 139 } 140 } 141 } 142 if (lastImplFound != -1) { 143 extractImplicant(table, lastImplFound); 144 return lastImplFound; 145 } 146 } 147 return -1; 148 } 149 150 private void extractImplicant(boolean[][] table, int impl) { 151 for (int term=0; term < table[0].length; term++) { 152 if (table[impl][term]) { 153 for (int impl2=0; impl2 < table.length; impl2++) { 154 table[impl2][term] = false; 155 } 156 } 157 } 158 } 159 160 private int extractLargestImplicant(boolean[][] table) { 161 int maxNumTerms = 0; 162 int maxNumTermsImpl = -1; 163 for (int impl=0; impl < table.length; impl++) { 164 int numTerms = 0; 165 for (int term=0; term < table[0].length; term++) { 166 if (table[impl][term]) { 167 numTerms++; 168 } 169 } 170 if (numTerms > maxNumTerms) { 171 maxNumTerms = numTerms; 172 maxNumTermsImpl = impl; 173 } 174 } 175 if (maxNumTermsImpl != -1) { 176 extractImplicant(table, maxNumTermsImpl); 177 return maxNumTermsImpl; 178 } 179 return -1; 180 } 181 182 183 private List<Term> termList; 184 private List<Term> originalTermList; 185 186 187 public static void main(String[] args) throws IOException { 188 Formula f = Formula.read(new BufferedReader(new FileReader(args[0]))); 189 f.reduceToPrimeImplicants(); 190 System.out.println(f); 191 f.reducePrimeImplicantsToSubset(); 192 System.out.println(f); 193 } 194 195 } 196
Term.java
1 /* Copyright (c) 2010 the authors listed at the following URL, and/or 2 the authors of referenced articles or incorporated external code: 3 http://en.literateprograms.org/Quine-McCluskey_algorithm_(Java)?action=history&offset=20090311182700 4 5 Permission is hereby granted, free of charge, to any person obtaining 6 a copy of this software and associated documentation files (the 7 "Software"), to deal in the Software without restriction, including 8 without limitation the rights to use, copy, modify, merge, publish, 9 distribute, sublicense, and/or sell copies of the Software, and to 10 permit persons to whom the Software is furnished to do so, subject to 11 the following conditions: 12 13 The above copyright notice and this permission notice shall be 14 included in all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24 Retrieved from: http://en.literateprograms.org/Quine-McCluskey_algorithm_(Java)?oldid=16251 25 */ 26 27 import java.util.*; 28 import java.io.*; 29 30 31 class Term { 32 public static final byte DontCare = 2; 33 34 public Term(byte[] varVals) { 35 this.varVals = varVals; 36 } 37 38 public int getNumVars() { 39 return varVals.length; 40 } 41 42 public String toString() { 43 String result = "{"; 44 for(int i=0; i<varVals.length; i++) { 45 if (varVals[i] == DontCare) 46 result += "X"; 47 else 48 result += varVals[i]; 49 result += " "; 50 } 51 result += "}"; 52 return result; 53 } 54 55 public Term combine(Term term) { 56 int diffVarNum = -1; // The position where they differ 57 for(int i=0; i<varVals.length; i++) { 58 if (this.varVals[i] != term.varVals[i]) { 59 if (diffVarNum == -1) { 60 diffVarNum = i; 61 } else { 62 // They're different in at least two places 63 return null; 64 } 65 } 66 } 67 if (diffVarNum == -1) { 68 // They're identical 69 return null; 70 } 71 byte[] resultVars = varVals.clone(); 72 resultVars[diffVarNum] = DontCare; 73 return new Term(resultVars); 74 } 75 76 public int countValues(byte value) { 77 int result = 0; 78 for(int i=0; i<varVals.length; i++) { 79 if (varVals[i] == value) { 80 result++; 81 } 82 } 83 return result; 84 } 85 86 public boolean equals(Object o) { 87 if (o == this) { 88 return true; 89 } else if (o == null || !getClass().equals(o.getClass())) { 90 return false; 91 } else { 92 Term rhs = (Term)o; 93 return Arrays.equals(this.varVals, rhs.varVals); 94 } 95 } 96 97 public int hashCode() { 98 return varVals.hashCode(); 99 } 100 101 boolean implies(Term term) { 102 for(int i=0; i<varVals.length; i++) { 103 if (this.varVals[i] != DontCare && 104 this.varVals[i] != term.varVals[i]) { 105 return false; 106 } 107 } 108 return true; 109 } 110 111 public static Term read(Reader reader) throws IOException { 112 int c = '\0'; 113 ArrayList<Byte> t = new ArrayList<Byte>(); 114 while (c != '\n' && c != -1) { 115 c = reader.read(); 116 if (c == '0') { 117 t.add((byte)0); 118 } else if (c == '1') { 119 t.add((byte)1); 120 } 121 } 122 if (t.size() > 0) { 123 byte[] resultBytes = new byte[t.size()]; 124 for(int i=0; i<t.size(); i++) { 125 resultBytes[i] = (byte)t.get(i); 126 } 127 return new Term(resultBytes); 128 } else { 129 return null; 130 } 131 } 132 133 134 private byte[] varVals; 135 } 136
input_example.txt
1 000 2 010 3 011 4 110 5 101 6 111 7
vastianos_example_1.3.txt
1 0000 2 0001 3 0010 4 0011 5 0101 6 0111 7 1000 8 1010 9 1100 10 1101 11 1111 12
