Mathematisches Praktikum - SoSe 2014

Ähnliche Dokumente
Verwendung eines KV-Diagramms

Teil III. Schaltnetze und ihre Optimierung

Bisher. minimale DNF. logischen Formeln Booleschen Funktionen Schaltungen

Teil 1: Digitale Logik

Algorithmus von McClusky: Der Algorithmus von McCluskey liefert durch wiederholte Anwendung der ersten und zweiten Vereinfachungsregel:

2.3 Logikoptimierung. Überblick digitale Synthese. Logikoptimierung

Darstellung von negativen binären Zahlen

Minimierung von logischen Schaltungen

Kapitel 4: Das Überdeckungsproblem

N Bit binäre Zahlen (signed)

Technische Informatik I

Informationsverarbeitung auf Bitebene

Rechnerstrukturen. Michael Engel und Peter Marwedel WS 2013/14. TU Dortmund, Fakultät für Informatik

Boolesche Algebra (1)

Kapitel 6 Programmierbare Logik. Literatur: Kapitel 6 aus Oberschelp/Vossen, Rechneraufbau und Rechnerstrukturen, 9. Auflage

Eingebettete Systeme

Übungsklausur - Beispiellösung

C Beispiel: Siebensegmentanzeige. Typische Anzeige für Ziffern a. f g. e d. Gesucht: Schaltfunktion für die Ansteuerung des Segmentes d

kanonische disjunktive Normalform (KDNF, DKF) Disjunktion einer Menge von Mintermen mit gleichen Variablen

C.34 C Normalformen (4) 5.7 Hauptsatz der Schaltalgebra. 5.7 Hauptsatz der Schaltalgebra (2) 5.7 Hauptsatz der Schaltalgebra (3)

Übungsblatt 5 (Block B - 1) (17 Punkte)

Computersysteme. 2. Grundlagen Digitaler Schaltungen 2.10 Minimierung Boole scher Funktionen 2.11 CMOS Komplexgatter

Rückblick. Erweiterte b-adische Darstellung von Kommazahlen. 7,1875 dargestellt mit l = 4 und m = 4 Bits. Informatik 1 / Kapitel 2: Grundlagen

Aussagenlogik. Aussagen und Aussagenverknüpfungen

Mathematisches Praktikum - SoSe 2015

8. Tutorium Digitaltechnik und Entwurfsverfahren

Rechnerstrukturen WS 2012/13

Allgemeingültige Aussagen

Klausur: Grundlagen der Informatik I, am 05. Februar 2008 Dirk Seeber, h_da, Fb Informatik. Nachname: Vorname: Matr.-Nr.: Punkte:

Technische Informatik - Eine Einführung

Grundlagen der Informationverarbeitung

Einführung in die technische Informatik

3. Übungsblatt zu Algorithmen I im SoSe 2017

Logik (Teschl/Teschl 1.1 und 1.3)

Lernen mit Queries. Hans Kleine Büning Institut für Informatik, Universität Paderborn Paderborn (Germany),

Normalformen von Schaltfunktionen

Schriftliche Prüfung

Grundlagen der Technischen Informatik. 8. Übung

Technische Informatik I 4. Vorlesung. 2. Funktion digitaler Schaltungen... wertverlaufsgleiche Umformungen

Störungen in Digitalsystemen

Klausur: Grundlagen der Informatik I, am 05. Februar 2008 Dirk Seeber, h_da, Fb Informatik

Grundlagen der Technischen Informatik. 7. Übung

Satz von De Morgan A B A + B A + B A B A. Transistoren: A B U a A 0 0 Vcc Vcc Vcc V 0

II. Grundlagen der Programmierung

Aufgabe 1. Aufgabe 2. Abbildung 1: Schaltung für die Multiplikation mit 4

Formelsammlung. Wahrscheinlichkeit und Information

x x y x y Informatik II Schaltkreise Schaltkreise Schaltkreise Rainer Schrader 3. November 2008

