Interview-Puzzle auf Reisen auf einem Liniensegment


10

Auf einer Zahlenlinie der Länge Mhaben 0 < M <= 1,000,000,000Sie N( 1 < N <= 100,000) ganzzahlige Punktepaare angegeben. In jedem Paar repräsentiert der erste Punkt, wo sich ein Objekt gerade befindet, und der zweite Punkt repräsentiert, wo ein Objekt bewegt werden soll. (Beachten Sie, dass der secondPunkt möglicherweise kleiner als der ist first).

Angenommen, Sie beginnen an der Stelle 0und haben einen Wagen, der 1Objekte aufnehmen kann. Sie möchten alle Objekte von ihren Anfangspositionen zu ihren jeweiligen Endpositionen verschieben, während Sie die geringste Strecke entlang der Zahlenlinie zurücklegen ( keine Verschiebung). Sie müssen auf den Punkt kommen M.

Jetzt habe ich versucht, dieses Problem auf ein einfacheres Problem zu reduzieren. Um ehrlich zu sein, kann ich mir nicht einmal eine Brute-Force- Lösung ( möglicherweise gierig) vorstellen. Mein erster Gedanke war jedoch, eine Rückwärtsbewegung in zwei Vorwärtsbewegungen zu degenerieren, aber das scheint nicht in allen Fällen zu funktionieren.

Ich habe diese 3Beispieltestfälle hier herausgezogen:http://i.stack.imgur.com/zRv4Q.png

Die Antwort auf den ersten Testfall lautet 12. Zuerst holen Sie den redGegenstand an der Stelle ab 0. Dann bewegen Sie sich zum Punkt 6(Entfernung = 6), lassen den redGegenstand vorübergehend fallen und nehmen den greenGegenstand auf. Dann bewegen Sie sich zum Punkt 5(Abstand = 1) und lassen den greenGegenstand fallen. Dann gehen Sie zurück zu Punkt 6(Entfernung = 1) und nehmen den redGegenstand auf, den Sie fallen gelassen haben. Gehen Sie zu Punkt 9 (Entfernung = 3) und dann zu Punkt 10(Entfernung = 1), um die Sequenz zu beenden.

Die zurückgelegte Gesamtstrecke war 6 + 1 + 1 + 3 + 1 = 12die minimal mögliche Entfernung.

Die beiden anderen Fälle haben Antworten auf 12, glaube ich. Ich kann jedoch keine allgemeine Regel finden, um das Problem zu lösen.

Hat jemand irgendwelche Ideen?


Wenn ich mich nicht irre, brauchen Sie dann keine Datenstruktur, um die "Überlappung" zu zählen? Ansonsten löse ich es falsch.
David

Sie können immer noch markieren und wenn der Mod zustimmt, wird er wieder öffnen und migrieren
Ratschenfreak

Wir können Fragen automatisch zwischen Websites verschieben (auch wenn diese geschlossen sind). Bitte nicht überkreuzen. Befolgen Sie stattdessen den Rat von @ ratchetfreak, markieren Sie die Aufmerksamkeit für die Moderation und fordern Sie die zu migrierende Frage an.
Yannis

1
Das klingt wirklich nie, aber was ist, wenn Sie sich zunächst nach rechts bewegen, bis Sie auf ein Stück Fracht treffen? Sobald Sie diese Ladung getroffen haben, lassen Sie alles fallen, was Sie tragen, nehmen Sie die Ladung auf und platzieren Sie sie an der richtigen Stelle. Wenn Sie auf ein anderes Stück Fracht treffen, das bewegt werden muss, lassen Sie den Strom fallen, heben Sie ihn auf und kümmern Sie sich darum. Wenn Sie keine Fracht haben, bewegen Sie sich nach rechts.
Supersam654

1
Existieren Objekte an allen Punkten oder nur an den angegebenen? Ist es möglich, mehrere Objekte an einem bestimmten Ort zu haben? Ist es zulässig, ein Objekt vorübergehend an einem anderen Ort als dem endgültigen abzulegen?
Sean McSomething

Antworten:


4
  1. Wenn Sie leer sind, bewegen Sie sich nach rechts.

  2. Wenn Sie ein Objekt erreichen und leer sind, heben Sie es auf (duh) und bewegen Sie sich in Richtung seines Ziels.

  3. Jedes Mal , wenn Sie ein Objekt zu erreichen aund Sie bereits tragen b, immer wählen , je nachdem , welche der Objekte die numerisch kleinste Ziel hat ( am weitesten links).

  4. Wenn Sie noch nicht bei M sind, fahren Sie mit Schritt 1 fort.

Dies ist optimal: Der einzige Ort, an dem Sie eine echte Auswahl haben, ist Schritt 3. Wenn Sie zuerst das Ziel ganz links behandeln, stellen Sie sicher, dass Sie sich zum Zeitpunkt des Versands beider Objekte so weit wie möglich rechts befinden.

Warum ist diese Frage auf programmers.sx? Ja, "Interviewfrage", aber es ist nur ein schönes Rätsel.

PS. Für die Implementierung benötigen Sie lediglich eine Liste der Aufgaben (die ganzzahligen Punktepaare), die nach der ursprünglichen Position sortiert sind.


1

