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

Informatiker Board » Themengebiete » Praktische Informatik » Vollständigesturnier: Lösungsalgorithmus bzw. mindestens eine Lösung für folgendes Problem gesucht » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen Vollständigesturnier: Lösungsalgorithmus bzw. mindestens eine Lösung für folgendes Problem gesucht
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
grohfuda
Grünschnabel


Dabei seit: 16.10.2017
Beiträge: 2

Vollständigesturnier: Lösungsalgorithmus bzw. mindestens eine Lösung für folgendes Problem gesucht Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Liebe Forumsteilnehmer, ich bin auf der Suche nach einem Lösungsalgorythmus oder wenigstens einer einzelnen Lösung für ein vollständiges Turnier. Auch wenn ich die Lösung eigentlich für etwas anderes brauche (Brettspielanalyse), möchte ich das Problem an einem anschaulichen Bespiel erläutern:


Nehmen wir einmal an 12 Hasen wollen über den Frühling bis Sommer ein vollständiges Wettlauf-Turnier mit Wellläufen gegeneinander bestreiten. Mangels Platz können immer nur 4 Hasen gleichzeitig rennen. Also wird im Laufe des Sommers jeder Hase mit allen Kombinationen von jeweils 3 anderen Hasen ein Rennen absolvieren:

H1, H2, H3, H4
H1, H2, H3, H5
H1, H2, H3, H6
[...]
H9, H10, H11, H12


Die Anzahl der möglichen Kombinationen beträgt 12! / (8! x 4!) = 495 (bzw. 135 pro Hase)

Nun sollen aber folgende Randbedingungen an das Turnier erfüllt sein:

1) Es sollen niemals die selben 4 Hasen ein zweites mal gegeneinander Laufen (2 bzw. 3 Hasen sind kein Problem), das heißtz.B. das Rennen H1, H2, H3, H4 darf es nur einmal geben.

2) Es werden jeden Tag genau 3 Rennen gestartet, wobei jeder Hase genau ein Rennen pro Tag absolviert. (Hierbei ist es egal in welchem der Tagesrennen jeder Hase jewils startet, auch die Bahnnummer ist nicht von Bedeutung.

Frage 1)
Wie kann hier eine Lösung aussehen? Ich vermute mal, dass das Ganze mit Backtracking lösbar ist (falls es eine Lösung gibt), leider reichen hier meine Programmierfähigkeiten nicht aus...

Randbemerkung: Für 8 Hasen und 2 Rennen ist die Lösung trivial. Man nehme ein beliebiges Hasenrennen und die übrigen Hasen laufen im zweiten. Dieser Ansatz hat mich aber hier nicht weitergebracht.


Frage 2)
Existiert eine solche Lösung auch für 16 Hasen und 4 Rennen mit 4 Hasen bzw. 15 Hasen und 3 Rennen mit 5 Hasen?


Viele Dank im Voraus.
grohfuda
16.10.2017 12:33 grohfuda ist offline Beiträge von grohfuda suchen Nehmen Sie grohfuda in Ihre Freundesliste auf
eulerscheZahl eulerscheZahl ist männlich
Foren Gott


Dabei seit: 04.01.2013
Beiträge: 2.859

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Letztendlich läuft das auf ein Independent Set Problem hinaus, wobei die Kanten unmögliche Paarungen sind, also solche mit doppelten Rennen.

Mein Programm schafft das und 8 Hasen und 2 Rennen in Sekundenbruchteilen, aber bei 12 und 3 habe ich es abgebrochen. Die Erkennung einer ungültigen Paarung kann man mit einer Lookup Table beschleunigen, aber ich glaube nicht, dass das reicht.
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:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
using System;
using System.Linq;
using System.Collections.Generic;

class Infoboard
{
	public static void Main (string[] args)
	{
		int bunnies = 12; //8
		int races = 3; //2
		int participants = bunnies / races;

		List<Race> raceList = Race.CreateRaces(participants, bunnies);
		List<Day> days = Day.CreateMatchdays (raceList, races);
		List<Tournament> tournaments = Tournament.CreateTournament (days, 495 / races); //495 = binom(12, 4)
	}

	class Race {
		public int[] Participants { get; private set; }

		public Race(int[] participants) {
			this.Participants = (int[]) participants.Clone();
		}

		public bool Collide(Race r) {
			foreach (int p in this.Participants) {
				foreach (int q in r.Participants) {
					if (p == q)
						return true;
				}
			}
			return false;
		}

		public static List<Race> CreateRaces(int participants, int bunnies) {
			List<Race> matches = new List<Race> ();
			CreateRaces (matches, new int[participants], 0, 0, bunnies);
			return matches;
		}

		private static void CreateRaces(List<Race> matches, int[] current, int index, int taken, int max) {
			if (taken == current.Length) {
				matches.Add (new Race (current));
				return;
			}
			if (index >= max)
				return;
			CreateRaces (matches, current, index + 1, taken, max);
			current [taken] = index;
			CreateRaces (matches, current, index + 1, taken + 1, max);
		}

		public override string ToString ()
		{
			return string.Join (" ", Participants.Select (p => p + 1));
		}
	}

	class Day {
		public Race[] Races { get; private set; }
		public Day(Race[] races) {
			this.Races = (Race[]) races.Clone();
		}

		public static List<Day> CreateMatchdays(List<Race> raceList, int racesPerDay) {
			List<Day> days = new List<Day>();
			CreateMatchdays (days, raceList, new Race[racesPerDay], 0, 0);
			return days;
		}

