MuPAD Education Group: Kostenlose Materialen für MuPAD Pro:
www.sciface.com/education, schule.mupad.de, studium.mupad.de, mupad.zum.de.

________________________________________________________________________________

 

Inhalt....: Konstruktion von Primzahlen

Kategorie.: Unterrichtsmaterial

Mathematik: Zahlentheorie

MuPAD.....: 3.1.0

Datum.....: 2006-10-24

Autoren...: August Barkhausen <abarkhausen@gmx.de>

Funktionen: for, if, print, Typeset, min, numlib::primedivisors, testeq, matrix

Funktionen: map, testeq

________________________________________________________________________________

 

Konstruktion von Primzahlen nach einem

Beweis des Satzes von Euklid über die

Anzahl von Primzahlen

 

Im folgenden wird ein Algorithmus zur Berechnung von Primzahlen durchgeführt, der

auf die in dem Buch "Elementare Zahlentheorie" von Remmert und Ulrich, 2. Auflage

Birkhäuser1995 dargestellte Version des Satzes von Euklid zurückgeht. Der Algorith-

mus wird zunächst heuristisch und dann mit einer Programmierlösung durchgeführt.

In diesem Zusammenhang wird darüber hinaus nachgewiesen, dass die gefundenen

Zahlen tatsächlich Primzahlen sind.

Im Rahmen der heuristischen Vorarbeit wird darüber hinaus mit gezeigt, dass die

gefundenen Primzahlen paarweise voneinander verschieden sind.

 

Am Ende des Notebooks finden sich Anregungen für Folgeaufgaben.

 

Als mathematischer Hintergrund werden ausreichende Kenntnisse über Primzahlen

und Primfaktorzerlegungen sowie Grundkenntnisse der Logik vorausgesetzt. Aus

dem Bereich der EDV werden Programmierkenntnisse benötigt. Schließlich werden

zur Simulation von Tabellen Matrizen benutzt. Wenn keine mathematischen Kennt-

nisse über Matrizen bzw. Vektoren vorhanden sind, sollte zumindest erklärt werden,

wie man Matrizen in MuPAD erstellen und zur Datenein- und ausgabe nutzen kann. 

Aus der Zahlentheorie (siehe zum Beispiel Remmert, Ulrich: "Elementare Zahlentheorie",

2. Auflage Birkhäuser 1995 S. 25 ff) ist bekannt, dass es unendlich viele Primzahlen gibt.

Genauer gilt: Sind die Primzahlen q1, q2, ... ,qn  bekannt, so ist der kleinste

Teiler t > 1 der natürlichen Zahl a = (q1*q2*...*qn + 1) eine Primzahl, die von den

bisherigen Primzahlen q1, q2, ....., qn verschieden ist.

 

Es soll (sollen) in diesem Notebook

1) schrittweise beginnend mit 2 einzelne Primzahlen mit dem angegebenen Algorithmus

    konstruiert werden.

2) nachgewiesen werden, dass die so konstruierten Zahlen tatsächlich Primzahlen sind.

3) die Aussage, dass die so konstruierte Primzahl von den Primzahlen q1, q2, ..... qn

    paarweise verschieden ist, außerhalb der Programmierlösung nachgewiesen werden.

4) in einer Programmierlösung Primzahlen nach dem angegebenen Algorithmus konstruiert

    werden.

5) nachgewiesen werden, dass die in der Programmierlösung ermittelten Zahlen tatsächlich

    Primzahlen sind.

6) überprüft werden, ob mit dem Algorithmus alle Primzahlen ermittelt werden.

 

Heuristische Lösung

 

Zunächst werden iterativ ausgehend von der Primzahl 2 zwei Primzahlen in Einzelschritten

bestimmt, um den Algorithmus zu überprüfen. An dieser Stelle erscheint eine Prüfung durch

MuPAD, ob die gefundenen Zahlen Primzahlen sind, noch überflüssig, da diese Eigenschaft

bei den gefundenen Zahlen offensichtlich ist. Andererseits ist die Eigenschaft "Primzahl"

bei großen Zahlen nicht mehr offensichtlich. Insofern wird hier die Prüfung zur Erklärung

und Kontrolle des Algorithmus doch durchgeführt. 

 

Um zu erkennen, ob eine Zahl Primzahl ist, lässt man zweckmäßigerweise durch MuPAD

die Primfaktorzerlegung durchführen. Eine Probe, ob eine natürliche Zahl a Primzahl ist, ist 

mit MuPAD ist wie folgt möglich:

Zunächst wird die Primfaktorzerlegung der Zahl a mit dem Befehl primedivisors durchgeführt.

