2015-05-13 6 views
13

Es wurde eine Frage in einem Interview gestellt:So implementieren Sie die Lösung für Race Simulation Probleme

In einer Formel-1-Herausforderung gibt es n Teams von 1 bis n nummeriert. Jedes Team hat ein Auto und einen Fahrer. Auto-Spezifikation ist wie folgt:

  • Höchstgeschwindigkeit: (150 + 10 * i) km pro Stunde
  • Beschleunigung: (2 * i) Meter pro Sekunde Platz.
  • Handlingsfaktor (hf) = 0,8
  • Nitro: Erhöht die Geschwindigkeit auf die doppelte oder höchste Geschwindigkeit, je nachdem, welcher Wert niedriger ist. Kann nur einmal verwendet werden.

Hier ist ich die Teamnummer. Die Autos richten sich nach dem Rennen. Die Startlinie für das (i + 1) te Auto ist 200 * i Meter hinter dem i-ten Auto.

Alle starten gleichzeitig und versuchen ihre Höchstgeschwindigkeit zu erreichen. Eine Neubewertung der Positionen erfolgt alle 2 Sekunden (also auch wenn das Auto die Ziellinie dazwischen passiert hat, erfahren Sie nach 2 Sekunden). Während dieser Prüfung überprüft jeder Fahrer, ob sich ein Auto innerhalb von 10 Metern von seinem Auto befindet, seine Geschwindigkeit reduziert sich auf: hf * (Geschwindigkeit in diesem Moment). Wenn der Fahrer bemerkt, dass er der Letzte im Rennen ist, verwendet er "Nitro".

Aus der Anzahl der Teams und der Länge der Spur als Eingabe berechnen Sie die Endgeschwindigkeiten und die entsprechenden Fertigstellungszeiten.

Ich verstehe nicht, wie man diese Art von Problemen angeht. Für jede Instanz sollte ich alle C(n,2) Kombinationen jedes Paares von Treibern überprüfen und das Ergebnis berechnen? Aber wie kann ich herausfinden, an welcher Stelle ich die Berechnungen machen soll?

+1

ich bin mir nicht sicher, aber wenn ich Ihre Frage habe, ich denke, Sie müssen in "Client-Server" -Modell implementiert werden.Sie haben einen Server, der verantwortlich ist für das Halten der match.clients sind Autos (Teams). Bei jedem Schritt teilen die Clients dem Server ihre Informationen mit, und der Server speichert sie. Sie können auf alle anderen Informationen zugreifen. So erhalten sie bei jedem Schritt eine vollständige Liste der Autos und ihrer Informationen. So können sie herausfinden, ob es Autos gibt innerhalb von 10 Metern mit der Zeit von O (n). gerade wie reale Formel 1, die alle Fahrerklassifizierungen und den Platz zeigt, den sie auf dem Schirm sind! –

Antwort

8

Wenn Sie die Conway's Game of Life überprüfen, werden Sie feststellen, dass das Race-Problem sehr ähnlich ist. Hier

ist die Analogie:

  • Der Anfangszustand (der Samen des Systems):
    • Spiel des Lebens: initial Muster auf dem Raster. Jede Zelle mit den folgenden Parametern:
      • x und y-Koordinate
      • ob die Zelle lebt oder tot ist
    • Rennen Problem: n Fahrzeuge jeweils eine mit vorbestimmten Parametern und die Länge der Strecke l. Jeder Wagen hat die folgenden Parameter:
      • Endgeschwindigkeit
      • Beschleunigungs
      • Faktor Handhabung
      • Position auf der Strecke
      • aktuelle Geschwindigkeit
  • Die Regeln an diskreten Momente aufgebracht werden, die heißen Ticks.
    • Spiel des Lebens: Die Regeln werden gleichzeitig auf jede Zelle der vorherigen Generation angewendet, die eine nächste Generation produziert. Jede Generation ist eine reine Funktion des vorhergehenden.
    • Race Problem: die Regeln werden gleichzeitig auf jedes Auto aus dem vorherigen Zustand angewendet, der einen nächsten Zustand produziert. Dies geschieht alle 2 Sekunden. Wie bei Game of Life ist jeder Schritt eine reine Funktion des vorhergehenden, was bedeutet, dass es nur von den Parametern der Autos aus dem vorherigen Zustand abhängt.

Was anders ist, ist, dass das Spiel des Lebens endet nie während des Rennens Problems beendet werden soll, wenn die aktuelle Position jedes Auto größer oder gleich die Spurlänge l ist (Obwohl die letzte Aussage ist fraglich: due zum Handling-Faktor ist es möglich, dass unter manchen Bedingungen einige Autos nie die Ziellinie erreichen werden).

Der entscheidende Punkt ist, dass Berechnungen an diskreten Momente getan werden, die Ihre Frage beantwortet:

