· 

Ein mathematisches Machtmodell

Koalitionsspiele werden üblicherweise nach Wahlen oder in Abstimmungssituationen aller Art gespielt. Die Spieltheorie liefert uns Antworten auf die Koalitionsfrage (also welche Fraktionen/Parteien sich zwecks Erreichen eines Quorums zusammenschließen). Eine Möglichkeit der mathematischen Beschreibung von Macht ist durch den Banzhaf'schen Machtindex möglich, um den es in diesem Artikel geht.

Was bedeutet Macht?

Definition: Macht

Unter Macht verstehen wir den Einfluss auf das Ergebnis von Abstimmungen. Diese Vorstellung von Macht bezeichnen wir auch als Abstimmungsmacht.
  • Mehr Stimmen bedeuten mehr Abstimmungsmacht.
  • Erhält man nach einer Wahl mehr Stimmen als man vorher hatte, so steigt die Macht. Bleibt die Stimmenanzahl vor und nach der Wahl gleich, ändert sich die Abstimmungsmacht nicht. Ansonsten sinkt die Abstimmungsmacht.
  • Mitglieder \(m_i\) einer Fraktion \(F\) können insgesamt nicht mehr Abstimmungsmacht besitzen als die Fraktion selbst, d.h. die Summe aller Abstimmungsmächte aller \(m_i\in F\) entspricht (exakt) der Abstimmungsmacht von \(F\).
  • Beteiligen sich weitere Spieler und Fraktionen an dem Abstimmungsspiel, so sinkt die Macht im Allgemeinen.
  • Feinden sich die Fraktionen \(F_1\) und \(F_2\) derart an, dass sie nicht bereit sind eine Koalition \(K = \{F_1,F_2\}\) einzugehen, sinkt die Abstimmungsmacht von \(F_1\) und \(F_2\).

Fraktionen, Koalitionen, Quorum

Um zu verstehen, wie Koalitionsbildung von Fraktionen, Stimmen und Quoren (Plural von Quorum) zusammenhängen, müssen wir diese Begriffe zunächst definieren:

Definition: Fraktion

Eine Fraktion \(F\) ist eine Einheit, die in einer Abstimmung Stimmen abgibt. Eine Fraktion besteht aus Mitgliedern \(m_1, m_2, ..., m_n\). Ist \(\mathcal{F}\) die Menge aller Fraktionen, dann ordnet die Funktion \(s:\mathcal{F}\rightarrow \mathbb{N}\) einer Fraktion \(F\in\mathcal{F}\) eine Stimmzahl \(s\in\mathbb{N}\) zu.
Definition: Stimme

Eine Stimme \(S\in\mathbb{N}\) ist eine Einheit, die von Mitgliedern einer Fraktion eingesetzt wird. Eine Fraktion \(F\) besitzt genau \(s(F)\) Stimmen. Die Anzahl der Stimmen entscheidet darüber, ob ein Quorum erreicht wird. Jedes Mitglied \(m_i\in F\) besitzt genau eine Stimme. Die Anzahl der Stimmen einer Fraktion ergibt sich durch die Anzahl der Stimmen ihrer Mitglieder. Eine Fraktion mit den Mitgliedern \(m_1, m_2, ..., m_n\) hat also \(\underbrace{1 + 1 + ... + 1}_{n \text{ mal}}=n\) Stimmen.
Wir nehmen für unsere Überlegungen an, dass in einer Abstimmung alle Mitglieder einer Fraktion einstimmig entscheiden.
Definition: Quorum

Ein Quorum \(Q\) ist die notwendige Anzahl an Stimmen, die erreicht sein muss, damit eine Abstimmung Gültigkeit erlangt. Wir unterscheiden (wie in der Politik) Quoren, für die eine einfache Mehrheit (also \(\gt 50\%\)) der Stimmen genügt und welchen, bei denen mindestens \(\frac{2}{3}\) der Stimmen benötigt werden.
Definition: Koalition

