Entrevista sobre viajar en un segmento de línea

10

En una recta numérica de longitud M, donde 0 < M <= 1,000,000,000, le dio N( 1 < N <= 100,000) pares enteros de puntos. En cada par, el primer punto representa dónde se encuentra actualmente un objeto y el segundo punto representa dónde se debe mover un objeto. (Tenga en cuenta que el secondpunto puede ser más pequeño que el first).

Ahora, suponga que comienza en el punto 0y tiene un carrito que puede contener 1objetos. Desea mover todos los objetos desde sus posiciones iniciales a sus respectivas posiciones finales mientras recorre la menor distancia a lo largo de la recta numérica ( no desplazamiento). Tienes que terminar a punto M.

Ahora, he estado tratando de reducir este problema a un problema más simple. Para ser sincero, ni siquiera puedo pensar en una solución de fuerza bruta ( posiblemente codiciosa). Sin embargo, mi primer pensamiento fue degenerar un movimiento hacia atrás a dos movimientos hacia adelante, pero eso no parece funcionar en todos los casos.

Dibujé estos 3casos de prueba de muestra aquí:http://i.stack.imgur.com/zRv4Q.png

La respuesta al primer caso de prueba es 12. Primero, recoges el redartículo en el punto 0. Luego te mueves al punto 6(distancia = 6), sueltas el redartículo temporalmente y luego lo recoges green. Luego te mueves al punto 5(distancia = 1) y sueltas el greenelemento. Luego regresa al punto 6(distancia = 1) y recoge el redelemento que dejó caer, vaya al punto 9 (distancia = 3), luego vaya al punto 10(distancia = 1) para finalizar la secuencia.

La distancia total recorrida fue 6 + 1 + 1 + 3 + 1 = 12, que es la distancia mínima posible.

Los otros dos casos tienen respuestas 12, creo. Sin embargo, no puedo encontrar una regla general para resolverlo.

¿Alguien tiene alguna idea?

david
fuente
Si no me equivoco, ¿no necesitaría una estructura de datos para contar la "superposición"? De lo contrario, lo estoy resolviendo de la manera incorrecta.
David
todavía puedes marcar y si el mod está de acuerdo, volverá a abrir y migrará
fanático del trinquete
Podemos mover las preguntas entre sitios automáticamente (incluso si están cerradas), por favor, no publique mensajes cruzados. En cambio, siga los consejos de @ ratchetfreak, marque la atención de moderación y solicite que se migre la pregunta.
Yannis
1
Esto suena realmente nevado, pero ¿qué pasa si comienzas moviéndote hacia la derecha hasta que golpeas un pedazo de carga? Una vez que golpea esa carga, suelte lo que esté cargando, recoja esa carga y proceda a colocarla en el lugar correcto. Si golpea otra pieza de carga que necesita ser movida, deje caer la corriente, recójala y enfréntela. Cuando no tenga carga, muévase a la derecha.
supersam654
1
¿Existen objetos en todos los puntos o solo en los dados? ¿Es posible tener múltiples objetos en una ubicación dada? ¿Está permitido establecer temporalmente un objeto en una ubicación distinta de la final?
Sean McSomething

Respuestas:

4
  1. Si está vacío, comience a moverse hacia la derecha.

  2. Siempre que alcances un objeto y estés vacío, recógelo (duh) y muévete hacia su destino.

  3. Siempre que llegue a un objeto ay ya lo esté cargando b, elija siempre el objeto que tenga el destino numéricamente más pequeño (más a la izquierda).

  4. Si aún no estás en M, vuelve al paso 1.

Esto es óptimo: el único lugar donde tiene una opción real es en el paso 3. El manejo del destino más a la izquierda primero asegura que para cuando haya despachado ambos objetos, estará lo más a la derecha posible.

¿Por qué esta pregunta está en programmers.sx? Sí, "pregunta de entrevista", pero es un buen acertijo.

PD. En términos de implementación, todo lo que necesita es la lista de tareas (los pares de puntos enteros) ordenadas por posición original.

alexis
fuente
1