Aber wie kann ich auf das, was beispielsweise herausfinden, ich sollte die Berechnungen machen?

Sie können die Idee aus dem Abschnitt Algorithms nehmen, um dieses Problem zu lösen. Sie müssen 2 Autos Arrays haben: eine repräsentiert den aktuellen Zustand und die andere den nächsten Schritt. Bei jeder Iteration berechnen Sie die aktuelle Position und die Geschwindigkeit jedes Autos nach den Regeln aus der Zuweisung und prüfen, ob die Schleife beendet werden soll. Vor der nächsten Iteration tauschen Sie die Array-Rollen aus, so dass das Nachfolger-Array in der letzten Iteration in der nächsten Iteration zum aktuellen Array wird.

Der hohe Pseudo-Code kann wie folgt aussehen:

n = ..; // initial number of cars 
l = ..; // track length 
Car[] currentState = initializeState(n, l); 
Car[] nextState = clone(currentState); 
for (int iteration = 0; iteration < MAX_ITERATIONS; iteration++) { 
    calculateNextState(currentState, nextState, iteration); 
    swap(currentState, nextState); 
    if (shouldTerminate(currentState, l) { 
     break; 
    } 
} 

printResultOrClaimNotTerminated(currentState); 

Die Regeln angewandt werden in der calculateNextState (..) Funktion. In der am meisten naiven Implementierung überprüfen Sie jedes Paar von Autos, die Ihnen

O (C(n, 2)) = O (n * (n - 1)/2) = O (n^2)

Komplexität für jede Iteration gibt. Allerdings können Sie hier an mögliche Optimierungen denken. Zum Beispiel können Sie die Autos nach der aktuellen Position zuerst sortieren (O (n * log(n))) und dann das sortierte Array durchqueren und nur benachbarte Autos überprüfen (O (2 * n)). Sie können dies tun, da, wenn die 10-Meter-Bedingung für benachbarte Autos nicht genügt, sie für nicht benachbarte Autos nicht genügen wird. Dies gibt Ihnen die resultierende Komplexität von:

was viel besser ist. Das sortierte Array von Autos gibt Ihnen natürlich das Auto mit der letzten Position, auf die Sie die Nitro Boost-Regel anwenden müssen. Wahrscheinlich kann es andere Optimierungen geben. Dies beantwortet Ihre Frage:

Für jede Instanz sollte ich alle C (n, 2) Kombinationen von jedem Paar Treiber überprüfen und das Ergebnis berechnen?

+0

Entschuldigung, wenn ich falsch verstehe, muss die Sortieroperation jede Instanz (jede 2 Sekunden) durchgeführt werden? – shole

+0

@shole ja die Sortieroperation muss bei jeder Iteration durchgeführt werden. – medvedev1088

0

Auto Objekte und Spielobjekt

Ich gehe davon aus, dass Sie die erforderlichen Objekte für das Auto erstellt haben, in einem Spiel-Objekt gekapselt.

Ideen jedes Update Schritt zu beschleunigen nicht alle C zu tun (n, 2) prüft

Sie können die Update Position beschleunigen und Parameter Schritt, indem sie nicht alle C zu prüfen, mit (n, 2) Kombinationen . Eine einfache Heuristik, die Sie verwenden können, besteht darin, dass wir die Interaktionen zwischen weit entfernten Fahrzeugen nicht überprüfen müssen. Zum Beispiel wird ein Auto im ersten Viertel der Rennstrecke im dritten Viertel der Rennstrecke nicht mit einem Auto interagieren. Ich denke, basierend auf den Parametern Ihrer Frage wollen Sie die Rennstrecke in 10m lange Abschnitte aufteilen. Pflegen Sie eine Liste für jeden Abschnitt und behalten Sie alle Autos in jedem Abschnitt im Auge. Nach dem Aktualisieren der Positionen prüfen Sie die Interaktion zwischen den Fahrzeugen nur in aufeinanderfolgenden Abschnitten.

Behalten Sie in jedem Update-Schritt ebenfalls im Auge, welches Auto sich in der letzten Position befindet, und schalten Sie den Nitrobooster entsprechend um.

Wahl des Timesteps

In Ihrer Frage des Zeitschritt scheint bei 2 Sekunden festgelegt werden. In einer allgemeinen Einstellung, wenn Sie beispielsweise ein Spiel programmieren, ist diese Wahl jedoch entscheidend. Sie können mit ein paar verschiedenen Nummern spielen (zB 10.50.100.500 Millisekunden).

Wenn Sie den Zeitschritt wählen, um eine höhere Nummer zu sein, (z. B.) kann das Auto ein anderes Auto passieren und die Erkennung einer Kollision vermeiden. Wenn Sie andererseits den Zeitschritt zu klein wählen und die für die Vorgänge benötigte Zeit größer ist als der Zeitschritt, wird das Spiel langsamer als in Echtzeit ausgeführt.

Verwandte Themen