Denksport: Radialer Bestplatz-Algorithmus

Mik3e hat gesagt.:
Das klingt hier ja wie bei der Einwanderungsbehörde (Mutter, Vater, kinder, zeugung.. :)
Vor allem den Codekommentar finde ich gut:

//die bessere Hälfte bleibt erhalten und zeugt Kinder
lol..

...

Leider versteh ich von dem genetischen Code im Moment überhaupt nichts :(

Ciao,
Mike
Genau so kannst Du Dir einen genetischen Algorithmus vorstellen.
Es gibt eine Population. Im Sinne von "Survival of the Fittest" mischen die besten ihren genetischen Code und erzeugen Nachkommen daraus. Damit entsteht eine neue Population, die selbst wieder Nachkommen erzeugt, usw.
Die Population besteht aus Individuen.
Jedes Individuum enthält einen genetischen Code (eine Gruppe von Plätzen) und eine Fitness (Bewertung der Gruppe von Plätzen).
Nun sucht man sich nach bestimmten Kriterien zwei Individuen aus und mischt ihren genetischen Code. Man nimmt also ein Paar Plätze aus dem einen Individuum und ein Paar aus dem anderen. Daraus entsteht ein neues Individuum, welches in die Population der nächsten Generation übernommen wird.

Gruß hpvw
 
Mik3e hat gesagt.:
Ist ein Wert mit 4 Werten.. aber was gibt der vierte an
Den vierten Wert verwende ich für den Abstand der Plätze-Gruppe zum idealen Platz. Damit die Entfernung der Gruppe zum idealen Platz weniger stark gewichtet wird, als die Entfernung der Plätze in der Gruppe untereinander, aber zwei gleichwertige Gruppen, mit unterschiedlicher Entfernung zum idealen Platz geordnet werden können.
Dazu wird der Mittelpunkt der Gruppe gebildet, von diesem die Entfernung zum idealen Platz und das Ergebnis dann mit dem Faktor (4.Wert im Array) multipliziert.

Wie gesagt, ist die Bewertung einer Platzgruppe ein Punkt, an dem sicherlich noch verbessert werden kann.

Gruß hpvw
 
Wie gesagt scheitere ich schon bei den Distanzparametern..
Ich vermute $di ist die Bewertung der Distanz zwischen zwei Objekten...
d.h:
Horizontal = 1.0
Vertikal = 1.3
Diagonal = 1.5
? = 0.1 <= Welche Anordnung stellt dieser Wert dar?

Und jenes Individum, die in Summe die geringste Distanz hat, ist das Beste...

Habe ich diese erste Überlegung mal richtig verstanden
 
Ich würde den genetischen Algorithmus mal gerne so weit durchblicken, dass ich es selbst schaffe, die Priorisierung zu ändern (d.h. OBEN geht vor LINKS). In beigefügtem Beispiel für 2 gewählte Plätze würde das heißen, dass er mir die Plätze 2-0 und 3-0 zurückliefert, und nicht wie derzeit die Plätze 0-1 und 1-1...
 

Anhänge

  • platzmatrix.gif
    platzmatrix.gif
    8,3 KB · Aufrufe: 73
Es wird zur Zeit nur die Distanz, egal in welche Richtung, vom idealen Platz ermittelt.
Eine leichte Priorisierung entsteht durch den ersten und den zweiten Faktor. Womit dieselbe Reihe bereits leicht bevorzugt wird.
Da die Bedingungen zunehmend binär, bzw. unstetig werden, muss wohl eine neue Funktion zur Bewertung her, die mehr mit Bedingungen, als mit Rechnungen arbeitet.
Ich schau mal, ob mir noch was einfällt.

Gruß hpvw
 
Hilfe.. mir wird das langsam zu komplex :)
Es muss doch auch eine simplere und einfachere Lösung geben.
Hast Du Dir den Ansatz von Datic schon angesehen Das funktioniert eigentlich perfekt.

Den variablen Startpunkt kannst Du ruhig außen vor lassen (ist nicht wichtig im Moment)... Damit wird die Sache sicher wesentlich simpler...
 
Ich hab keine interesse das zu machen, keine Lust zurzeit.
Vielleicht werde ich das mal in ein paar Wochen, wenn ich Lust habe auch machen.