Übungs- und Praktikumsaufgaben zur Systemprogrammierung Dipl.-Ing. H. Büchter (Lehrbeauftragter) FH-Dortmund WS 2001/2002 / SS 2002

Algorithmen zur Datenanalyse in C++

Einführung in die Informatik I

Systemorientierte Informatik 1

Arbeitsblatt Logische Verknüpfungen Schaltnetzsynthese

Übungspaket 12 Der Datentyp char

Programmierung 1 (Wintersemester 2015/16) Wiederholungstutorium Lösungsblatt 15 (Linearer Speicher, Listen, Bäume)

Algorithmen & Programmierung. Logik

Vorwort Einführung in Power Query Erste Abfrage erstellen... 21

Informatik A (Autor: Max Willert)

Assoziative Container in C++ Christian Poulter

Mathematische Grundlagen I Logik und Algebra

Grundlagen der Digitaltechnik GD. Aufgaben und Musterlösungen

Hier wird die Verwendung der Standard Template Library (kurz STL) kurz beschrieben. Inhalt 1.Verwendung der STL Grundlagen...

Gran Turismo Cars - WS 11/12

Vor(schau)kurs für Studienanfänger Mathematik: Aussagen und Mengen

DIGITALTECHNIK 06 SCHALTUNGS- SYNTHESE UND ANALYSE

7. Einführung in C++ Programmieren / Algorithmen und Datenstrukturen 1 Prof. Dr. Bernhard Humm FB Informatik, Hochschule Darmstadt

Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):

Resolutionskalkül. wird t als eine Menge K t von Klauseln geschrieben, welche die einzelnen Maxterme repräsentieren:

Grundlagen: Algorithmen und Datenstrukturen

, WS2012 Übungsgruppen: Mo.,

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen.

float: Fließkommazahl nach IEEE 754 Standard mit 32 bit

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.

Übungen zur Vorlesung Wissenschaftliches Rechnen I. Grundelemente von Java. Eine Anweisung. wird mit dem Wertzuweisungsoperator = geschrieben.

Einführung in die Programmierung (EPR)

A.1 Schaltfunktionen und Schaltnetze

Vom Leichtesten zum Schwersten Sortieralgorithmen

Intensivübung zu Algorithmen und Datenstrukturen

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen

MySQL-Befehle. In diesem Tutorial möchte ich eine kurze Übersicht der wichtigsten Befehle von MySQL geben.

Klausur zur Vorlesung Technische Informatik 1 im WS 06/07 Donnerstag, den von Uhr Uhr, HS 5

Vorsemesterkurs Informatik Sommersemester Aufgabenblatt Nr. 5A. Lösung zu Aufgabe 1 (Fehler in Haskell-Quelltext: Parsefehler)

Wissenschaftliches Rechnen

Einheit Datentypen in der Programmiersprache C Schwerpunkt: Elementare (arithmetische) Datentypen

Java Einführung Operatoren Kapitel 2 und 3

Polymorphismus 179. Function.h. #include <string>

Unterlagen. CPP-Uebungen-08/

Technische Informatik I, SS03. Boole sche Algebra, Kombinatorische Logik

Einführung in die STL

Einführung in die C++ Programmierung für Ingenieure

Digitalelektronik - Inhalt

5 BINÄRE ENTSCHEIDUNGS- DIAGRAMME (BDDS)

Welche Informatik-Kenntnisse bringen Sie mit?

Hochschule Darmstadt Informatik-Praktikum WS 2016/2017 WIng Bachelor 4. Aufgabenblatt Modularisierung, Funktionen, Unterprogramme

Grundlagen digitaler Systeme WS12

Programmieren lernen mit Visual Basic

Physische Datenstrukturen

Objektorientierte Programmierung mit C++ SS 2007

Transkript:

