Quebra-cabeça da entrevista sobre como viajar em um segmento de linha


10

Em uma linha numérica de comprimento M, em que 0 < M <= 1,000,000,000você forneceu N( 1 < N <= 100,000) pares inteiros de pontos. Em cada par, o primeiro ponto representa onde um objeto está localizado atualmente e o segundo ponto representa para onde um objeto deve ser movido. (Lembre-se de que o secondponto pode ser menor que o first).

Agora, suponha que você comece no ponto 0e tenha um carrinho que possa conter 1objetos. Você deseja mover todos os objetos de suas posições iniciais para suas respectivas posições finais enquanto percorre a menor distância ao longo da linha numérica ( não deslocamento). Você tem que acabar no ponto M.

Agora, estou tentando reduzir esse problema para um problema mais simples. Para ser sincero, nem consigo pensar em uma solução de força bruta ( possivelmente gananciosa). No entanto, meu primeiro pensamento foi degenerar um movimento para trás em dois movimentos para frente, mas isso não parece funcionar em todos os casos.

Eu desenhei esses 3casos de teste de amostra aqui:http://i.stack.imgur.com/zRv4Q.png

A resposta para o primeiro caso de teste é 12. Primeiro, você escolhe o reditem no ponto 0. Então você vai para o ponto 6(distância = 6), solta o reditem temporariamente e, em seguida, pega o greenitem. Então você vai para o ponto 5(distância = 1) e solta o greenitem. Então você volta ao ponto 6(distância = 1) e pega o reditem que caiu, passa ao ponto 9 (distância = 3) e depois ao ponto 10(distância = 1) para finalizar a sequência.

A distância total percorrida foi 6 + 1 + 1 + 3 + 1 = 12, que é a distância mínima possível.

Os outros dois casos têm respostas 12, acredito. No entanto, não consigo encontrar uma regra geral para resolvê-lo.

Alguém tem alguma idéia?


Se não me engano, você não precisaria de uma estrutura de dados para contar a "sobreposição"? Caso contrário, estou resolvendo da maneira errada.
david

você ainda pode bandeira e se o mod concorda que ele vai reabrir e migrar
aberração catraca

Podemos mover perguntas entre sites automaticamente (mesmo que estejam fechados), por favor, não cruze a postagem. Em vez disso, siga o conselho de @ ratchetfreak, sinalize para atenção com moderação e solicite a migração da pergunta.
precisa

11
Isso parece realmente penoso, mas e se você começar movendo para a direita até atingir um pedaço de carga. Depois de atingir a carga, solte o que estiver carregando, pegue a carga e coloque-a no lugar certo. Se você acertar outro pedaço de carga que precisa ser movido, solte a corrente, pegue-a e lide com ela. Quando você não tiver carga, mova-se para a direita.
precisa

11
Os objetos existem em todos os pontos ou apenas nos dados? É possível ter vários objetos em um determinado local? É permitido definir temporariamente um objeto em um local que não seja o final?
22613 Sean McSomething

Respostas:


4
  1. Se você estiver vazio, comece a se mover para a direita.

  2. Sempre que você alcançar um objeto e estiver vazio, pegue-o (duh) e vá em direção ao seu destino.

  3. Sempre que você alcançar um objeto ae já estiver carregando b, sempre escolha um dos objetos com o destino numericamente menor (mais à esquerda).

  4. Se você ainda não está na M, volte para a etapa 1.

Isso é ideal: o único lugar onde você tem uma escolha real é na etapa 3. O primeiro destino do lado esquerdo garante que, quando você despachar os dois objetos, você estará o mais à direita possível.

Por que essa pergunta está no programmers.sx? Sim, "pergunta da entrevista", mas é apenas um bom enigma.

PS. Em termos de implementação, tudo que você precisa é a lista de tarefas (os pares inteiros de pontos) classificadas pela posição original.


1

