線分の移動に関するインタビューパズル


10

長さの数直線上のM0 < M <= 1,000,000,000指定した、N1 < N <= 100,000点の対の整数)。各ペアで、最初のポイントはオブジェクトが現在配置されている場所を表し、2番目のポイントはオブジェクトを移動する必要がある場所を表します。(覚えておいてくださいsecondポイントがかもしれ小さいよりfirst)。

ここで、その時点0から始めて、1オブジェクトを保持できるカートがあるとします。すべてのオブジェクトを最初の位置からそれぞれの最終位置に移動し、数直線に沿って(変位ではなく)最短距離を移動したいとします。あなたはポイントで終わる必要がありMます。

今、私はこの問題をより簡単な問題に削減しようとしています。正直なところ、私は力ずくの(おそらく貪欲な)解決策を考えることすらできません。しかし、私の最初の考えは、後方への動きを2つの前方への動きに縮退させることでしたが、それがすべての場合に機能するとは思われません。

私はこれらの3サンプルテストケースをここに引き出しました:http://i.stack.imgur.com/zRv4Q.png

最初のテストケースへの答えは12です。まず、redポイントでアイテムを受け取ります0。次に、ポイント6(距離= 6)に移動し、redアイテムを一時的にドロップして、アイテムを拾いgreenます。次に、ポイント5(距離= 1)に移動してgreenアイテムをドロップします。次に、ポイント6(距離= 1)に戻ってredドロップしたアイテムを拾い、ポイント9(距離= 3)に移動してから、ポイント10(距離= 1)に移動してシーケンスを終了します。

移動した総距離はでした6 + 1 + 1 + 3 + 1 = 12。これは可能な最小距離です。

他の2つのケースにはの答えがある12と思います。しかし、私はそれを解決するための一般的なルールを見つけることができません。

誰かアイデアはありますか?


私が間違っていなければ、「オーバーラップ」をカウントするためのデータ構造が必要ではないでしょうか。そうでなければ私はそれを間違った方法で解決しています。
デヴィッド・

あなたはまだすることができフラグとmodが同意すれば、彼は再度開くと移行する
ラチェットフリーク

質問はサイト間で自動的に移動できます(閉じている場合でも)。クロスポストしないでください。代わりに、@ ratchetfreakのアドバイスに従い、モデレートの注意を喚起し、移行する質問を尋ねます。
yannis 2013

1
これは本当に素朴に聞こえますが、貨物に当たるまで右に移動することから始めたらどうでしょう。その貨物にぶつかったら、運んでいるものをすべて落とし、その貨物を拾って、正しい場所に置きます。移動する必要がある別の貨物にぶつかった場合は、電流をドロップし、それを拾って対処します。荷物がなくなったら右に移動。
supersam654 2013

1
オブジェクトはすべてのポイントに存在しますか、それとも指定されたものだけに存在しますか?特定の場所に複数のオブジェクトを配置することは可能ですか?オブジェクトを最終的な場所以外の場所に一時的に置くことはできますか?
Sean McSomething、2013

回答:


4
  1. 空の場合は、右に移動してください。

  2. あなたがオブジェクトに到達して空になったときはいつでも、それを拾って(duh)そしてその目的地に向かって移動します。

  3. オブジェクトに到達してa既にを持っている場合はb常に、数値的に最小の宛先(左端)のオブジェクトを選択してください。

  4. まだMにいない場合は、手順1に戻ります。

これが最適です。実際に選択できる唯一の場所はステップ3です。左端の宛先を最初に処理することで、両方のオブジェクトをディスパッチするまでに、可能な限り右側に移動します。

なぜprogrammers.sxでこの質問があるのですか?はい、「インタビューの質問」ですが、それはちょうどいい謎です。

PS。実装に関して必要なのは、元の位置でソートされたタスクのリスト(ポイントの整数ペア)だけです。


1

これらの動きが与えられたとすると、あなたが移動し(a, b), (c, d), (e, f), ...なければならない最小距離はでabs(b - a) + abs(d - c) + abs(f - e) + ...あり、実際の移動距離はabs(b - a) + abs(c - b) + abs(d - c) + abs(e - d) + ...です。
基本的に、移動の配列が与えられた場合、ポイントは、要素を交換することによって「移動距離」関数を最小化することです。特定の組み合わせをノードと見なし、そこから到達できるすべての組み合わせをエッジと見なす場合は、ヒューリスティックを利用する多くのグラフ検索アルゴリズムの1つを使用できます。その一例がビームサーチです。


0

私は問題を誤解しているかもしれませんが、以下についてはどうですか:

  1. 現在の場所であるペアの最初の番号でペアを並べ替えます
  2. 要素を交換する行に沿って適切な場所に移動します(一時変数があります)。

それがソートされているという事実は、要素を前後に動かして適切な場所に配置しないことを保証します(行が配列またはリストとして表されているかどうかに関係なく)

@templatetypedefコメントの後の更新:
a HashTableを使用してすべてのペアを保存します。各ペアの現在の場所をインデックスキーとして使用します。
ペアに対して2番目のインデックスを使用します。

 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  

一度に移動できるのは1ユニットだけなので、何度も経路をたどる必要があると思います
david

私は実際にはあなたに従いません。要件は、前進して番号を交換することだけであるようです。現在の場所とターゲットの場所がすでにわかっているので、それらを交換して(カート変数を使用して)、次のペア
user10326

この反例を考えてみましょう:(1、10)、(10、1)、(2、3)、(3、4)。これを行う最適な方法は、オブジェクト1を位置10に運び、オブジェクトを位置10でピックアップして位置1に運び、2を3に、3を4に運ぶことです。開始位置の順序は、1から10を運び、最初から最後まで戻って2から3、3から4を運び、最後から最後まで移動して10をピックアップし、それが戻った。
templatetypedef

@templatetypedef:私はあなたが答えをmean.Updatedものを見る
user10326

更新された回答では、「現在のインデックス」は現在の位置を示しているだけですか?
david

0

基本的に貪欲なアルゴリズムに関する私の傾向:

移動する必要があるポイントのリストを作成します。これを最適化することは必要な問題の一部ではないので、整理することについて心配するつもりはありません。

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()

これはすべてのケースをカバーすると思います。ある意味でそれは再帰的ですが、それ自体を呼び出すのではなく、リストを更新することによって。


答えてくれてありがとう。説明できますDestination = SubList.FindSmallest(Location, Move.Origin)か?何をMove.Origin表していますか?
david

Move.Originは、現在移動するオブジェクトがある場所、つまりその原点です。基本的に、最初に動きを見るとき、そのスパン内に含まれる小さな動きを実行します。
Loren Pechtel 2013

-1

これは非対称巡回セールスマン問題です。これはグラフと考えることができます。エッジは、各(開始、終了)ペア、各(0、開始)の各ペア、および(終了、開始)の他のすべてのペアになります。

NP!= Pと仮定すると、予想実行時間は指数関数的になります。


3
それが本当かどうかはわかりません。これは非対称TSPの特殊なケースであるため、多項式時間の解を持つ可能性があります。
templatetypedef

(finish、M)のようなエッジは必要ありませんMか?数直線の端点はどこですか?
デビッド

また、指数アルゴリズムは非常に遅いため、N100,000になる場合があります。
david

この声明を裏付けるために、おそらくあなたはすべての非対称巡回セールスマン問題をこの説明の同等の問題に変換する方法を持っていますか?
dan_waterworth 2013

1
それは同等ではありません。巡回セールスマンは、グラフのすべての頂点を訪問する必要があります。あなたの処方は彼/彼女がすべてのエッジを訪問することを要求します。
アレクシス2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.