Головоломка для інтерв'ю про подорожі по відрізку лінії


10

На числовому рядку довжини M, де 0 < M <= 1,000,000,000ви вказали N( 1 < N <= 100,000) цілі пари пар точок. У кожній парі перша точка відображає те, де зараз знаходиться об'єкт, а друга точка - куди слід перемістити об’єкт. (Майте на увазі, secondточка може бути меншою за точку first).

Тепер припустимо, що ви починаєте з пункту 0і маєте візок, який може вмістити 1об'єкт. Ви хочете перемістити всі об'єкти з їх початкових позицій у відповідні кінцеві позиції, проїжджаючи найменшу відстань уздовж рядка числення ( не зміщення). Ви повинні закінчитись на точці M.

Зараз я намагаюся звести цю проблему до більш простої проблеми. Якщо чесно кажучи, я навіть не можу думати про грубі сили ( можливо, жадібні) рішення. Однак моя перша думка полягала в тому, щоб переробити рух назад на два рухи вперед, але це, здається, не працює у всіх випадках.

Я накреслив ці 3зразки тестових випадків тут:http://i.stack.imgur.com/zRv4Q.png

Відповідь на перший TestCase є 12. Спочатку ви забираєте redпредмет у точці 0. Потім ви переходите до точки 6(відстань = 6), redтимчасово опускаєте предмет, а потім піднімаєте greenпредмет. Потім ви переходите до точки 5(відстань = 1) і опускаєте greenпредмет. Потім ви переходите назад до точки 6(відстань = 1) і піднімаєте redпредмет, який ви упустили, переходите до точки 9 (відстань = 3), а потім переходите до точки 10(відстань = 1), щоб закінчити послідовність.

Загальна пройдена відстань становила 6 + 1 + 1 + 3 + 1 = 12мінімально можливу відстань.

На два інші випадки 12я вважаю відповідями. Однак я не можу знайти загальне правило для її вирішення.

Хтось мав якісь ідеї?


Якщо я не помиляюся, чи не потрібна вам структура даних для підрахунку "перекриття"? Інакше я вирішую це неправильно.
Девід

ви все ще можете прапор, і якщо мод погодиться, він знову відкриється та мігруватиме
храповик виродка

Ми можемо пересувати питання між сайтами автоматично (навіть якщо вони закриті), будь ласка, не переписуйте повідомлення. Натомість дотримуйтесь порад @ ratchetfreak, позначте увагу на модерацію та попросіть перенести це питання.
янніс

1
Це звучить насправді нівельно, але що робити, якщо ви почнете, рухаючись праворуч, поки не потрапите на шматок вантажу. Після того, як ви потрапите в цей вантаж, відкиньте все, що ви перевозили, підберіть його та продовжуйте розміщувати його в потрібному місці. Якщо ви потрапили на інший шматок вантажу, який потрібно перемістити, киньте струм, підберіть його і розібрайтеся з ним. Коли у вас немає вантажу, рухайтеся праворуч.
supersam654

1
Чи існують об'єкти у всіх точках чи лише в заданих? Чи можливо мати декілька об’єктів у даному місці? Чи дозволено тимчасово скидати об'єкт у місце, відмінне від його остаточного?
Шон Максомі

Відповіді:


4
  1. Якщо ви порожні, почніть рухатися праворуч.

  2. Щоразу, коли ви досягаєте об'єкта, і ви порожній, піднімайте його (духу) і рухайтеся до місця призначення.

  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) + ....
В основному, зважаючи на масив рухів, точка полягає в тому, щоб мінімізувати функцію "відстань проїзду" шляхом заміни елементів навколо. Якщо ви розглядаєте певну комбінацію як вузол, і всі комбінації, які ви можете досягти від неї, як краї, ви можете використовувати один із багатьох алгоритмів пошуку графіків, навколо яких використовується евристичний. Одним із прикладів є пошук променя .


0

Можливо, я не розумію проблеми, але як бути з наступним:

  1. Сортуйте пари за першим номером пари, який є поточним місцем розташування
  2. Перемістіть по елементах заміни рядка в потрібне місце (у вас є тимчасова змінна)

Той факт, що він відсортований, гарантує, що ви не повернетесь назад та вперед по елементах, щоб розмістити їх у потрібному місці (незалежно від того, якщо рядок представлений як масив чи список)

Оновлення після коментаря @templatetypedef:
Використовуйте a, HashTableщоб зберігати всі пари. Використовуйте поточне розташування кожної пари як індексний ключ.
Використовуйте другий індекс за парами.

 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  

Ви можете переміщати тільки один блок , в той час, так багато разів , ви повинні повторити свій шлях я думаю
Девід

Я насправді не стежу за вами. Здається, що вимога полягає лише в тому, щоб рухатись вперед і змінювати номери. Ви вже знаєте поточне місце розташування та цільове місце розташування. Просто поміняйте їх (використовуючи змінну кошика, як ви це говорите) та перейдіть до наступна пара
користувач10326

Розглянемо цей контрприклад: (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: Я бачу, що ви маєте на увазі. Оновлена ​​відповідь
user10326

Чи означає у вашій оновленій відповіді "поточний індекс" лише поточну позицію?
Девід

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являє собою?
Девід

Move.Origin - це місце, де знаходиться об'єкт, який потрібно перемістити в даний час - це його походження. В основному, дивлячись на крок, спочатку робіть будь-які менші рухи, що містяться в його діапазоні.
Лорен Печтел

-1

Це асиметрична проблема продавця подорожей . Ви можете думати це як графік. Краї будуть кожною парою (старт, кінець), по одній для кожного (0, початок), і всі інші пари (закінчити, почати).

Якщо припустити NP! = P, це матиме очікуваний експоненційний час роботи.


3
Я не впевнений, що це правда. Це особливий випадок асиметричного TSP, тому він може мати поліноміально-часове рішення.
templatetypedef

Чи не потрібні вам ребра типу (закінчення, М), де Mкінцева точка числового рядка?
Девід

Крім того, експоненціальний алгоритм занадто повільний, бо Nможе бути 100000.
Девід

Для підтвердження цього твердження, мабуть, у вас є метод перетворення кожної асиметричної проблеми продавця подорожі в рівноцінну проблему цього опису?
dan_waterworth

1
Це не рівнозначно. Мандрівний продавець повинен відвідати всі вершини графіка. Ваше формулювання вимагає від нього / її відвідування всіх країв.
alexis
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.