Mathematisches Praktikum - SoSe 2014 Prof. Dr. Wolfgang Dahmen Felix Gruber, M. Sc., Christian Löbbert, M. Sc., Yuanjun Zhang, M. Sc., Klaus Kaiser, M. Sc. Zusatzaufgabe 2 für Informatiker Bearbeitungszeit: zwei Wochen (bis Freitag, den 23. Mai 2014) Mathematischer Hintergrund: Boolesche Logik, Quine-McCluskey-Algorithmus Elemente von C ++ : Klassen, STL-Container Boolesche Funktionen spielen eine wichtige Rolle in vielen Bereichen der Mathematik und Informatik. Ein solcher Anwendungsbereich ist z. B. der Entwurf von Schaltkreisen, indem mithilfe von Transistoren die logischen Grundbausteine Und, Oder und Negation konstruiert werden, aus denen dann komplexere Schaltungen erstellt werden können. Diese Schaltungen lassen sich dann als Boolesche Funktionen auffassen. Beim Entwurf von logischen Schaltungen ist man daran interessiert, möglichst wenige Bauteile zu verwenden, um die Produktionskosten gering zu halten und um eine schnellere Auswertung des implementierten logischen Ausdrucks zu ermöglichen. Boolesche Funktionen mit bis zu vier Variablen lassen sich noch leicht per Hand über Karnaugh-Diagramme minimieren. Für logische Ausdrücke in vielen Variablen bietet sich hingegen der Algorithmus von Quine-McCluskey an, welcher im Folgenden vorgestellt wird. Aufgabenstellung Implementieren Sie den Algorithmus von Quine-McCluskey, um zu einer gegebenen Wahrheitstabelle eine äquivalente Boolesche Funktion mit kürzestmöglicher Sum-of-Products-Darstellung zu finden. Greifen Sie dazu auf die Standardcontainer aus der Standard Template Library (STL) zurück. Boolesche Funktionen Es sei F 2 := ({0, 1}, +,, ) die Boolesche Algebra mit den Verknüpfungen Oder +, Und, sowie Negation, welche über die Wahrheitstabellen in Tabelle 1 definiert sind. Dabei schreiben wir für die Negation statt x auch häufig x. + 0 1 0 0 1 1 1 1 0 1 0 0 0 1 0 1 0 1 1 0 Tabelle 1: Die drei Booleschen Verknüfungen Oder (+), Und ( ) und Negation ( ). Eine Abbildung f : F n 2 F 2 heißt Boolesche Funkktion. Tupel der Form i = (i 1,..., i n ) F n 2 auch Indices. Ein Index i F n 2 so, dass f(i 1,..., i n ) = 1, heißt einschlägiger Index von f. Für einen gegebenen Index i F n 2, sei xi k k definiert als x i k k := { x k falls i k = 1, x k falls i k = 0. nennen wir 1

Dann nennen wir die Funktion m i : F n 2 F 2, m i (x) = den i-ten Minterm von f. Damit lässt sich f jetzt eindeutig in der disjunktiven Normalform (DNF) f(x) = i I m i (x) n k=1 x i k k darstellen, wobei I {0,..., 2 n 1} die Menge der einschlägigen Indices von f bezeichnet. Nun ist die disjunktive Normalform häufig recht lang und damit zeitaufwändig in der Auswertung. Deshalb würden wir gerne f in einer möglichst kurzen disjunktiven Form mit möglicherweise kürzeren Produkten f(x) = k M i (x), k 1 i=1 M i (x) = l i j=1 x α j i j, l i 1 darstellen. Der Algorithmus von Quine-McCluskey Um eine solche kürzest-mögliche disjunktive Form für eine gegebene Boolesche Funktion f zu finden, können wir den Algorithmus von Quine-McCluskey benutzen. Dieser Algorithmus wurde erstmals 1952 von W. V. Quine veröffentlicht und 1956 von E. J. McCluskey [2] verbessert. Für den Algorithmus von Quine-McCluskey benötigen wir die folgenden Definitionen: Ein Term M heißt Implikant der Funktion f : F n 2 F 2, wenn M(x) = 1 f(x) = 1 x F n 2. Insbesondere ist jeder Minterm zu einem einschlägigen Index von f ein Implikant von f. Falls durch keine Streichung von Variablen aus M mehr ein kürzerer Implikant von f entsteht, nennen wir M Primimplikant von f. Damit lässt sich der Algorithmus von Quine-McCluskey grob in zwei Schritte unterteilen, die wir in den folgenden Abschnitten vorstellen werden: a.) Finde alle Primimplikanten von f. b.) Wähle Primimplikanten aus, die zusammenaddiert f ergeben und dabei minimale Kosten haben. Um zu bewerten, welche Darstellung einer Booleschen Funktion f die kürzeste ist, zählen wir die Und- und Oder-Verknüpfungen der Darstellung. Somit ergibt sich die Kostenfunktion ( k ) C M i := k 1 + i=1 C(M i ) := l i 1. k C(M i ) Die Negationen verursachen hier keine zusätzlichen Kosten, weil beim Aufbau von logischen Schaltungen meistens die Eingangssignale bereits sowohl in negierter als auch in nicht-negierter Form vorliegen. Eventuell macht es Sinn, die Kostenfunktion in anderen Anwendungen leicht abzuändern. Als Eingabe für den Algorithmus von Quine-McCluskey verwenden wir eine Wahrheitstabelle, in der die einschlägigen Indices einer Booleschen Funktion f stehen. Zusätzlich kann die Wahrheitstabelle Indices zu i=1 2

