Erstellung matrix von zahlen, die einzigartig in Zeile und Spalte

Wenn dir ein besserer Titel nach der Lektüre die Frage, bitte fühlen Sie sich frei, es zu ändern.

So, als input habe ich eine ganze Zahl, die eine gerade Zahl zwischen 2 und 20. Nennen wir diese ganze Zahl $teams. Was ich tun müssen, ist erzeugen eine $teams x $teams große matrix von zahlen zwischen 1 und $teams-1 (inklusive) unter Beachtung der folgenden Regeln:

  1. Der diagonalen (von oben Links nach unten rechts) hat den Wert -1.
  2. Die gleiche Nummer erscheinen nicht in der gleichen Spalte oder Zeile mehr als einmal.
  3. Wenn eine Nummer angezeigt, die in Spalte N, im Mai dann nicht angezeigt, in der Zeile N. Zum Beispiel, wenn es erscheint in der Spalte #2, kann es nicht angezeigt wird in der Zeile #2, etc.

Beachten Sie, dass wir nur den Blick auf den Teil oberhalb der Diagonale. Der Teil darunter ist nur ein Spiegelbild der, dass (jede Zahl ist die Reflexion + $teams - 1), und es spielt keine Rolle für dieses problem.

Den ersten 2 Bedingungen waren relativ einfach zu bewerkstelligen, aber der 3. ist, mich zu töten. Ich weiß nicht, wie es geschehen zu lassen, vor allem, da die $teams Nummer könnte jede gerade Zahl zwischen 2 und 20. Der code, der eine korrekte Ausgabe für die Bedingungen 1 und 2 ist unten gegeben. Kann mir jemand helfen mit Bedingung Nummer 3?

$teams = 6;         //example value - should work for any even Int between 2 and 20
$games = array();   //2D array tracking which week teams will be playing

//do the work
for( $i=1; $i<=$teams; $i++ ) {
    $games[$i] = array();
    for( $j=1; $j<=$teams; $j++ ) {
        $games[$i][$j] = getWeek($i, $j, $teams);
    }
}

//show output
echo '<pre>';
$max=0;
foreach($games as $key => $row) {
    foreach($row as $k => $col) {
        printf('%4d', is_null($col) ? -2 : $col);
        if($col > $max){
            $max=$col;
        }
    }
    echo "\n";
}
printf("%d teams in %d weeks, %.2f weeks per team\n", $teams, $max, $max/$teams);
echo '</pre>';

function getWeek($home, $away, $num_teams) {
    if($home == $away){
        return -1;
    }
    $week = $home+$away-2;
    if($week >= $num_teams){
        $week = $week-$num_teams+1;
    }
    if($home>$away){
        $week += $num_teams-1;
    }

    return $week;
}

Den aktuellen code (für $teams=6) gibt die folgende Ausgabe:

  -1   1   2   3   4   5
   6  -1   3   4   5   1
   7   8  -1   5   1   2
   8   9  10  -1   2   3
   9  10   6   7  -1   4
  10   6   7   8   9  -1
6 teams in 10 weeks, 1.67 weeks per team

Wie Sie sehen, wird die Zahl 1 angezeigt, sowohl in der 2. Spalte und 2. Zeile, die Zahl 4 erscheint sowohl in der 5. Spalte und 5. Zeile usw, die Pausen-Regel #3.

  • Vielleicht gibt es einfachere Lösungen, aber man konnte einen Blick auf backtracking: en.wikipedia.org/wiki/Backtracking
  • Danke, aber ich würde eher zu entdecken einfacher, die möglichen Lösungen zuerst. Backtracking sieht aus wie es könnte auf jeden Fall lösen es, aber würde eine Menge Aufwand und scheint nicht sehr effizient in Bezug auf die Anzahl der Iterationen (wenn das nicht zu viel von einem Problem bei der geringen Anzahl von $teams).
  • Eine Sache, die mir eingefallen ist, als Sie sagte: "die Nummer wird in der n-TEN Spalte", und bezieht sich auf den nth collumn von der ersten Zeile. Nun, wissen Sie, dass in der ersten Zeile haben Sie die zahlen von -1 zu n-1. Beim generieren der zahlen für Zeile Nummer x können Sie einfach überspringen Sie die Zahl, die in $games[1][x]. Hoffe, das hilft etwas 😉
  • Werde ich versuchen, danke. Ich vermute, dass die Letzte Zeile eine falsche Eingabe obwohl, da gibt es keine Wahl an dieser Stelle.
  • aber die Letzte Zeile ist unter der diagonalen, und Sie sagte nur, die Einträge oben sind relevant oder habe ich etwas falsch gemacht? 😉
  • Ich meine die Zeile oberhalb der letzten, sorry - das einzige, wo Nummer 4 ist den ganzen Weg auf der rechten Seite in meinem Beispiel. Für die, die eine Zahl, es ist nicht eine Wahl, so wird es das sein, was übrig ist, nachdem die anderen gefüllt sind, so gibt es keine Möglichkeit zu wissen, ob es wird richtig sein (denke ich).
  • Ich würde sagen, versuchen, die richtige Lösung zu erreichen, die auf einem Stück Papier zuerst, um dann zu schauen, ob Sie extrahieren können einige Abhängigkeiten zwischen den zahlen in den Zeilen und Spalten, die würde führen Sie zu den richtigen Algorithmus.
  • Ist das nicht eine Variante des n-Damen-problem? en.wikipedia.org/wiki/Eight_queens_puzzle
  • Es ist ähnlich, aber ich würde nicht nennen es eine Variante, wie meine Dritte Bedingung, die Sie trennt - in der 8-Damen-problem, es ist notwendig für die Königinnen erscheinen in jeder Spalte und Zeile nur einmal, sondern per definition, dass auch Pausen-Regel #3 mein problem ist, wie zum Beispiel, es gibt eine Königin die beiden in Zeile 2 und Spalte B (sprechen in Schach AGB).

InformationsquelleAutor robert | 2013-04-11
Schreibe einen Kommentar