Gegeben seien \(n\) Fraktionen \(F_1, F_2, ..., F_n\) mit den Stimmenzahlen \(s(F_1)=s_1, s(F_2)=s_2, ..., s(F_n)=s_n\). Eine Koalition \(K\) ist eine Teilmenge aller Fraktionen: \(K\subseteq\{F_1, F_2, ..., F_n\}\). Die Anzahl der Stimmen von \(K\) ergibt sich durch die Summe der Stimmen aller an \(K\) beteiligten Fraktionen, d.h. die Anzahl der Stimmen der Koalition \(K=\{F_1,F_3,F_5\}\) (lies: „Koalition der Fraktionen \(F_1, F_3\) und \(F_5\)“) ist \(s_1 + s_3 + s_5\).
Ist \(s=s_1+s_2+...+s_n\) die Gesamtzahl aller Stimmen bei einer Abstimmung, so ist das Quorum erreicht (und der Beschluss durchgesetzt), wenn gilt:
  • Einfache Mehrheit: $$\sum_{i\in I}{s_i\gt \underbrace{0.5s}_{Q_{\gt 0.5}}}$$
  • \(\frac{2}{3}\) Mehrheit: $$\sum_{i\in I}{s_i\geq \underbrace{\frac{2}{3}s}_{Q_{\geq\frac{2}{3}}}}$$
Dabei ist \(I\subseteq\{1,2,...,n\}\) eine Teilmenge aller möglichen Indizes für die Stimmen. Die Kombination der Indizes entspricht den Koalitionsbildungsmöglichkeiten von \(F_1, F_2, ..., F_n\).
Wir unterscheiden zwei Typen von Koalitionen:
Definition: Gewinnende und verlierende Koalition

Gegeben seien die Fraktionen \(F_1,F_2,...,F_n\) mit den zugehörigen Stimmzahlen \(s(F_1)=s_1,s(F_2)=s_2,...,s(F_n)=s_n\) und ein Quorum \(Q\). Wir nennen eine Koalition \(K\subseteq\{F_1,F_2,...,F_n\}\) gewinnend, wenn gilt: $$\sum_{F_i\in K}{s(F_i)}\geq Q$$ Ansonsten heißt \(K\) verlierend.

Die Abstimmung