Dann prüft man, ob das erste Element der Primfaktorzerlegung von a  identisch mit der der

Zahl a ist.

Sind beide Zahlen identisch, kann es keine weiteren Elemente der Primfaktorzerlegung geben

und die gefundenen Zahl ist tatsächlich eine Primzahl. Anderenfalls ist a keine Primzahl. 

 

 

Der Algorithmus zur Bestimmung von Primzahlen weicht in einem Punkt von der oben

angegebenen Theorie ab. Entsprechend der Theorie ist der kleinste von 1 verschiedene

Teiler der Zahl a die neue Primzahl. In MuPAD entspricht dies dem Befehl

"numlib::divisors[2]", da MuPAD die Teiler von links nach rechts in wachsender Größe

anordnet.

In diesem Notebook wird abweichend davon der kleinste Primteiler benutzt. Da der kleinste

Primteiler allerdings mit dem kleinsten von 1 verschiedenem Teiler entspricht, ist es möglich,

auch mit diesem Wert zu rechnen. In MuPAD spricht man den kleinsten Primteiler mit

dem Befehl "numlib::primdivisors[1]" an.

 

Wir beginnen mit der ersten Primzahl 2. (Die Zahl 1 ist keine Primzahl)

 

primzahl1:=2

math

Die zweite potenzielle Primzahl wird konstruiert.

 

primzahl2:=min(numlib::primedivisors(primzahl1+1))

math

Es wird überprüft, ob die gefundene Zahl tatsächlich Primzahl ist. Bei der Antwort

True handelt es sich um eine Primzahl, bei der Antwort false liegt keine Primzahl vor. 

 

testeq(numlib::primedivisors(primzahl1+1)[1]=primzahl2)

math

Es wird nun überprüft, ob die gefundene neue Primzahl von den bisher bekannten

Primzahlen verschieden ist. Bei der Antwort false sind die Zahlen des überprüften

Zahlenpaares voneinander verschieden.

testeq(primzahl1=primzahl2)

math

Die ersten beiden Primzahlen sind somit voneinander verschieden.

 

Die dritte potenzielle Primzahl wird konstruiert.

 

primzahl3:=

  min(numlib::primedivisors(primzahl1*primzahl2+1))

math

Es wird nachgewiesen, dass die gefundene Zahl eine Primzahl ist.

 

testeq

  (numlib::primedivisors(primzahl1*primzahl2+1)[1]=primzahl3)

math

Es wird nachgewiesen, dass die gefundene Primzahl von den beiden bisher bekannten

Primzahlen verschieden ist.

 

testeq(primzahl1=primzahl3)

math

testeq(primzahl2=primzahl3)

math

Bereits mit diesem Iterationsschritt wird klar, dass der benutzte Algorithmus nicht alle

Primzahlen liefert, da die Primzahl 5 fehlt.

 

Im folgenden soll eine Programmierlösung für eine größere Anzahl von Primzahlen

erfolgen. Zunächst soll nur der konstruktive Aspekt berücksichtigt werden.

 

Erster Schritt: Die Anzahl der Iterationsschritte und der Startwert für die Laufvariable

werden festgelegt.

 

Ende:=10:

n:=1:

 

Zweiter Schritt: Die Daten sollen in einen Vektor der Dimension Ende geschrieben

werden.

Die erste Komponente wird mit 2 als erster Primzahl vorinitialisiert.

Möchte man den Algorithmus mit einer anderen Zahl beginnen, ist die zwei

entsprechend zu ersetzen.

Die anderen Elemente der Matrix werden automatisch mit 0 initialisiert und später

überschrieben.    

Durch den Doppelpunkt wird die Ausgabe unterdrückt.

 

Primzahlmatrix:=matrix(Ende,1,[2]):

 

Die Variable Primzahlprodukt ist eine Hilfsvariable, da die Produkte im Algorithmus

benötigt werden. Diese Variable wird mit dem Startprimzahl für den Algorithmus

vorinitialisiert.

 

Primzahlprodukt:=Primzahlmatrix[1]:

 

Nun werden die Primzahlen berechnet und in die Primzahlmatrix geschrieben.

 

while n < Ende do

   Primzahlmatrix[n+1]

      :=min(numlib::primedivisors(Primzahlprodukt+1));

   Primzahlprodukt

      :=Primzahlprodukt*Primzahlmatrix[n+1];

   n:=n+1;

end_while:

 

Die Primzahlmatrix wird ausgegeben.

 

Primzahlmatrix

math

 

Offensichtlich stimmen die ersten drei ausgegebenen Elemente der Matrix mit den oben

bestimmten Primzahlen überein. Die weiteren Elemente lassen sich sowohl durch