		private static void CreateMatchdays(List<Day> days, List<Race> matches, Race[] current, int index, int taken) {
			if (taken == current.Length) {
				days.Add (new Day (current));
				return;
			}
			if (index >= matches.Count)
				return;
			CreateMatchdays (days, matches, current, index + 1, taken);
			if (!current.Take (taken).Any (c => c.Collide (matches [index]))) {
				current [taken] = matches [index];
				CreateMatchdays (days, matches, current, index + 1, taken + 1);
			}
		}

		public bool Collide(Day d) {
			foreach (Race p in this.Races) {
				foreach (Race q in d.Races) {
					if (p == q)
						return true;
				}
			}
			return false;
		}

		public override string ToString ()
		{
			return string.Join<Race> ("     ", Races);
		}
	}

	class Tournament {
		public Day[] Days { get; private set; }
		public Tournament(Day[] days) {
			this.Days = (Day[]) days.Clone();
		}

		public static List<Tournament> CreateTournament(List<Day> dayList, int daysPerTournament) {
			List<Tournament> tournaments = new List<Tournament>();
			CreateTournament (tournaments, dayList, new Day[daysPerTournament], 0, 0);
			return tournaments;
		}

		private static void CreateTournament(List<Tournament> tournaments, List<Day> days, Day[] current, int index, int taken) {
			if (taken == current.Length) {
				tournaments.Add (new Tournament (current));

				Console.WriteLine (tournaments.Last () + "\n\n");
				return;
			}
			if (index >= days.Count)
				return;
			if (current.Length - taken > days.Count - index)
				return;
			CreateTournament (tournaments, days, current, index + 1, taken);
			if (!current.Take (taken).Any (c => c.Collide (days [index]))) {
				current [taken] = days [index];
				CreateTournament (tournaments, days, current, index + 1, taken + 1);
			}
		}

		public override string ToString ()
		{
			return string.Join<Day> (Environment.NewLine, Days);
		}
	}
}


__________________
Syntax Highlighting fürs Board (Link)
16.10.2017 18:01 eulerscheZahl ist offline Beiträge von eulerscheZahl suchen Nehmen Sie eulerscheZahl in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Verstehe ich es richtig, dass es eigentlich recht einfach ist, die 4er-Gruppen zu ermitteln, das Problem aber darin besteht, pro Tag 3 Rennen zu machen wobei ein Hase nie 2 mal an einem Tag rennen darf?

Gruß,

Karlito
16.10.2017 19:45 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
eulerscheZahl eulerscheZahl ist männlich
Foren Gott


Dabei seit: 04.01.2013
Beiträge: 2.859

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Ja, oder dass du an zwei Tagen das selbe Rennen aus 4 Hasen hast.
Die einzelnen Tage zu ermitteln geht noch recht flott, für die gegebenen Werte (12 Hasen, 3 Rennen) könne ich auf 5775 Möglichkeiten für einen einzelnen Tag.
Aber dann muss man davon 165 Tage auswählen, sodass kein Rennen doppelt ist. Wird wohl auf einen LP Solver hinauslaufen.

__________________
Syntax Highlighting fürs Board (Link)
16.10.2017 21:39 eulerscheZahl ist offline Beiträge von eulerscheZahl suchen Nehmen Sie eulerscheZahl in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Ich würde einen genetischen Algorithmus probieren. Damit schonmal rumgespielt? Wäre eine Premiere für mich. Kennst Du Gegenargumente?

Gruß,

Karlito
16.10.2017 22:02 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
eulerscheZahl eulerscheZahl ist männlich
Foren Gott


Dabei seit: 04.01.2013
Beiträge: 2.859

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Ein randomisierter Ansatz könnte klappen. Hängt davor ab, wie viele Lösungen es gibt. Die einzige zu finden wird schwer, da bist du mit Bruteforce evtl sogar besser beraten.
Meine Masterarbeit geht auch in die Richtung, aber nicht für Hasenrennen.

CodinGame ist eine gute Anlaufstelle, um damit herumzuspielen.
Hier sind soweit ich weiß alles randomisierte Algorithmen (Monte Carlo, genetische Algorithmen). Die finden ganz gute Züge.

__________________
Syntax Highlighting fürs Board (Link)
17.10.2017 17:26 eulerscheZahl ist offline Beiträge von eulerscheZahl suchen Nehmen Sie eulerscheZahl in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

OK. Wenn ich am WE Zeit finde, probiere ich mal einen Lösungsversuch mit einem evolutionären Algorithmus.

Gruß,

Karlito
17.10.2017 22:31 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
grohfuda
Grünschnabel


Dabei seit: 16.10.2017
Beiträge: 2

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Würde es helfen (bzw. das Programm beschleunigen), wenn man festlegt, das Hase 1 immer im ersten Rennen des Tages läuft?

Viele Grüße
grohfuda
22.10.2017 18:27 grohfuda ist offline Beiträge von grohfuda suchen Nehmen Sie grohfuda in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Nicht wirklich. Wenn man systematisch nach einer Lösung sucht, würde man eh damit beginnen.

Gruß,

Karlito
22.10.2017 23:19 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
Informatiker Board » Themengebiete » Praktische Informatik » Vollständigesturnier: Lösungsalgorithmus bzw. mindestens eine Lösung für folgendes Problem gesucht