Angenommen, Sie erhalten diese Bewegungen, (a, b), (c, d), (e, f), ...dann ist die Mindestentfernung, die Sie zurücklegen müssen, abs(b - a) + abs(d - c) + abs(f - e) + ...und die tatsächliche Entfernung, die Sie zurücklegen abs(b - a) + abs(c - b) + abs(d - c) + abs(e - d) + ....
Grundsätzlich besteht der Punkt bei einer Reihe von Bewegungen darin, die Funktion "Fahrstrecke" durch Vertauschen von Elementen zu minimieren. Wenn Sie eine bestimmte Kombination als Knoten betrachten und alle Kombinationen, die Sie daraus als Kanten erreichen können, können Sie einen der vielen Graphensuchalgorithmen verwenden, um die herum eine Heuristik verwendet wird. Ein Beispiel ist die Strahlensuche .


0

Vielleicht verstehe ich das Problem falsch, aber was ist mit Folgendem:

  1. Sortieren Sie die Paare nach der ersten Nummer des Paares, das der aktuelle Standort ist
  2. Bewegen Sie sich entlang der Linie und tauschen Sie die Elemente an die richtige Position aus (Sie haben eine temporäre Variable).

Die Tatsache, dass es sortiert ist, garantiert, dass Sie die Elemente nicht hin und her bewegen, um sie an der richtigen Stelle zu platzieren (unabhängig davon, ob die Linie als Array oder Liste dargestellt wird).

Update nach @ templatetypedef Kommentar:
Verwenden Sie a HashTable, um alle Paare zu speichern. Verwenden Sie die aktuelle Position jedes Paares als Indexschlüssel.
Verwenden Sie einen zweiten Index über den Paaren.

 1. Get next pair according to index from the line.
 2. If current pair exists in hashtable then place element to its target location.  
    2.a Remove pair from hashtable.  
    2.b Make current pair the target location. Then go to step 1  
 ELSE 
        Increment current index until you get a pair present in the hashtable. Go to step 2  

Sie können nur eine Einheit zu einem Zeitpunkt verschieben, so oft Sie Ihren Weg zurückzuverfolgen muss ich denken
david

Ich folge dir nicht wirklich. Es scheint, dass die Anforderung nur darin besteht, vorwärts zu gehen und Nummern zu tauschen. Du kennst bereits den aktuellen Ort und den Zielort. Tausche sie einfach aus (benutze die Wagenvariable, wie du es sagst) und gehe zum nächstes Paar
user10326

Betrachten Sie dieses Gegenbeispiel: (1, 10), (10, 1), (2, 3), (3, 4). Der optimale Weg, dies zu tun, wäre, Objekt 1 zu Position 10 zu tragen, dann das Objekt an Position 10 aufzunehmen und zu Position 1 zu tragen, dann die 2 zu 3 und die 3 zu 4 zu tragen Die Reihenfolge der Startposition würde die 1 bis 10 tragen, dann bis zum Start zurück, um die 2 bis 3, die 3 bis 4 zu tragen, und dann bis zum Ende gehen, um die 10 aufzunehmen und zu bringen es zurück.
Templatetypedef

@ Templatetypedef: Ich verstehe, was Sie meinen. Aktualisierte Antwort
user10326

Gibt der "aktuelle Index" in Ihrer aktualisierten Antwort nur die aktuelle Position an?
David

0

Meine Neigung zu einem Algorithmus, der grundsätzlich gierig ist:

Erstellen Sie eine Liste mit Punkten, die verschoben werden müssen. Da die Optimierung nicht Teil des erforderlichen Problems ist, werde ich mich nicht um die Organisation kümmern.

while !Done
    if CartIsEmpty()
        FindClosestObjectToMove()
        MoveToObject()
       LoadCart()
    else
        Destination = Cart.Contains.Target
        CurrentMove = [Location, Destination]
        SubList = List.Where(Move.Within(CurrentMove))
        if !SubList.Empty
            Destination = SubList.FindSmallest(Location, Move.Origin)
        MoveTo(Destination)
        if !Destination.Empty
            SwapCart()
            UpdateTaskList()
        else
            EmptyCart()
            DeleteTask()

Ich denke, das deckt alle Fälle ab. In gewisser Weise ist es rekursiv, aber durch Aktualisieren der Liste, anstatt sich selbst aufzurufen.


Danke für die Antwort. Kannst du das erklären Destination = SubList.FindSmallest(Location, Move.Origin)? Was bedeutet Move.Origin?
david

Move.Origin ist der Ort, an dem sich das zu verschiebende Objekt gerade befindet - sein Ursprung. Wenn Sie sich zuerst einen Zug ansehen, machen Sie grundsätzlich alle kleineren Züge, die in seiner Spanne enthalten sind.
Loren Pechtel

-1

Dies ist das asymmetrische Problem des Handlungsreisenden . Sie können sich dies als Grafik vorstellen. Die Kanten sind jedes Paar (Start, Ende), eines für jedes Paar (0, Start) und alle anderen Paare von (Ende, Start).

Unter der Annahme von NP! = P hat es eine exponentiell erwartete Laufzeit.


3
Ich bin mir nicht sicher, ob das stimmt. Dies ist ein Sonderfall von asymmetrischem TSP, daher kann es sich um eine Polynomzeitlösung handeln.
Templatetypedef

Benötigen Sie keine Kanten wie (Ende, M), wo Mist der Endpunkt der Zahlenlinie?
david

Außerdem ist ein Exponentialalgorithmus viel zu langsam, Nda er 100.000 betragen kann.
David

Um diese Aussage zu untermauern, haben Sie vermutlich eine Methode, um jedes asymmetrische Problem eines reisenden Verkäufers in ein gleichwertiges Problem dieser Beschreibung umzuwandeln?
dan_waterworth

1
Es ist nicht gleichwertig. Der reisende Verkäufer muss alle Eckpunkte des Diagramms besuchen. Ihre Formulierung erfordert, dass er / sie alle Kanten besucht.
Alexis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.