manuelle Berechnungen, als auch wie oben beschrieben mit MuPAD berechnen. 

Man stellt durch Ablesen fest:

1) Die Zahlen sind  paarweise voneinander verschieden.

2) Es werden nicht alle Primzahlen erfasst. Hier fehlt beispielsweise die Primzahl 11.

3) Wider Erwarten ist die Folge der Primzahlen nicht monoton steigend.

Die ersten sieben Ergebnisse der Iteration sind offensichtlich Primzahlen. Bei größeren

Zahlen ist jedoch nicht ohne weiteres erkennbar, dass es sich eine um eine Primzahl

ergeben hat.

 

Für den Nachweis, dass die berechneten Zahlen tatsächlich Primzahlen sind, werden

die Elemente der Primzahlmatrix ausgelesen und einzeln entsprechend dem weiter oben

angegebenem Algorithmus mit dem ersten Element der Primzahlzerlegung verglichen.

Die Ergebnisse der jeweiligen Proben werden in eine als Testmatrix bezeichnete Matrix

eingelesen. Die Elemente der Matrix sind mit 0 vorinitialisiert und werden dann bei

jedem Iterationsschritt überschrieben.

 

Die hier durchgeführte Entkopplung der Iterationen hat den Vorteil, dass die Algorithmen

unabhängig voneinander entwickelt und getestet werden können. Gemeinsame Daten

aller Iterationen sind die Variable Ende, die die Anzahl der Iterationen bestimmt,

die Primzahlmatrix und die Testmatrix.

 

Testmatrix:=matrix(Ende,1):

delete(m):

 

An dieser Stelle sollte zunächst die Iteration bei 1 begonnen werden. Fehlermeldungen

von MuPAD erzwangen die Besetzung der ersten Komponente der Testmatrix außerhalb

der Schleife und die Benutzung der Variablen Zwischenspeicher.

Zwischenspeicher:=

    testeq(numlib::primedivisors(Primzahlmatrix[1])[1]

                                 =Primzahlmatrix[1]):

Testmatrix[1]:=Zwischenspeicher:

for m from 2 to Ende  do

   Testmatrix[m]:=testeq(numlib::primedivisors

                (Primzahlmatrix[m])[1]=Primzahlmatrix[m]);

     

end_for:

 

 

Testmatrix

math

An dieser Stelle sind bis auf die angegebene Lücke bei der Überprüfung auf Ungleichheit

der Primzahlen die mathematischen Inhalte im Rahmen des Algorithmus abgearbeitet.

Allerdings ist die Ausgabe der Testmatrix ohne gemeinsame Darstellung mit der zuge-

hörigen Primzahl nicht optimal. Angebrachter erscheint es, die Primzahlen mit den

Ergebnissen der Überprüfung, ob es sich um Primzahlen handelt, gemeinsam darzustellen.

Um Doppelausgaben der Ergebnisse zu vermeiden, kann es sinnvoll sein, die uner-

wünschten Ausgaben durch einen Doppelpunkt hinter dem jeweiligen Befehl zu

unterdrücken.

 

Die gemeinsame Darstellung in einer einheitlichen Matrix mit geeigneter Dokumentation wird

im folgenden durchgeführt. Dabei wird in einem ersten Schritt das Ergebnis der Testmatrix

in eine besser lesbare Aussage "ist Primzahl" beim Ergebnis TRUE bzw. "ist keine Primzahl"

beim Ergebnis FALSE übersetzt.

 

Der folgende Teil der Notebooks benutzt anspruchsvollere Funktionen von MuPAD als in

den vorherigen Teilen, dient aber andererseits zur Verbesserung der Dokumentation und kann

bei einer ersten Durchsicht übersprungen werden.   

 

Zunächst wird der Startwert der Laufvariablen zurückgesetzt. Dann wird die Ausgabematrix

definiert. Alle Elemente dieser Matrix sind mit 0 vorinitialisiert und werden dann in der 

Durchführung der Iteration mit den Werten aus den oben angegebenen Matrizen über

schrieben.Es werden zwei Ausgabevarianten dargestellt: Erst wird die Funktion print benutzt

und anschließend wird die Ausgabematrix ausgegeben. Auch hier lassen sich unerwünschte

Ausgaben durch Doppelpunkte hinter den Befehlen unterdrücken.

 

delete k:

Ausgabe:= matrix(Ende, 2):

for k from 1 to Ende do

  if Testmatrix[k] = TRUE

    then

      print(Typeset,

       "Primzahl Nr. ".expr2text(k).": ".Primzahlmatrix[k]);

      Ausgabe[k,1]:= "Primzahl Nr. ".expr2text(k);

      Ausgabe[k,2]:= Primzahlmatrix[k];

    else

      print(Typeset,

       "keine Primzahl: ".expr2text(Primzahlmatrix[k]));

      Ausgabe[k,1]:= "keine Primzahl: ";

      Ausgabe[k,2]:= Primzahlmatrix[k];

  end_if;