sogenannten Don t-care-termen enthalten. Das sind Indices für die es uns egal ist, welchen Wert die Funktion dort annimmt. Don t-care-terme sind z. B. nützlich, um kürzere Darstellungen für Schaltungen zu erhalten, bei denen manche Eingaben nicht vorkommen können. Beispielsweise könnten wir eine Sieben-Segment- Anzeige für Dezimalziffern mit 4 binären Eingängen realisieren, jedoch haben wir nur 10 gültige Zustände für die Eingänge. Damit hätten wir für die Steuerungslogik für jedes Segment 6 Don t-care-terme, die wir nutzen können, um kürzere Primimplikanten zu finden. Generieren von Primimplikanten Zunächst suchen wir Minterme, die sich nur in einer Binärstelle unterscheiden und nutzen aus, dass x x = 1. Die Stelle, in der sich die beiden Minterme unterscheiden, können wir streichen und erhalten einen Implikanten für beide Minterme, der eine Variable weniger enthält. Um den Implikanten ähnlich zur Binärdarstellung der Minterme darstellen zu können, führen wir ein Platzhaltersymbol * ein, das wir für die entfernte Binärstelle einsetzen. Zum Beispiel unterscheiden sich die beiden Minterme A B C D = 1000 und A BC D = 1010 nur in einer Stelle und werden beide von A B D = 10*0 impliziert. Um die Anzahl der Minterme, die wir vergleichen müssen, zu minimieren, können wir ausnutzen, dass sich Minterme, auf die wir obige Regel anwenden können, in der Anzahl der Einsen um genau 1 unterscheiden. Somit bietet es sich an, die Minterme zunächst nach der Anzahl der Einsen zu sortiern, um dann nur noch Minterme zu vergleichen, die sich in der Anzahl der Einsen um 1 unterscheiden. Wir generieren nun alle Implikanten mit einem Platzhalter und merken uns welche Minterme wir nicht zu Implikanten verschmolzen haben. Nun fahren wir mit den Implikanten mit einem Platzhalter fort und suchen wieder Implikanten, die sich in nur einer Binärstelle unterscheiden. Um hierbei den Aufwand zu minimieren, können wir ausnutzen, dass die Position der Platzhaltersymbole in den beiden Implikanten übereinstimmen müssen. Wir merken uns wieder die Implikanten, auf die wir die Verschmelzungsregel nicht anwenden konnten und iterieren die Suche nach neuen Implikanten so lange, bis wir keine neuen mehr finden. Dann sind alle Implikanten, die wir uns zuvor gemerkt haben Primimplikanten von f. Zur Veranschaulichung betrachten wir das folgende Beispiel aus [2, Table V]: Gegeben sei eine Boolesche Funktion f in fünf Variablen mit einschlägigen Indices 0, 1, 2, 3, 7, 14, 15, 22, 23, 29, 31. In Tabelle 2 wenden wir darauf die Verschmelzungsregel an. Die linke Tabelle enthält die Indices der Minterme und ihre Binärdarstellung. Dabei sind diese schon nach der Anzahl der Einsen gruppiert. Indem wir nun Minterme aus benachbarten Gruppen verschmelzen erhalten wir die mittlere Tabelle. Nun hat jede Zeile zwei Indices, da durch Einsetzen von 0 oder 1 für das Platzhaltersymbol * zwei Indices impliziert werden. Die Tabelle ist diesmal nach der Position des Platzhaltersymbols gruppiert. Innerhalb dieser Gruppen wenden wir wieder die Verschmelzungsregel auf Implikanten an, die sich in nur einer Stelle unterscheiden und erhalten dadurch die rechte Tabelle. Implikanten, die dabei nicht weiter verschmolzen werden konnten, sind bereits Primimplikanten und wurden mit einem gekennzeichnet. In der rechten Tabelle können wir keine weitere Verschmelzung mehr durchführen, weshalb beide Implikanten markiert werden. Damit sind wir fertig und haben alle Primimplikanten von f gefunden. Suche Überdeckung mit minimalen Kosten Aus dem vorherigen Schritt des Quine-McCluskey-Algorithmus haben wir eine Liste mit allen Primimplikanten von f. Außerdem haben wir aus der Wahrheitstabelle von f eine Liste mit allen Mintermen zu einschlägigen Indices von f. Damit können wir folgende Matrix, bzw. Tabelle aufstellen: { 1 primeimplicant[i] impliziert Minterm j P ij := 0 sonst. 3

0 00000 1 00001 2 00010 3 00011 7 00111 14 01110 21 10110 15 01111 23 10111 29 11101 31 11111 0 1 0000* 2 3 0001* 14 15 0111* 22 23 1011* 0 2 000*0 1 3 000*1 29 31 111*1 3 7 00*11 7 15 0*111 23 31 1*111 7 23 *0111 15 31 *1111 0 1 2 3 000** 7 15 23 31 **111 Tabelle 2: Beispiel aus [2, Table V], Primimplikanten mit gekennzeichnet 0 1 2 3 7 14 15 22 23 29 31 ( 3 7) 1 1 (14 15) 1 1 (22 23) 1 1 (29 31) 1 1 (0 1 2 3) 1 1 1 1 (7 15 23 31) 1 1 1 1 Tabelle 3: Primimplikantentabelle zum Beispiel aus [2, Table V] Die Primimplikantentabelle P zu dem Beispiel aus Tabelle 2, sieht dann wie in Tabelle 3 aus. Würde die Funktion Don t-care-terme enthalten, würden die zugehörigen Spalten in der Tabelle fehlen. Damit die Summe der Primimplikanten, die wir im Folgenden auswählen werden, die Funktion f darstellt, muss diese Summe jeden Minterm zu einschlägigen Indices von f implizieren. Das heißt die zu den ausgewählten Primimplikanten gehörigen Zeilen in der Tabelle P müssen eine Teilmatrix bilden, die in jeder Spalte mindestens eine 1 enthält. Diese Auswahl an Zeilen von P nennen wir auch eine Überdeckung der Spalten von P. Jeder Überdeckung weisen wir die Kosten der Summe der zu ihren Zeilen gehörigen Primimplikanten zu. Wir nennen eine Überdeckung minimal, wenn es keine andere Überdeckung gibt, die geringere Kosten hat. Die Summe der Primimplikanten aus einer minimalen Überdeckung ist dann eine der gesuchten minimalen disjunktiven Formen von f. Die Suche nach minimalen Überdeckungen können wir mit dem folgenden Algorithmus durchführen, der einfach alle Kandidaten für eine minimale Überdeckung auflistet und danach die Kosten dieser Kandidaten vergleicht. covers [] Generiere eine Liste aller Überdeckungen der Spalten von P for all i with P i1 = 1 do covers.append({i}) 5: for j 2,..., j max do Erstellen von Überdeckungen durch sukzessives hinzufügen von Spalten newcovers [] for all cover covers do for all i with P ij = 1 do newcover cover {i} 10: insert true for all cover newcovers do if newcover cover then newcovers newcovers cover else if newcover cover then 4

15: insert false end if if insert then newcovers.append(newcover) 20: end if covers newcovers 25: result [] Suche Überdeckungen mit minimalen Kosten in der vorher erstellten Liste mincost for all cover covers do if cost(cover) < mincost then mincost cost(cover) 30: result [] end if if cost(cover) mincost then result.append({primeimplicant[i] i cover}) end if 35: Um die Tabelle P möglichst klein zu halten, können wir vor dem Suchen nach Überdeckungen alle Zeilen löschen, für die es eine Spalte gibt, die nur von dieser einen Zeile überdeckt wird (diese Spalte kann dann natürlich auch gelöscht werden). Die zu diesen Zeilen gehörigen Primimplikanten nennen wir essentielle Primimplikanten, da sie in jeder minimalen disjunktiven Normalform zur gegebenen Wahrheitstabelle vorkommen müssen. Deshalb können wir diese in einer Liste speichern und später an jede der Lösungen anhängen, die wir mithilfe der verkleinerten Tabelle P erhalten. Für unser Beispiel aus Tabelle 3 erhalten wir nach Entfernen aller essentiellen Primimplikanten die deutlich kleinere Tabelle 4. 7 (3 7) 1 (7 15 23 31) 1 Tabelle 4: Tabelle 3 nach Löschen aller essentiellen Primimplikanten Dateiformat für Wahrheitstabellen Für Wahrheitstabellen verwenden wir ein einfaches Textformat, das folgendermaßen aufgebaut ist. Die Datei besteht aus Blöcken, die jeweils mit einem Stichwort gefolgt von einem Doppelpunkt eingeleitet werden. Der erste Block beginnt mit dem Stichwort Variables und enthält danach einen einzelnen Integer, der die Anzahl der Variablen in der Wahrheitstabelle angibt. Danach kommt der Block Ones, der die Minterme mit f(m) = 1 angibt. Der Block fängt mit einem Integer n an, der die Anzahl der Minterme angibt. Danach folgen n Integer, die den Indices der Minterme entsprechen. Analog gibt es noch einen Block Don t Cares, der die Don t-care-terme im gleichen Format, wie der Block Ones angibt. Beispielsweise sieht die zur Verfügung gestellte Wahrheitstabelle truthtable1 folgendermaßen aus: Variables : 4 Ones : 6 4 8 10 5

11 12 15 Don t Cares : 2 9 14 Aufbau des Programms Ihr Programm soll eine Wahrheitstabelle einlesen und mithilfe des Quine-McCluskey-Algorithmus alle kürzesten Sum-of-Products-Darstellungen zur Wahrheitstabelle finden. Die unit.{h,o} stellt die Funktion bool solution ( const char * examplename, const std :: vector < sumofproducts > & sops ); zur Verfügung, mit der Sie Ihr Ergebnis überprüfen können. Testdaten Im Ordner examples sind mehrere Wahrheitstabellen enthalten, deren minimalen Sum-of-Products-Darstellungen Sie mit der oben genannten Funktion solution überprüfen können. truthtable1 Beispiel aus dem Quine-McCluskey-Artikel der Wikipedia [1] truthtable2 Beispiel aus [2, Table V] 7segment? Logik für die Segmente einer 7-Segment-Anzeige (?=1,..., 7) true Konstante 1-Funktion false Konstante 0-Funktion (+ Don t-care-terme) Hinweise zur Implementierung Minterme lassen sich effizient als die Binärdarstellung ihrer Indices speichern. Dazu könnten wir den Datentyp std::bitset<n> verwenden. Dieser ist für unsere Anwendung jedoch zu unflexibel, da die Länge N des Bitsets schon zur Compile-Zeit festgelegt werden muss. Stattdessen bietet sich der Datentyp boost::dynamic_bitset<> an, der im Header boost/dynamic_bitset.hpp 1 definiert ist. Dieser Datentyp ist Teil der Boost-Bibliothek 2. Dabei handelt es sich um eine Sammlung von verschiedenen C ++ -Klassen, welche die Funktionalität der STL auf nützliche Weise erweitern. Diese Erweiterungen sind in der Vergangenheit aucht teilweise schon standartisiert und in die STL übernommen worden. Installieren kann man die Boost-Header bei den meisten Linux-Distributionen komfortabel über den Paketmanager. Unter Debian heißt das entsprechende Paket beispielsweise libboost-all-dev. Die Bitset-Klassen bieten mit dem Operator [] Zugriff auf einzelne Bits und bieten einige weitere nützliche Funktionen. So zählt die Methode count z. B. die Anzahl der Einsen in einem Bitset. Ein Blick in die Dokumentation liefert noch einige weitere Methoden, die beim Lösen dieser Aufgabe hilfreich sein könnten. Um jetzt zusätzlich noch die Platzhaltersymbole * speichern zu können, benutzen wir zusätzlich zu dem Bitset, das den Index enthält noch ein weiteres Bitset, in dem wir zu jeder Variable vermerken, ob diese im Implikanten enthalten ist. Um eine eindeutige Darstellung zu erhalten können wir zusätzlich an den Stellen mit Platzhaltersymbolen das Bit für die Verneinung der zugehörigen Variablen auf 0 setzen. 1 http://www.boost.org/doc/libs/release/libs/dynamic_bitset/dynamic_bitset.html 2 http://www.boost.org/ 6

Um eine Liste von Primimplikanten abzuspeichern bieten sich std::list und std::vector an. Ersteres erlaubt günstiges Einfügen und Löschen von Elementen, während Letzteres wahlfreien Zugriff auf Elemente bietet. Eventuell könnten auch die Datentypen std::set und std::map nützlich sein. Für alle diese Container-Klassen finden Sie im Header algorithms Funktionen zum Suchen nach Elementen und einige Mengen-Operationen, von denen Sie vor allem includes zur Überprüfung von Teilmengen gebrauchen können. In den vorgegebenen Quelltext-Gerüsten sind noch zu bearbeitende Stellen mit TODO-Kommentaren gekennzeichnet. Die Datei qmc.cpp enthält die main-funktion und die von Ihnen zu schreibende Funktion QuineMcCluskey, die den Algorithmus von Quine-McCluskey ausführen soll, um alle kostenminimalen disjunktiven Formen einer gegebenen Wahrheitstabelle zu finden. In den Dateien types.{h,cpp} finden Sie schon einige vordefinierte Datentypen, die Ihnen bei der Implementierung behilflich sein werden. Hier müssen Sie noch die Klasse primeimplicantchart vervollständigen die für die zweite Phase des Algorithmus von Quine-McCluskey benötigt wird. Literatur [1] Wikipedia-Artikel zum Quine McCluskey Algorithmus. http://en.wikipedia.org/wiki/quine McCluskey_algorithm. [2] McCluskey, E. J.: Minimization of Boolean Functions. Bell System Technical Journal, 35(6):1417 1444, 1956. http://alcatel-lucent.com/bstj/vol35-1956/articles/bstj35-6-1417.pdf. [3] Oberschelp, W. und G. Vossen: Rechneraufbau und Rechnerstrukturen. Oldenbourg Wissenschaftsverlag, Berlin, 10. Auflage, 2006. 7