Wir werden uns nun in einer fiktiven Abstimmungssituation dem Begriff der Abstimmungsmacht nähern. Dazu seien in einem Parlament drei Fraktionen \(F_1,F_2\) und \(F_3\) vertreten. \(F_1\) hat \(s(F_1)=50\), \(F_2\) hat \(s(F_2)=1\) und \(F_3\) hat \(s(F_3)=49\) Stimmen. Das Quorum \(Q\) betrage \(51\), d.h. \(Q=Q_{\gt 0.5}\) (da es insgesamt \(100\) Stimmen gibt und \(51\) die einfache Mehrheit ist. Wie setzen sich nun die gewinnenden und verlierenden Koalitionen zusammen? Dazu überlegen wir uns, welche Koalitionen überhaupt möglich sind. Wir haben bereits im vorangegangenen Abschnitt gelernt, dass Koalitionen Teilmengen der Menge aller Fraktionen sind. Wir können nun noch einen Schritt weitergehen und feststellen, dass bei einer Menge von \(n\) Fraktionen \(\mathcal{F}:=\{F_1,F_2,...,F_n\}\) die Menge aller Koalitionen \(\mathcal{K}\) der Potenzmenge von \(\mathcal{F}\) entspricht, d.h.: $$\mathcal{K}=\mathcal{P}(\mathcal{F})=\mathcal{P}(\{F_1,F_2,...,F_n\})$$ Somit wissen wir auch, dass bei \(n\) gegebenen Fraktionen insgesamt \(2^n\) Koalitionen möglich sind, da die Mächtigkeit der Potenzmenge einer Menge mit \(n\) Elementen \(2^n\) entspricht.
Für unser Beispiel mit den Fraktionen \(F_1, F_2\) und \(F_3\) sind folgende Koalitionen möglich: $$\mathcal{K}=\{\emptyset,\{F_1\},\{F_2\},\{F_3\},\{F_1,F_2\},\{F_1,F_3\},\{F_2,F_3\},\{F_1,F_2,F_3\}\}$$ Wir wissen, dass das Quorum bei \(51\) Stimmen liegt und dass sich die Anzahl der Stimmen einer Koalition als Summe der Stimmen aller beteiligten Fraktionen ergibt. Wir können nun ermitteln, wie viele Stimmen die einzelnen Koalitionen besitzen:
\begin{array}{|l|c|} \hline \text{Koalition} & \text{Stimmen}\\\hline \emptyset & 0 \\\hline \{F_1\} & 50\\\hline \{F_2\} & 1\\\hline \{F_3\} & 49\\\hline \{F_1,F_2\} & 51\\\hline \{F_1,F_3\} & 99\\\hline \{F_2,F_3\} & 50\\\hline \{F_1,F_2,F_3\} & 100\\\hline \end{array}
Bei den \(\{F_1,F_2\},\{F_1,F_3\}\) und \(\{F_1,F_2,F_3\}\) handelt es sich um gewinnende Koalitionen, da durch diese das Quorum \(Q_{\gt 0.5}=51\) erreicht wird.
Nun notieren wir, in wie vielen gewinnenden Koalitionen die einzelnen Fraktionen vertreten sind:
\begin{array}{|c|c|} \hline \text{Fraktion} & \text{Anzahl gewinnender Koalitionen}\\\hline F_1 & 3\\\hline F_2 & 2\\\hline F_3 & 2\\\hline \end{array}
\(F_1\) ist in allen gewinnenden Koalitionen \(\{F_1,F_2\}, \{F_1,F_3\}\) und \(\{F_1,F_2,F_3\}\) vertreten. \(F_2\) und \(F_3\) tauchen nur in jeweils zwei gewinnenden Koalitionen, nämlich \(\{F_1,F_2\}\) und \(\{F_1,F_2,F_3\}\) bzw. \(\{F_1,F_3\}\) und \(\{F_1,F_2,F_3\}\). \(F_2\) und \(F_3\) können alleine keine gewinnende Koalition bilden, was ihnen intuitiv weniger Macht einräumt als z.B. \(F_1\), die mit jeder anderen Fraktion eine gewinnende Koalition bilden kann.
Nehmen wir nun allgemein an, dass \(F\) einer gewinnenden Koalition \(K\) angehört. Wenn \(F\) die Koalition \(K\) verlässt, dann bleibt \(K\setminus\{F\}\) übrig. Das Austreten von \(F\) aus \(K\) kann zwei Folgen haben:
  • \(K\setminus\{F\}\) bleibt weiterhin eine gewinnende Koalition.
  • \(K\setminus\{F\}\) ist nun eine verlierende Koalition.
Im ersten Fall ist der Austritt von \(F\) nicht sonderlich tragisch, da die Koalition auch ohne \(F\) das Quorum erreicht. Der zweite Fall sorgt hingegen dafür, dass \(K\setminus\{F\}\) das Quorum nicht mehr erreicht, was für alle Fraktionsmitglieder schlecht ist. In diesem Fall besitzt \(F\) also eine gewisse Macht gegenüber den anderen Koalitionspartnern, was uns zum Banzhaf'schen Machtindex führt. Vorher definieren wir jedoch noch eine Eigenschaft von Fraktionen:
Definition: Kritische Fraktion

Sei \(K=\{F_1, F_2, ..., F_n\}\) eine Koalition. Eine Fraktion \(F_i\) heißt kritisch für \(K\), wenn folgende Eigenschaften gelten:
  • \(F_i\in K\)
  • \(K\) ist eine gewinnende Koalition.
  • \(K\setminus\{F_i\}\) ist eine verlierende Koalition.
Nun können wir die Banzhaf-Macht definieren:
Definition: Banzhaf-Macht

Sei \(\mathcal{F}\) die Menge aller Fraktionen, \(F\in\mathcal{F}\) eine Fraktion und \(\mathcal{K}=\mathcal{P}(\mathcal{F})\) die Menge aller möglichen Koalitionen. Die Anzahl der Koalitionen \(K_i\in\mathcal{K}\), für die \(F\) eine kritische Fraktion ist, heißt Banzhaf-Macht \(P_B(F)\) von \(F\).
Darauf aufsetzend definieren wir den Banzhaf-Index:
Definition: Banzhaf-Index

Gegeben seien die Fraktionen \(F_1, F_2, ..., F_n\). Der Banzhaf-Index \(I_B(F_i)\) von \(F_i\) ergibt sich durch: $$I_B(F_i) = \frac{P_B(F_i)}{\sum\limits_{k=1}^{n}{P_B(F_k)}}=\frac{P_B(F_i)}{P_B(F_1)+P_B(F_2)+...+P_B(F_n)} $$ Es ist \(I_B(F_i)\in[0,1]\) und \(\sum\limits_{k=1}^{n}{P_B(F_k)}\) die Summe der Banzhaf-Mächte aller Fraktionen.
Ein Banzhaf-Index von \(0\) bedeutet, dass die Banzhaf-Macht der entsprechenden Fraktion \(0\) ist. Hat eine Fraktion \(F\) einen Banzhaf-Index von \(1\), dann besitzen alle anderen Fraktionen eine Banzhaf-Macht von \(0\). Die Summe der Banzhaf-Mächte aller Fraktionen muss \(1\) sein.

Wir berechnen abschließend die Banzhaf-Indizes für unser Abstimmungsbeispiel mit den Fraktionen \(F_1, F_2\) und \(F_3\). Die Anzahl der gewinnenden Koalitionen, die wir bereits tabellarisch erfasst haben, genügt für die Berechnung der Banzhaf-Macht nicht, da eine Fraktion innerhalb einer gewinnenden Koalition nicht automatisch kritisch ist. Aus diesem Grund listen wir für jede Fraktion auf, für welche gewinnenden Koalitionen sie kritisch sind.
\begin{array}{|c|l|c|} \hline \text{Fraktion} & \text{kritisch für} & P_B(F_i)\\\hline F_1 & \{F_1,F_2\},\{F_1,F_3\},\{F_1,F_2,F_3\} & 3\\\hline F_2 &\{F_1,F_2\} & 1\\\hline F_3 & \{F_1,F_3\} & 1\\\hline \end{array}
Daraus können wir die Banzhaf-Indizes berechnen. Es ist \(\sum\limits_{k=1}^{3}{P_B(F_k)}=3+1+1=5\) (Nenner). Daraus ergibt sich folgende Tabelle:
\begin{array}{|c|c|c|} \hline \text{Fraktion} & P_B(F_i) & I_B(F_i)\\\hline F_1 & 3 & \frac{3}{5}\\\hline F_2 & 1 & \frac{1}{5}\\\hline F_3 & 1 & \frac{1}{5}\\\hline \end{array}
Interessanterweise besitzen die Fraktionen \(F_2\) und \(F_3\) nach Banzhaf dieselbe Abstimmungsmacht, obwohl sie sich von der Mitgliederzahl (und dementsprechend der Stimmgewalt) sehr stark unterscheiden.

Python-Programm zur Simulation einer Wahl

Wir können uns nun ein kleines Simulationsprogramm in Python schreiben, mit dem man dieses mathematische Machtmodell auf reale Situationen anwenden und somit die "Abstimmungsmacht" (nach Banzhaf) für die an der Wahl beteiligten Parteien ermitteln kann.

Zuerst wird der Import itertools benötigt, der beim Berechnen der Potenzmenge aller Fraktionen (also zum Ermitteln der Koalitionen) verwendet wird. 

import itertools

Als erstes schreiben wir uns eine kleine Fraktionsklasse. Diese erhält im Konstruktor einen Namen und eine Anzahl an Stimmen, die maßgeblich über die tatsächliche Abstimmungsmacht mitentscheidet. Diese Werte weisen wir entsprechenden Objektvariablen zu. Zusätzlich definieren wir noch je eine Objektvariable für die Banzhaf-Macht und den Banzhaf-Index. Beide Objektvariablen werden mit dem Startwert 0 initialisiert.

class Fraktion:
    def __init__(self, name, stimmen):
        self.name = name
        self.stimmen = stimmen
        self.banzhaf_macht = 0
        self.banzhaf_index = 0

Nun werden für die Objektvariablen entsprechende Getter-Methoden implementiert, also get_name, get_stimmen, get_banzhaf_macht und get_banzhaf_index

    def get_name(self):
        return self.name
        
    def get_stimmen(self):
        return self.stimmen
        
    def get_banzhaf_macht(self):
        return self.banzhaf_macht
        
    def get_banzhaf_index(self):
        return self.banzhaf_index

Zudem definieren wir eine Methode ist_kritisch, die den Wert der Banzhaf-Macht um 1 erhöht. Diese Methode wird auf einer Fraktion aufgerufen, wenn das Wegbleiben der Stimmen dieser Fraktion innerhalb einer gewinnenden Koalition dafür sorgt, dass diese Koalition dann verlierend ist. 

    def ist_kritisch(self):
        self.banzhaf_macht += 1

Zum Schluss wird eine Methode berechne_banzhaf_index implementiert, die für eine Fraktion den Banzhaf-Index berechnet. Dazu wird als Parameter die Summe aller Banzhaf-Mächte n übergeben. Der Banzhaf-Index berechnet sich dann durch den Quotienten der Banzhaf-Macht und der Summe aller Banzhaf-Mächte n.

    def berechne_banzhaf_index(self, n):
        self.banzhaf_index = self.banzhaf_macht/n

Als nächstes definieren wir eine Klasse Koalition. Da eine Koalition ein Zusammenschluss von Fraktionen ist, wird im Konstruktor eine Liste von Fraktionen übergeben und diese einer Objektvariable zugewiesen. Zudem wird eine Objektvariable stimmen definiert, die anfangs auf 0 gesetzt wird. In einer For-Schleife wird über alle Fraktionen innerhalb der Koalition iteriert und die Stimmen addiert. Die Anzahl der Stimmen einer Koalition ergibt sich schließlich als Summe der Stimmen aller darin enthaltenen Fraktionen. 

class Koalition: 
    def __init__(self, fraktionen):
        self.fraktionen = fraktionen
        self.stimmen = 0
        for fraktion in self.fraktionen:
            self.stimmen += fraktion.get_stimmen()

Für die Objektvariablen fraktionen und stimmen werden nun entsprechende Getter-Methoden vorgesehen. 

    def get_stimmen(self):
        return self.stimmen
        
    def get_fraktionen(self):
        return self.fraktionen

Zusätzlich gibt es eine Funktion kritische_fraktionen, die diejenigen Fraktionen innerhalb der Koalition ermittelt, die gemäß unserer Definition kritisch sind. Dazu wird über alle Fraktionen in der Koalition iteriert und geprüft, ob die Anzahl der Stimmen in der Koalition nicht mehr ausreicht, wenn man von der Gesamtanzahl an Stimmen die der jeweiligen Fraktion entfernt. Wenn das der Fall ist, wird die Funktion ist_kritisch auf der entsprechenden Fraktion ausgerufen, welche die Banzhaf-Macht der Fraktion um 1 erhöht. Dementsprechend muss der Methode das Quorum, gegen das geprüft werden soll, als Parameter übergeben werden.

    def kritische_fraktionen(self, quorum):
        for fraktion in self.fraktionen:
            if self.get_stimmen() - fraktion.get_stimmen() < quorum:
                fraktion.ist_kritisch()

Zum Schluss definieren wir noch eine Methode ist_gewinnend, mit der entschieden werden kann, ob abhängig von einem bestimmten Quorum, eine Koalition gewinnend ist. Das wird gemacht, indem man prüft, ob die Stimmen der Koalition das Quorum erreichen.

    def ist_gewinnend(self, quorum):
        return self.stimmen >= quorum

Zum Schluss definieren wir noch eine Klasse Abstimmung. Diese erhält im Konstruktor ein Quorum und eine Liste mit Fraktionen, die an einer Abstimmung teilnehmen. Diese werden entsprechenden Objektvariablen zugewiesen. Zudem definieren wir zwei Objektvariablen koalitionen und gewinnend in Form einer leeren Liste, die einmal alle möglichen Koalitionen speichern und diejenigen, die gewinnend gemäß unserer Definition sind. Im Konstruktor wird die Liste mit den möglichen Koalitionen direkt gefüllt, indem wir zuerst die Potenzmenge der übergebenen Fraktionen berechnen und die Ergebnisse dann nacheinander einfügen. Wichtig ist, dass innerhalb dieser Liste Koalitionen stehen, d.h. wir erzeugen in jedem Schleifendurchlauf ein Koalitionsobjekt, das als Übergabeparameter eine Liste mit den Fraktionen erhält. 

class Abstimmung:
    def __init__(self, quorum, *fraktionen):    
        self.fraktionen = fraktionen
        self.quorum = quorum
        self.koalitionen = []
        self.gewinnend = []
        potenzmenge = [x for length in range(len(self.fraktionen)+1) for x in itertools.combinations(self.fraktionen, length)]
        for fraktion in potenzmenge:
            self.koalitionen.append(Koalition(list(fraktion)))

Als nächstes schreiben wir uns eine Methode gewinnende_koalitionen, die alle gewinnenden Koalitionen berechnet und somit die Objektvariable gewinnend füllt. Das wird getan, indem wir über alle ermittelten Koalitionen iterieren und die Koalition in die Liste der gewinnenden Koalitionen eintragen, wenn sie gewinnend ist. Um dies entscheiden zu können, verwenden wir die zuvor in der Klasse Koalition implementierte Methode ist_gewinnend.

    def gewinnende_koalitionen(self):
        for koalition in self.koalitionen:
            if koalition.ist_gewinnend(self.quorum):
                self.gewinnend.append(koalition)

Diese Methode kann nun auch im Konstruktor aufgerufen werden.

Als nächstes schreiben wir eine Methode kritische_fraktionen, die für alle gewinnenden Koalitionen die kritischen Fraktionen berechnet und somit das Quorum an die Koalitions-Instanzen weiterreicht. Es wird einfach nur in einer For-Schleife über die gewinnenden Koalitionen iteriert und auf den Koalitions-Instanzen die Methode kritische_fraktionen aufgerufen, der das Quorum übergeben wird. 

    def kritische_fraktionen(self):
        for koalition in self.gewinnend:
            koalition.kritische_fraktionen(self.quorum) 

Nun wird eine Methode geschrieben, mit der die Berechnung der Banzhaf-Indizes der Fraktionen getriggert werden kann. Da in der Abstimmung alle Koalitionen und Fraktionen vorhanden sind und die Fraktionen nichts voneinander wissen, braucht es diese Methode, um den Nenner des Bruchs zur Berechnung der Banzhaf-Indizes zu ermitteln. Zuerst wird dieser Nenner n mit dem Wert 0 initialisiert. Anschließend wird in einer For-Schleife über alle Fraktionen iteriert und die Banzhaf-Mächte der Fraktionen addiert. Danach wird erneut in einer For-Schleife jede Fraktion durchlaufen und die Methode berechne_banzhaf_index aufgerufen, der der zuvor ermittelte Nenner übergeben wird. 

    def berechne_banzhaf_indizes(self):
        n = 0
        for fraktion in self.fraktionen:
            n += fraktion.get_banzhaf_macht()
        for fraktion in self.fraktionen:
            fraktion.berechne_banzhaf_index(n)

Abschließend schreiben wir eine Funktion simulieren, die nacheinander die kritischen Fraktionen und die Banzhaf-Indizes berechnet und die Ergebnisse übersichtlich ausgibt. 

    def simulieren(self):
        self.kritische_fraktionen()
        self.berechne_banzhaf_indizes()
        for fraktion in self.fraktionen:
            print(fraktion.get_name() + " - " + str(fraktion.get_banzhaf_index()))

Mit den Daten des Bundeswahlleiters kannst du die mathematische Machtverteilung in dem Koalitionsspiel der Bundestagswahl 2017 ermitteln. Dazu definierst du zunächst Fraktionsobjekte für alle an der Wahl beteiligten Parteien mit den entsprechenden Sitzanteilen im Bundestag. Danach instantiierst du ein Abstimmungsobjekt, dem du als Quorum 355 übergibst, da insgesamt 709 Sitze vergeben wurden und eine absolute Mehrheit erforderlich ist. Zusätzlich übergibst du die an der Wahl beteiligten Fraktionen bzw. Parteien (die Parteien, die es nicht über die 5%-Hürde geschafft haben, bleiben an dieser Stelle unbeachtet). Durch einen Aufruf der Methode simulieren auf dem Abstimmungsobjekt kannst du die Bundestagswahl 2017 simulieren bzw. die mathematische Macht der einzelnen Fraktionen ermitteln. Als Ergebnis erhältst du die folgende Übersicht: 

CDU - 0.2903225806451613
SPD - 0.1935483870967742
AFD - 0.16129032258064516
FDP - 0.0967741935483871
Die Linke - 0.0967741935483871
Grüne - 0.0967741935483871
CSU - 0.06451612903225806

Dieses Programm kannst du für alle möglichen Koalitionsspiele anwenden. Ein für uns interessantes Koalitionsspiel wird wieder im Jahr 2021 gespielt. 


Quellcode

Der gesamte Quellcode des Python-Simulationsprogramms kann hier heruntergeladen werden.

import itertools

class Fraktion:
    def __init__(self, name, stimmen):
        self.name = name
        self.stimmen = stimmen
        self.banzhaf_macht = 0
        self.banzhaf_index = 0
        
    def get_name(self):
        return self.name
        
    def get_stimmen(self):
        return self.stimmen
        
    def get_banzhaf_macht(self):
        return self.banzhaf_macht
        
    def get_banzhaf_index(self):
        return self.banzhaf_index
     
    def ist_kritisch(self):
        self.banzhaf_macht += 1
    
    def berechne_banzhaf_index(self, n):
        self.banzhaf_index = self.banzhaf_macht/n
        
class Koalition: 
    def __init__(self, fraktionen):
        self.fraktionen = fraktionen
        self.stimmen = 0
        for fraktion in self.fraktionen:
            self.stimmen += fraktion.get_stimmen()
            
    def get_stimmen(self):
        return self.stimmen
        
    def get_fraktionen(self):
        return self.fraktionen
        
    def kritische_fraktionen(self, quorum):
        for fraktion in self.fraktionen:
            if self.get_stimmen() - fraktion.get_stimmen() < quorum:
                fraktion.ist_kritisch()
 
    def ist_gewinnend(self, quorum):
        return self.stimmen >= quorum
        
class Abstimmung:
    def __init__(self, quorum, *fraktionen):    
        self.fraktionen = fraktionen
        self.quorum = quorum
        self.koalitionen = []
        self.gewinnend = []
        potenzmenge = [x for length in range(len(self.fraktionen)+1) for x in itertools.combinations(self.fraktionen, length)]
        for fraktion in potenzmenge:
            self.koalitionen.append(Koalition(list(fraktion)))
    
    def gewinnende_koalitionen(self):
        for koalition in self.koalitionen:
            if koalition.ist_gewinnend(self.quorum):
                self.gewinnend.append(koalition)
    
    def kritische_fraktionen(self):
        for koalition in self.gewinnend:
            koalition.kritische_fraktionen(self.quorum)     

    def berechne_banzhaf_indizes(self):
        n = 0
        for fraktion in self.fraktionen:
            n += fraktion.get_banzhaf_macht()
        for fraktion in self.fraktionen:
            fraktion.berechne_banzhaf_index(n)
    
    def simulieren(self):
        self.gewinnende_koalitionen()
        self.kritische_fraktionen()
        self.berechne_banzhaf_indizes()
        for fraktion in self.fraktionen:
            print(fraktion.get_name() + " - " + str(fraktion.get_banzhaf_index()))
        
cdu = Fraktion("CDU", 200)
spd = Fraktion("SPD", 153)
afd = Fraktion("AFD", 94)
fdp = Fraktion("FDP", 80)
linke = Fraktion("Die Linke", 69)
gruene = Fraktion("Grüne", 67)
csu = Fraktion("CSU", 46)

abstimmung = Abstimmung(355, cdu, spd, afd, fdp, linke, gruene, csu)
abstimmung.simulieren()