Aber ich hätte noch eine Idee:
Das von der 2d Ebene auf 3d zu übertragen: $places[0][0][0] ;)
Also der erste index bestimmt dann das Stockwerk oder so. Bei nem Doppeldecker-Bus zum Beispiel^^
Noch eine Aufgabe: Das alles so so Flexibel sein, dass man angeben kann, wie viele Reihen, Stockwerke und Sitze es gibt.
Also Sitze = Sitze pro Reihe
Reihen = Reihe pro Stockwerk.

Man gibt also sozusagen alles an ;)

Das könnte man als contest-Thema nehmen :D

edit: oder vierdimensional. Dann gibt man noch an, dass das selbe nocheinmal daneben gestellt wird. ^^
 
Zuletzt bearbeitet:
Mik3e hat gesagt.:
Hilfe.. mir wird das langsam zu komplex :)
Das ist auch kein triviales Problem.

Mik3e hat gesagt.:
Es muss doch auch eine simplere und einfachere Lösung geben.
Möglich, aber mir fällt als einfache Lösung nur die eigenständige Wahl durch den Anwender ein.

Mik3e hat gesagt.:
Hast Du Dir den Ansatz von Datic schon angesehen Das funktioniert eigentlich perfekt.
Den Code habe ich mir angesehen. Im unglücklichsten Fall führt das (zumindest fast) zur vollstängiden Enumeration. Bist Du Dir sicher, dass er in einer Endlosschleife steckt oder kann es sein, dass er nur sehr lange braucht? Oder war das jetzt Blödsinn und ich habe die Lösung überlesen?

Mik3e hat gesagt.:
Den variablen Startpunkt kannst Du ruhig außen vor lassen (ist nicht wichtig im Moment)... Damit wird die Sache sicher wesentlich simpler...
Bei Datics Code macht das sicher einen Unterschied, da die dreifach verschachtelte Schleife etwas anders aussehen müßte, bei den Bewertungsfunktionen des genetischen Algorithmus ist das relativ egal.

@Irgendjemand_1:
Das ganze in 2d mit vernünftigen Ergebnissen und akzeptablem Laufzeitverhalten hinzukriegen ist schon Arbeit genug. Wenn das jedoch anständig läuft, dürfte es ein geringfügiges Problem sein, das auf eine weitere Dimension zu portieren.

Das war jetzt bis Sonntag erstmal mein letzter Post, jetzt geht es ins Wochenende.
Ich wünsche Euch noch viel Spaß und vor allem Erfolg.

Gruß hpvw
 
Mik3e hat gesagt.:
@hpvw:
Ich gehe das Problem nun anders (simpler) an...
Ich versuche immr nebeneinanderliegende Plätze zu finden....

Angenommen der User möchte 8 Plätze->
1. System prüft, ob in einer Reihe noch 8 Plätze nebeneinander vorhanden sind.
Wenn nicht wird die Anzahl halbiert
8 -> 4 / 4

2. System prüft, ob 4 Plätze in einer Reihe nebeneinander vorhanden sind. Wenn nicht, werden wieder beide Zahlenwerte halbiert usw...
Das geht dann hinuter bis auf 1...

Also
Suche 8
Suche 4 | 4
Suche 2 | 2 | 2 | 2
Suche 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1

Von der Lösung her ist das absolut ok..
Nur mit der Performance muss ich mir noch etwas überlegen (im schlechtesten Fall muss er bei 8 gesuchten Plätzen den array 14x durchlaufen...).

Was hältst Du von der Logik?

LG
Mike
Die Idee ist ganz gut. Ich hätte evtl. einen Vorschlag, wie man das Beschleunigen und ggf. auch verbessern könnte (Bei 8: 8; 4/4; 5/3; 6/2; 4/2/2; 3/3/2; 2/2/2/2).

Wie wäre es, wenn Du das Array nur einmal durchläufst und jeweils in einer Zeile nebeneinanderliegende Plätze gruppierst. Dann hättest Du ein wesentlich kleineres Array, was Du so oft durchlaufen kannst, wie Du willst.

Die oben angesprochene andere Verteilung müßte man evtl. für gängige Gruppengrößen von Hand machen, aber ich versuche gleich mal eine Funktion zu schreiben.

Gruß hpvw
 
Warte - Stop - Halt :)