end_for:

math

math

math

math

math

math

math

math

math

math

Ausgabe

math

Eine Auswahl möglicher Anschlussaufgaben:

 

1)   Ein noch offener Punkt in der Programmierlösung ist der Nachweis, dass die gefundenen

      Primzahlen paarweise voneinander verschieden sind. Die Programmierlösung kann um

      diesen Nachweis ergänzt werden.

 

2)   Es ist unter Umständen lästig, dass der Nachweis, dass die gefundenen Zahlen Primzahlen

      sind, für jede Zahl einzeln ausgegeben wird. Es ist möglich, die Ergebnisse der Nachweise

      zu einer einzigen Aussage zusammenzufassen.

 

3)   Bei der Benutzung des Algorithmus wurden die beginnend mit 2 die gefundenen Primzahlen

      im jeweils nächsten Iterationsschritt benutzt.  Es ist möglich, mit anderen Startwerten als 2

      zu beginnen und den Algorithmus in der beschriebenen Form durchführen.

      Es ist aber auch möglich, sich von der beschriebenen Iteration zu lösen und

      mit willkürlich gewählten Produkten von Primzahlen zu experimentieren.

 

4)   Eine interessante Aufgabe ist es, große Primzahlen bzw. Primzahlen mit bestimmten

      Eigenschaften zu finden.

      Man kann daher die Programmierlösung so ergänzen, dass der Algorithmus Primzahlen

      findet, deren Ziffernzahl eine vorgegebene Anzahl von Ziffern überschreitet bzw. mit

      dieser Ziffernzahl übereinstimmt. Alternativ ist es auch möglich, sich nur die Anzahl der

      Ziffern mit der gewünschten Eigenschaft ausgeben zu lassen.  

 

5)   Es kann überprüft werden, welche Auswirkungen auftreten, wenn man im Algorithmus

      Zahlen benutzt, die keine Primzahlen sind. Diese Überprüfung ist problemlos außerhalb

      der Programmierlösung möglich. Andererseits kann man auch den Startwert der

      Programmierlösung so wählen, dass er keine Primzahl ist. In diesem Fall sollte erklärt,

      werden, warum alle weiteren Zahlen doch Primzahlen sind.

 

6)   Es kann einen Check eingebaut werden, der bewirkt, dass der Algorithmus nur mit

      Primzahlen als Startwert durchlaufen wird.

 

7)   Man kann die Programmierlösung in Form einer Prozedur realisieren.

 

8)   In der vorliegenden Lösung wird die Primzahlnummer fehlerhaft ausgegeben, wenn man

      den Algorithmus mit einer Zahl beginnt, die keine Primzahl ist. Der Fehler tritt nicht auf,

      wenn der Startwert eine Primzahl ist. Dies teilkorrekte Verhalten sollte verifiziert,

      begründet und korrigiert werden.

 

9)   Es ist möglich, die vorliegende Lösung zu verkürzen und optimieren, indem man die aus

     didaktischen Gründen getrennt dargestellten Programmierlösungen zu einer

      kompakten Lösung zusammenfasst.

 

10) Schließlich kann man den Algorithmus auf den Befehl "numlib::divisors[2] umstellen.

 

______________________________________________________________________________

 

Anmerkung:

 

1. Darstellungen des gewählten Algorithmus finden sich in vielen Büchern zur Zahlentheorie. Das vorliegende

    Notebook bezieht sich auf die Darstellung in Remmert, Ulrich: "Elementare Zahlentheorie", 2. Auflage

    Birkhäuser 1995. 

 

2. Lösungen von Programmierproblemen im Rahmen der linearen Algebra und Analysis finden sich in weiteren

    Notebooks des gleichen Autors.

 

3. Weitere Aspekte der Anwendung von MuPAD auf die Zahlentheorie finden sich in zwei Notebooks des

    gleichen Autors, die sich mit vollkommenen Zahlen beschäftigen.

 

4.  Weitere Anregungen finden Sie in der Unterrichsmaterialsammlung unter schule.mupad.de. In diesen

     Notebooks werden eine Vielzahl unterschiedlichster mathematischer Probleme mit MuPAD Pro gelöst.

______________________________________________________________________________

 

 

 

MuPAD Education Group: Kostenlose Materialen für MuPAD Pro:
www.sciface.com/education, schule.mupad.de, studium.mupad.de, mupad.zum.de.