Suponha que você receba esses movimentos, (a, b), (c, d), (e, f), ...então a distância mínima a ser percorrida é abs(b - a) + abs(d - c) + abs(f - e) + ...a distância real percorrida abs(b - a) + abs(c - b) + abs(d - c) + abs(e - d) + ....
Basicamente, dado um conjunto de movimentos, o objetivo é minimizar a função "distância da viagem" trocando elementos. Se você considerar uma combinação específica como um nó e todas as combinações que podem ser alcançadas como arestas, poderá usar um dos muitos algoritmos de pesquisa de gráficos em torno dos quais utiliza uma heurística. Um exemplo é a busca por vigas .


0

Pode ser que eu esteja entendendo mal o problema, mas e o seguinte:

  1. Classifique os pares pelo primeiro número do par que é o local atual
  2. Mova os elementos de troca de linha para o local apropriado (você tem uma variável temporária)

O fato de ser classificado garante que você não avance e avance os elementos para colocá-los no local apropriado (independentemente se a linha estiver representada como uma matriz ou lista)

Atualizar após o comentário @templatetypedef:
use a HashTablepara armazenar todos os pares. Use a localização atual de cada par como chave de índice.
Use um segundo índice sobre os 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  

Você só pode mover uma unidade de cada vez, por isso, muitas vezes você tem que refazer o caminho Eu acho
david

Eu realmente não o sigo. Parece que o requisito é apenas avançar e trocar números.Você já sabe o local atual e o local de destino. Apenas troque-os (usando a variável do carrinho como você diz) e vá para o próximo par
user10326

Considere este contra-exemplo: (1, 10), (10, 1), (2, 3), (3, 4). A melhor maneira de fazer isso seria transportar o objeto 1 para a posição 10, depois pegá-lo na posição 10 e carregá-lo para a posição 1, depois transportar o 2 para o 3 e o 3 para o 4. A ordem da posição inicial levaria de 1 a 10, depois de volta até o início, de 2 a 3, de 3 a 4, depois de todo o caminho até o final para pegar o 10 e trazer de volta.
templatetypedef

@templatetypedef: Eu ver o que você mean.Updated resposta
user10326

Na sua resposta atualizada, o "índice atual" indica apenas a posição atual?
david

0

Minha inclinação para um algoritmo que é basicamente ganancioso:

Crie uma lista de pontos que precisam ser movidos. Como otimizar isso não faz parte do problema necessário, não vou me preocupar em organizá-lo.

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

Eu acho que isso cobre todos os casos. Em certo sentido, é recursivo, mas através da atualização da lista, em vez de se chamar.


Obrigado pela resposta. Você pode explicar Destination = SubList.FindSmallest(Location, Move.Origin)? O que Move.Originrepresenta?
david

Move.Origin é o local onde está o objeto a ser movido atualmente - é sua origem. Basicamente, ao observar uma movimentação, faça movimentos menores contidos nela.
Loren Pechtel

-1

Esse é o problema do vendedor ambulante assimétrico . Você pode pensar nisso como um gráfico. As arestas serão cada par (início, término), um para cada (0, início) e todos os outros pares de (término, início).

Supondo que NP! = P, ele terá um tempo de execução esperado exponencial.


3
Não sei se isso é verdade. Este é um caso especial de TSP assimétrico, portanto, ele pode ter uma solução em tempo polinomial.
templatetypedef

Você não precisa de arestas como (acabamento, M), onde Mestá o ponto final da linha numérica?
david

Além disso, um algoritmo exponencial é muito lento, pois Npode ser 100.000.
david

Para apoiar esta afirmação, presumivelmente você tem um método para transformar todos os problemas de vendedores ambulantes assimétricos em um problema equivalente dessa descrição?
22613 dan_waterworth

11
Não é equivalente. O vendedor viajante deve visitar todos os vértices do gráfico. Sua formulação exige que ele visite todas as bordas.
22413 alexis
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.