Ich hab mir den Code von Datic nochmal zu gemüte geführt..
Ich muss sagen, die Lösung ist überhaupt genial und schnell..

Habe es jetzt noch für PHP umgesetzt (abgesehen von den noch hässlichen global-Definitionen)...
Sieh es dir mal an.. Bei der Flood-Funktion hab ich noch nicht ganz den Durchblick:

PHP:
// In $places steht die gesamte Platzmatrix 
$places = array();
 
// Reihe 1
$places[0][0] = true; 
$places[0][1] = true; 
$places[0][2] = false; 
$places[0][3] = false; 
$places[0][4] = false; 

// Reihe 2
$places[1][0] = false; 
$places[1][1] = false; 
$places[1][2] = false; 
$places[1][3] = true; 
$places[1][4] = true; 

// Reihe 3
$places[2][0]= false; 
$places[2][1]= true; 
$places[2][2]= true; 
$places[2][3]= true; 
$places[2][4]= false; 

// Reihe 4
$places[3][0] = true;
$places[3][1] = true;
$places[3][2] = false;
$places[3][3] = false;
$places[3][4] = false;

function searchPlaces($amt) { 
    checkPlaces($amt); 
} 

// Gefundene Plätze löschen 
function clearResp() { 
    global $places, $response, $famt; 
    $response = array(); 
    for ($y=0; $y<count($places); $y++) { 
        $response[$y] = array(); 
        for ($x=0; $x<count($places[$y]); $x++) { 
            $response[$y][$x] = false; 
        } 
    } 
    $famt = 0; 
} 

// Gefundene Plätze zählen 
function countResp() { 
    global $places, $response; 
    $c = 0; 
    for ($y=0; $y<count($places); $y++) { 
        for ($x=0; $x<count($places[$y]); $x++) { 
            if ($response[$y][$x] == true) {
				$c++;
			} 
        } 
    } 
    return $c; 
} 

// Plätze suchen: 
function checkPlaces($amt) { 
    global $places, $response, $famt; 
	/********************************
	* $i = 3 Varianten:
	* - horizontal verbunden
	* - vertikal verbunden
	* - diagonal verbunden
	/********************************/
    for ($i=1; $i<=3; $i++) {
        for ($y=0; $y<count($places); $y++) { 
            for ($x=0; $x<count($places[0]); $x++) { 
                /*echo 'REIHE:'.$y.'<br>';
				echo 'PLATZ:'.$x.'<br>';*/
				clearResp(); 
                flood($i, $x, $y, $amt); 
                if (countResp() >= $amt) {
					return true;
				} 
            } 
        } 
    } 
} 

// Weitersuchen 
function flood($fmode, $x, $y, $amt) { 
    global $places, $response, $famt; 
    if ($famt >= $amt) {
		return true; 
	}
    if ($places[$y][$x] == true && $response[$y][$x] != true) { 
        $response[$y][$x] = true; 
        $famt ++; 
        switch($fmode) { 
            case 1: 
                flood($fmode, ($x-1), $y, $amt); 
                flood($fmode, ($x+1), $y, $amt); 
                break; 
            case 2: 
                flood($fmode, ($x-1), $y, $amt); 
                flood($fmode, ($x+1), $y, $amt); 
                flood($fmode, $x, ($y-1), $amt); 
                flood($fmode, $x, ($y+1), $amt); 
                break; 
            case 3: 
                flood($fmode, ($x-1), $y, $amt); 
                flood($fmode, ($x+1), $y, $amt); 
                flood($fmode, $x, ($y-1), $amt); 
                flood($fmode, $x, ($y+1), $amt); 
                flood($fmode, ($x-1), ($y-1), $amt); 
                flood($fmode, ($x+1), ($y-1), $amt); 
                flood($fmode, ($x-1), ($y+1), $amt); 
                flood($fmode, ($x+1), ($y+1), $amt); 
                break; 
        } 
    } 
    return; 
} 

// In $response werden die gefundenen Plätze geschrieben 
$response = Array(); 
$famt = 0; 
// Platzsuche für $amt=4 Plätze starten
searchPlaces(4);
print_r($response);

LG
mike

EDIT: War noch ein Fehler im Source-Code.. ist jetzt korrigiert...
 
Zuletzt bearbeitet:
Zurück