Suponga que le dan estos movimientos, (a, b), (c, d), (e, f), ...entonces la distancia mínima que tiene que viajar es abs(b - a) + abs(d - c) + abs(f - e) + ...y la distancia real que viaja abs(b - a) + abs(c - b) + abs(d - c) + abs(e - d) + ....
Básicamente, dada una serie de movimientos, el punto es minimizar la función de "distancia de viaje" intercambiando elementos. Si considera una combinación particular como un nodo y todas las combinaciones que puede alcanzar desde él como bordes, puede usar uno de los muchos algoritmos de búsqueda de gráficos alrededor del cual se utiliza una heurística. Un ejemplo es la búsqueda de haz .

Oso negro
fuente
0

Puede ser que no entienda bien el problema, pero ¿qué pasa con lo siguiente?

  1. Ordenar los pares por el primer número del par, que es la ubicación actual
  2. Mover a lo largo de la línea intercambiando elementos a su ubicación adecuada (tiene una variable temporal)

El hecho de que esté ordenado garantiza que no vaya de un lado a otro de los elementos para colocarlos en la ubicación adecuada (independientemente de si la línea se representa como una matriz o lista)

Actualización después del comentario @templatetypedef:
use a HashTablepara almacenar todos los pares. Use la ubicación actual de cada par como clave de índice.
Use un segundo índice sobre los pares.

 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  
usuario10326
fuente
Solo puedes mover una unidad a la vez, creo que muchas veces tienes que volver sobre tu camino
david
Realmente no te sigo. Parece que el requisito es solo avanzar e intercambiar números. Ya conoces la ubicación actual y la ubicación de destino. Simplemente cámbialos (usando la variable del carrito como lo dices) y ve a siguiente par
user10326
Considere este contraejemplo: (1, 10), (10, 1), (2, 3), (3, 4). La forma óptima de hacer esto sería llevar el objeto 1 a la posición 10, luego levantar el objeto en la posición 10 y llevarlo a la posición 1, luego llevar el 2 al 3 y el 3 al 4. Hacer esto en orden el orden de la posición inicial llevaría el 1 al 10, luego volvería al principio para llevar el 2 al 3, el 3 al 4, luego iría hasta el final para recoger el 10 y traer de nuevo
templatetypedef
@templatetypedef: veo lo que quieres decir. Respuesta
actualizada
En su respuesta actualizada, ¿el "índice actual" solo indica la posición actual?
David
0

Mi inclinación hacia un algoritmo que es básicamente codicioso:

Crea una lista de puntos que necesites mover. Dado que optimizar esto no es parte del problema requerido, no me preocuparé de organizarlo.

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

Creo que esto cubre todos los casos. En cierto sentido, es recursivo, pero a través de la actualización de su lista en lugar de llamarse a sí mismo.

Loren Pechtel
fuente
Gracias por la respuesta. ¿Puede usted explicar Destination = SubList.FindSmallest(Location, Move.Origin)? ¿Qué Move.Originrepresenta?
David
Move.Origin es la ubicación donde está actualmente el objeto a mover: su origen. Básicamente, al mirar un movimiento primero, haga cualquier movimiento más pequeño contenido dentro de su lapso.
Loren Pechtel
-1

Este es el problema asimétrico del vendedor ambulante . Puedes pensar en esto como un gráfico. Los bordes serán cada par (inicio, finalización), uno para cada (0, inicio) y todos los demás pares de (finalización, inicio).

Suponiendo que NP! = P, tendrá un tiempo de ejecución esperado exponencial.

MSN
fuente
3
No estoy seguro de que sea verdad. Este es un caso especial de TSP asimétrico, por lo que podría tener una solución de tiempo polinomial.
templatetypedef
¿No necesita bordes como (acabado, M), donde Mestá el punto final de la recta numérica?
David
Además, un algoritmo exponencial es demasiado lento, ya que Npuede ser 100,000.
David
Para respaldar esta afirmación, ¿presumiblemente tiene un método para transformar cada problema de vendedor ambulante asimétrico en un problema equivalente de esta descripción?
dan_waterworth
1
No es equivalente El vendedor ambulante debe visitar todos los vértices del gráfico. Su formulación requiere que él / ella visite todos los bordes.
alexis