Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » Collatz Schleife » Antwort erstellen » Hallo Gast [Anmelden|Registrieren]

Antwort erstellen
Benutzername: (du bist nicht eingeloggt!)
Thema:
Nachricht:

HTML ist nicht erlaubt
BBCode ist erlaubt
Smilies sind erlaubt
Bilder sind erlaubt

Smilies: 21 von 33
smileWinkDaumen hoch
verwirrtAugenzwinkerngeschockt
Mit ZungeGottunglücklich
Forum Kloppebösegroßes Grinsen
TanzentraurigProst
TeufelSpamWillkommen
LehrerLOL HammerZunge raus
Hilfe 
aktuellen Tag schließen
alle Tags schließen
fettgedruckter Textkursiver Textunterstrichener Text zentrierter Text Hyperlink einfügenE-Mail-Adresse einfügenBild einfügen Zitat einfügenListe erstellen CODE einfügenPHP CODE farbig hervorheben
Spamschutz:
Text aus Bild eingeben
Spamschutz

Die letzten 10 Beiträge
blindmessenger

Zitat:
Original von eulerscheZahl
Excel ist die falsche Wahl: die Zahlen werden ziemlich schnell ziemlich groß - dafür hat Excel nicht die nötige Genauigkeit in der Zahlendarstellung.


Und der Code (C#)
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace Infoboard
{
	class MainClass
	{
		static List<BigInteger> Collatz(int start, int factor) {
			//zum nachgucken, ob schon gefunden - HashSet ist da schneller
			HashSet<BigInteger> found = new HashSet<BigInteger> ();
			//exakte Reihenfolge des Auftretens
			List<BigInteger> sequence = new List<BigInteger> ();
			BigInteger next = new BigInteger (start);
			while (!found.Contains(next)) {
				found.Add (next);
				sequence.Add (next);
				if (next.IsEven)
					next /= 2;
				else
					next = factor * next + 1;
				if (sequence.Count > 10000)
				return new List<BigInteger> { sequence.Max() };
			}
			sequence.Add (next);
			return sequence;
		}

		static void Main(string[] args) {
			for (int i = 1; i < 50; i++) {
				Console.WriteLine (string.Join (" ", Collatz (i, 5)));
			}
		}
	}
}


Im Prinzip bräuchten wir diesen Code mit folgender Veränderung:

1. Es sollen nur die ungeraden Zahlen ausgegeben werden.

2. Als Startzahlen nur die Zahlen der Form 4k+1

3. Jede Folge stoppt, wenn das "zweite mal" ein Element kleiner ist als sein Vorgänger.

Es sollte sich ein schönes regelmäßiges Treppenmuster ergeben, wo man erkennen kann, dass man Folgen mit mehr als 2 Elementen streichen kann.

Im Bild nochmal zu sehen wie Folgen mit mehr als 2 Elementen gestrichen werden sollen.

blindmessenger hat dieses Bild (verkleinerte Version) angehängt:
4k+1_Streichmuster.jpg

blindmessenger

Ich habe mir ein Streichalgorithmus überlegt, den ich aber nicht beweisen kann der aber bisher für kleinere Zahlen bis 1024"empirisch" funktioniert.

Es geht darum Collatzreihen auf andere Collatzreihen zurückzuführen, genauer gesagt gemeinsame Elemente zu finden. Sobald also zwei Reihen ein gemeinsames Element besitzen, dann haben sie auch dasselbe Ende, und man bracht nicht mehr beide Reihen zu testen sondern nur noch eine von beiden.

Als aller erstes streichen wir mal alle geraden Zahlen, weil wir ja wissen, dass diese immer nach endlichen Schritten bei einer ungeraden Zahl landen.

Nun teilen wir die verbleibenden ungeraden Zahlen in zwei Restklassen ein. Einmal in die Restklasse 4k+1 und einmal in die Restklasse 4k+3.

Mit dem Bild 4k+3 möchte ich zeigen, dass die Reihen der StartZahlen der Form 4k+3 immer auch in Reihen der Startzahlen der Form 4k+1 landen. Folgende Schritte werden hier angewendet:

1. Zahlen der Form 4k+3 werden einer Spalte aufgelistet und nach rechts gemäß des Collatzalgorithmus (nur mit ungeraden Zahlen) aufgereiht, bis ein Zahl entsteht die kleiner ist als ihre VorgängerZahl.

2. Es entstehen somit Verschieden lange Reihen. Jede zweite Reihe hat genau 3 Elemente. Nun ist die Idee, dass man die Folgen die mehr als drei Elemente besitzen streichen kann, weil sie immer auch in Folgen mit genau drei Elementen landen.

3. Nachdem wir diese längeren Folgen gestrichen haben, bleiben also nur Folgen mit genau drei Elementen. Nun wird die komplette erste Spalte gestrichen. Also immer das erste Element jeder Folge.

Nun ist zu sehen, dass die ersten Elemente dieser verbleibenden Folgen alle von der Form 8k+1 sind. Da [latex]8k+1 \subset 4k+1[/latex] lassen sich somit alle Zahlen der Form 4k+3 auf die Zahlen der Form 4k+1 zurückführen.



Also können wir 4k+3 auch abhacken und uns auf 4k+1 konzentrieren. Mit Bild 4k+1 will ich nun zeigen, dass durch mehrmaliges Wiederholen eines Streichzykluses Folgen auf immer größere Restklassen zurückgeführt werden.

Vorbereitung:

Zahlen der Form 4k+1 werden in einer Spalte aufgelistet und nach rechts gemäß des Collatzalgorithmus (nur mit ungeraden Zahlen) aufgereiht, bis ein Zahl entsteht die kleiner ist als ihre VorgängerZahl.
In diesem Fall (Und wohl in keinem anderen...) brechen alle Folgen beim zweiten Element ab. Interessanterweise: Wenn man diese zweiten Elemente auflisten würde, ergibt sich die OEIS Folge A067745.
Nun wird in 3 Schritten vorgegangen:

1. Schritt: Folgen neu aufbauen

Wir streichen das erste Element (somit die komplette erste Spalte) dieser 2er Folgen und lassen wieder nach dem Collatzalgorithmus neu entwickeln bis eine Zahl erreicht ist die kleiner als ihr Vorgänger ist.


2. Schritt: Gleiche Folgen streichen

Im zweiten Schritt werden aus den gerade neu aufgebauten Folgen, Folgen heraus gestrichen die mehrfach vorkommen. In diesem Fall ergibt sich, dass jede 4. Folge gestrichen werden kann.


3. Schritt: Folgen mit mehr als 2 Elementen streichen

Der dritte Schritt besteht darin, Folgen zu streichen die mehr als 2 Elemente beinhalten. Die Idee dahinter: Man kann empirisch für ein endliches Intervall nachweisen, dass alle Folgen mit mehr als 2 Elementen in Folgen mit genau 2 Elementen übergehen.


Nun ist ein Zyklus abgeschlossen. Nach mehrmaligen Wiederholen dieses Zykluses lassen sich so für beliebig große Restklassen zeigen, dass sie gemeinsame Elemente haben.

Mit diesem Siebalgorithmus ist natürlich noch keine Aussage darüber zu treffen ob alle Zahlen immer bei der 1 landen, aber es ist schon interessant, dass man im Grenzwert beliebig viel Folgen auf immer größere (im Grenzwert unendlich große) Restklassen zurückführen kann.

Das Problem an der ganzen Sache ist, dass ich mir nicht sicher bin, ob es zulässig ist immer Folgen zu streichen die mehr als zwei Elemente haben. Ich habe das nur empirisch für wenige Zahlen mit Excel überprüft.

Hat jemand eine Idee wie man den Streichalgorithmus programmieren kann, der dann aber auch gleichzeitig überprüft, ob und wie man Folgen mit mehr als zwei Elementen auch immer streichen kann?

Die Challenge wäre also ein Beweis, dass das Sieb auch immer zulässig ist...

blindmessenger hat diese Bilder (verkleinerte Versionen) angehängt:
4k+3.jpg 4k+1.jpg

blindmessenger

Ich gebe Dir recht... Ich muss mich da mal ein bisschen reinarbeiten...
eulerscheZahl

Wäre es nicht einfacher, selbst die Grundlagen des Programmierens zu lernen?

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
using System;
using System.Linq;
using System.Collections.Generic;

class Player
{
	static void Main(string[] args)
	{
		Console.Write ("Startwert: ");
		long n = long.Parse (Console.ReadLine ());
		Console.Write ("maximale Schritte: ");
		int steps = int.Parse (Console.ReadLine ());

		HashSet<long> numbers = new HashSet<long>();
		for (int i = 0; i < steps && !numbers.Contains(n); i++) {
			numbers.Add (n);
			if ((2 * n - 1) % 3 == 0)
				n = (2 * n - 1) / 3;
			else if ((4 * n - 1) % 3 == 0)
				n = (4 * n - 1) / 3;
			else
				n = 4 * n + 1;
			Console.Write (n + " ");
		}
		Console.WriteLine ();
	}
}
blindmessenger

Hallo,
um die Mengen, Gruppen und Klassen noch ein wenig weiter durchsuchen zu können suche ich ein einfaches Programm folgender Struktur für c-sharp

1. Ich starte mit einer beliebigen positiven ganzen Zahl n.

2. Nun werden nacheinander die 3 Operationen [latex] \frac {2n-1}{3} [/latex] , [latex] \frac {4n-1}{3} [/latex] und [latex] 4n+1 [/latex] durchprobiert bis die erste Operation gefunden ist die auf eine neue ganze Zahl führt.

3. Nun wird mit dieser neuen gefunden Zahl wieder wie in Schritt 2 verfahren.


In der Konsole sollen dann diese ganzen Zahlen aufgelistet werden.
Parameter des Algorithmus sind dann die Startzahl n und wie oft Schritt 2 wiederholt wird...
blindmessenger

Ich habe mit gnuplot etwas probiert:

blindmessenger hat dieses Bild (verkleinerte Version) angehängt:
Collatzkurve.jpg

eulerscheZahl

Bei mir klappt das nicht, weil Mono eine NotImplemented Exception wirft. Da du unter Windows arbeitest, könnte es aber klappen.
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

class Collatz
{
	static int Steps(long n) {
		int result = 0;
		while (n > 1) {
			if (n % 2 == 0)
				n /= 2;
			else {
				n = 3 * n + 1;
				result++;
			}
		}
		return result;
	}

	static void Main() {
		List<int> zerfall = new List<int> ();
		for (int i = 1; i < 1024; i += 2) {
			int tmp = Steps (i);
			while (zerfall.Count <= tmp)
				zerfall.Add (0);
			zerfall [tmp]++;
		}
		Chart chart = new Chart ();
		Series series = new Series ();
		for (int i = 0; i < zerfall.Count; i++) {
			Console.WriteLine (i + ": " + zerfall [i]);
			series.Points.AddXY (i, zerfall [i]);
		}
		chart.Series.Add (series);
		Form form = new Form ();
		chart.Dock = DockStyle.Fill;
		chart.Parent = form;
		form.Width = zerfall.Count;
		form.Height = zerfall.Max ();
		form.ShowDialog ();
	}
}
blindmessenger

Kann sein das ich mich verzählt habe...

Eine Idee wie man das schön plotten kann ausser mit excel?
eulerscheZahl

Deine Werte für 12 und 15 sind falsch (oder mein Programm, das ich eben zusammengetippt habe).
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
using System;
using System.Linq;
using System.Collections.Generic;

class Collatz
{
	static int Steps(long n) {
		int result = 0;
		while (n > 1) {
			if (n % 2 == 0)
				n /= 2;
			else {
				n = 3 * n + 1;
				result++;
			}
		}
		return result;
	}

	static void Main() {
		List<int> zerfall = new List<int> ();
		for (int i = 3; i < 1024; i += 2) {
			int tmp = Steps (i);
			while (zerfall.Count <= tmp)
				zerfall.Add (0);
			zerfall [tmp]++;
		}
		for (int i = 1; i < zerfall.Count; i++) {
			Console.WriteLine (i + ": " + zerfall [i]);
		}
	}
}
blindmessenger

Hallo Euler,
danke für Deine Mühen... Gott

Ich habe Deinen letzten Code gerechnet und habe bisher keine weiteren Nicht-Mersenne-Algorithmen gefunden ausser der 5n+1 und 181n+1...

Aber ich habe noch eine andere interessante Beobachtung gemacht...

[latex]T_k[/latex] sei eine ungerade Zahl die in [latex] k[/latex] 3n+1-Operationen bei der 1 landet. [latex]M_{T_k}[/latex] sei die Menge der Zahlen einer ZerfallsKlasse [latex]k[/latex]. Es ergibt sich folgendes Bild:

[latex]M_{T_1}=[5,21,85,341,...][/latex]

-----------

[latex]M_{T_{2_1}}=[3,13,53,213,...][/latex]

[latex]M_{T_{2_2}}=[113,453,1813,7253,...][/latex]

[latex]M_{T_{2_3}}=[227,909,3637,14549,...][/latex]

...

[latex]M_{T_{2_n}}[/latex]

-----------

[latex]M_{T_{3_{1_1}}}=[17,69,277,1109,...][/latex] [latex]M_{T_{3_{2_1}}}=[75,301,...][/latex][latex]M_{T_{1_{3_1}}}=[151,...][/latex]



[latex]M_{T_{3_{1_2}}}=[35,141,565,...][/latex] [latex]M_{T_{3_{2_2}}}=[2417,...][/latex][latex]M_{T_{3_{3_2}}}=[4849,...][/latex]



[latex]M_{T_{3_{1_3}}}=[1137,4549,18197,...][/latex] [latex]M_{T_{3_{2_3}}}=[4835,...][/latex] [latex]M_{T_{3_{3_3}}}=[9699,...][/latex]

...

[latex]M_{T_{3_{1_n}}}[/latex] [latex]M_{T_{3_{2_n}}}[/latex] [latex]M_{T_{3_{3_n}}}[/latex]

----------

[latex]M_{T_{k_{n_{n_{..._n}}}}}[/latex]

Folgende Arithmetik ergibt sich:

Aus 2 von 3 ungeraden Zahlen [latex]T_k[/latex] ergibt sich eine TeilMenge [latex]M_{T_{k+1}}[/latex] der nächstgrösseren Klasse. So bilden sich dann auch Gruppen etc....

Nun habe ich in einem bestimmten Intervall [latex] [1,1024] [/latex] die Anzahl [latex] x [/latex] der ungeraden Zahlen die in gleichviel Schritten zur 1 gelangen gezählt. Und es ergibt sich (wohl unabhängig von n...) folgendes Bild:

[latex]<br />
\tabular{|c|c|}<br />
\multicolumn {2}{|c|}{Anzahl x von ungeraden Zahlen derselben Zerfallsklasse k im Intervall 1-1024 } \\ \hline<br />
Zerfallsklasse k & x\\ \hline<br />
1&  4\\ \hline<br />
2& 9\\ \hline<br />
3& 10 \\ \hline<br />
4& 15 \\ \hline<br />
5& 17\\ \hline<br />
6& 18 \\ \hline<br />
7& 25\\ \hline<br />
8& 20\\ \hline<br />
9&  21\\ \hline<br />
10& 21\\ \hline<br />
11& 15\\ \hline<br />
12& 20\\ \hline<br />
13& 15\\ \hline<br />
14& 19 \\ \hline<br />
15& 18\\ \hline<br />
16& 10\\ \hline<br />
\endtabular<br />
[/latex]

Ich habe das für verschiedene Intervalle durchgezählt und es ergibt sich, dass immer bei der 7 ein Peak ist. Die Kurve die sich ergibt scheint ein schwach gedämpfter harmonischer Oszillator zu sein.

Um das genauer zu überprüfen, bräuchte man einen Code der diese Tabelle logisch fortführt für größere Intervalle und auch für größere k. Bei kleineren Intervallen ist dieser Oszillator nicht gut zu erkennen, aber je größer das Intervall desto besser sollte sich ein Oszillator herauskristallisieren...
Es sind weitere Beiträge zu diesem Thema vorhanden. Klicken Sie hier, um sich alle Beiträge anzusehen.