Fila de prioridade para prioridades parcialmente solicitadas com infima

16

Eu tenho alguns objetos com prioridade que é do tipo composto e é apenas parcialmente ordenada . Eu preciso selecionar os objetos na ordem desta prioridade (ou seja, produzir itens mínimos a cada vez). Mas, em vez de concluir arbitrariamente o pedido, eu preferiria que a fila fosse estável, no sentido de que, se houver mais de um elemento mínimo, ele retornará o mais antigo primeiro.

Existe alguma estrutura de dados de heap que funcione com pedidos parciais? Ou uma modificação da fila de prioridade regular para trabalhar com ela? A escolha comum para o algoritmo de que eu preciso é um binário simples ou heap de 4 árias, mas isso não funciona com a ordenação parcial.

Os valores de prioridade suportam:

  1. Pedido parcial usando a operação . É uma ordem parcial, portanto, é possível que a \ preccurlyeq b seja falso e b \ preccurlyeq a também seja falso. Eu escrevo a \ not \ lesseqgtr b nesse caso.a b b a a ̸ bumabbumauma⋚̸b
  2. Encontrar infima (glb) e suprema (lub). inf(xEu) é o máximo y modo que yxEu . Calcular o mínimo de n valores leva O(n) tempo. Existe o mínimo (e supremo) de todos os conjuntos.
  3. Uma extensão linear para a ordem parcial pode ser definida. Usá-lo para a fila de prioridade é a saída mais fácil, pois o algoritmo funciona dessa maneira. Mas a ordem afeta o desempenho e a ordem de inserção parece ser melhor para evitar os piores casos.

Além disso, o algoritmo em que eu quero usar isso precisa conhecer o mínimo de todas as prioridades na fila.

As prioridades têm algum significado no mundo real, mas estão sujeitas a alterações, portanto, não parece viável confiar em outras propriedades que possam ter.


Nota: pilhas binárias não funcionam com pedidos parciais. Suponha uma pilha binário com uma , b e c , onde umac e uma⋚̸b e uma⋚̸c . Eles estão posicionados nessa ordem, então

     a (0)
   /   \
 b (1)   c (2)

agora d está inserido. A próxima posição livre é 3, o filho esquerdo de b , então obtemos

        a (0)
      /   \
    b (1)   c (2)
  /
d (3)

Se (o que implica de transitividade, mas não diz nada sobre e ) e , então não se trocado com , porque não menos é. Mas, na verdade, é menor que , mas não é comparado a ele, então agora a invariante principal do heap não se sustenta; top não é mínimo.d c d b d ̸ b d b umdumadcdbd⋚̸bdbuma

Suspeito que uma floresta de montes um tanto no estilo de pilha binomial possa ser feita para funcionar. Basicamente, é importante sempre comparar novos valores com raiz e vincular apenas elementos comparáveis. Isso tornaria as árvores da floresta de tamanho aleatório e, portanto, tornaria a complexidade dependente do número de conjuntos mutuamente incomparáveis ​​no monte. Suspeito que a complexidade não possa ser corrigida (temos que continuar comparando até encontrarmos um elemento comparável). Talvez eu tenha perdido alguma coisa, então estou deixando isso em aberto.


Nota: A ordem é parcial e, embora haja maneiras de definir extensões lineares para ela, adicionar um carimbo de data e hora e usá-lo como critério secundário não é um deles. Suponha que atribuiu o timestamp para cada e definiu a ordenação como sse ou ( e . em seguida, suponha que temos distinta , , , tal que e . então et(uma)umaumabumabbumat(uma)t(b)umabct(uma)t(b)t(c)cumaumabbc , mas , então a relação não é transitiva e, portanto, não é uma ordenação. Esse tipo de extensão funciona apenas para pedidos fracos, mas não parciais.cuma


Edit: eu percebi que não só é o mínimo de qualquer conjunto definido, mas também preciso ser capaz de obter o menor número possível de elementos atualmente na fila com eficiência. Portanto, agora estou pensando se a adição de nós especiais contendo informações de subárvores a alguma estrutura de heap comum ajudaria.

Jan Hudec
fonte
Você considerou uma fila de prioridade indexada?
@hulkmeister: Você poderia explicar como a indexação da fila faz com a ordenação parcial (não, o heap binário comum não funciona com a ordenação parcial)?
1
Meu pensamento era que, quando dois itens são incomparáveis, você pode usar o índice para rastrear a ordem da inserção. Portanto, componha a prioridade com o índice e você terá chaves únicas comparáveis, mesmo quando a prioridade não for. Se isso soa como o que você deseja, posso colocá-lo em uma resposta completa.
1
@ hulkmeister: Bem, o problema é muito mais profundo do que isso. Quando um novo item é inserido, a fila de prioridade normalmente o compara com algum elemento. Mas se eles são incomparáveis, simplesmente não sabem onde inseri-lo. E a desambiguação com o índice não funcionará, porque o índice muda e porque provavelmente não daria uma ordem total consistente com a prioridade.
Você pode dar um exemplo desse tipo de composto e quando é incomparável? É possível considerar esses valores 'incomparáveis' iguais? Nesse caso, você pode armazená-los no mesmo nó em ordem de inserção.

Respostas:

3

Embora o problema exato colocado na pergunta original pareça difícil (e eu estaria interessado em uma solução para esse problema, especialmente a parte de encontrar informações). Eu só queria observar que, se o conjunto parcialmente ordenado consistir em vetores usando um pedido de produto e se for suficiente apenas garantir que a fila de prioridade retorne os valores em um pedido "compatível" com o pedido parcial ( ou seja, elementos menores sempre são retornados antes dos elementos maiores), então existe uma maneira bastante fácil de fazer isso.

A idéia é essencialmente encontrar uma ordem topológica do conjunto parcialmente ordenado. Ou seja, uma ordem total ' ' tal que . Para vetores que usam um pedido de produto, isso é bastante fácil: basta usar um pedido lexicográfico ' ', em que o primeiro "componente" é a soma de todos os componentes usados ​​para o pedido do produto (o restante dos componentes é essencialmente arbitrário, para que você também possa manter uma ordem fraca). Podemos então ver que e abTS a < bumabumaTbSa = b

uma<bEu(umaEubEu) e Eu(umaEu<bEu)(EuumaEu)<(EubEu)umaSb
a=bi(ai=bi)(iai)=(ibi)aSb,
e portanto, que . Assim, podemos usar esse pedido com uma fila prioritária e garantir que os elementos menores (na ordem do produto) sejam sempre extraídos antes dos elementos maiores.abaSb
Jaspe
fonte
Existem muitas mais opções. Usando um dos componentes, mínimo, máximo, qualquer combinação linear com coeficientes não negativos, pelo menos. A escolha da extensão afeta a rapidez com que o algoritmo de sobreposição será.
Jan Hudec
2

O que há de errado em concluir sua encomenda parcial?

Mas, em vez de concluir arbitrariamente o pedido, eu preferiria que a fila fosse estável, no sentido de que, se houver mais de um elemento mínimo, ele retornará o mais antigo primeiro.

Se você preferir "o mais antigo primeiro", seu pedido será efetivamente concluído; itens 'incomparáveis' são comparáveis ​​por idade.

Adicione um carimbo de data / hora (ou qualquer outro número inteiro que cresce monotonamente) a cada item e use-o se a comparação 'real' for impossível.


fonte
3
Isso seria ótimo se pudesse ser feita uma extensão linear da ordem parcial. Mas não é. Vamos ter 3 valores distintos, inseridos na ordem a , b , c , de modo que c ≤ a e b sejam incomparáveis ​​com qualquer um deles. A extensão com preenchimentos timestamp em um 'b ≤ e b ≤' c , então a partir transitividade agora um deve ser menor que c , mas que contradiz a ordem real.
Talvez você tenha confundido isso com pedidos fracos. Na ordem fraca, os elementos incomparáveis ​​formam classes de equivalência, para que você possa adicionar critérios adicionais arbitrários. Para pedidos parciais, você não pode.
1

EDIT: este parece ser um problema interessante, e eu tive uma pequena pesquisa sobre isso. Eu sugiro que você leia o seguinte:

  1. Darell Raymond. Bancos de dados de pedidos parciais, tese de doutorado, University of Waterloo.

Sugiro que você leia este artigo: Daskalakis, Constantinos, et al. "Classificação e seleção em posets." Jornal SIAM sobre Computação 40.3 (2011): 597-622.

Os autores apresentam aqui uma estrutura de dados chamada ChainMerge que aceita um poset e uma decomposição em cadeia do poset em cadeias . O tamanho da estrutura de dados é . Os autores apresentam um algoritmo para encontrar os mínimos que são executados em onde é um limite superior na largura do poset. .. Eu pensei que talvez isso seja interessante.qO(nq)O(Wn)W

Nota: eu apaguei uma resposta ingênua anterior. Clique em editar para vê-lo.

AJed
fonte
0

Meu uso da terminologia pode estar incorreto. Por favor, edite minha resposta diretamente para corrigir os problemas encontrados.


Primeiro, conjuntos mutuamente incomparáveis ​​precisam ser detectados a partir das entradas.

Por exemplo, pode haver 5 objetos a, b, c, d, e, mas sua ordem parcial forma dois gráficos desconectados:

  • a ≤ b ≤ c
  • d ≤ e
  • mas qualquer um de {a, b, c}é incomparável com qualquer um de {d, e}.

Esses conjuntos mutuamente incomparáveis ​​precisam ser detectados primeiro, antes que os objetos possam ser armazenados em uma estrutura de dados apropriada. Isso pode ser feito com um algoritmo de localização da União


Para eficiência, a inserção de um novo objeto precisa ter uma maneira eficiente de encontrar "a lista de objetos existentes que são comparáveis ​​a esse novo objeto".


Agora, dentro de cada subconjunto (respectivamente {a, b, c}e {d, e}), os mínimos devem ser bem definidos. (Para cada subconjunto, pode haver um ou mais mínimos, devido a pedidos parciais.)

Eu vejo isso como um gráfico acíclico direcionado . Tentar encaixá-lo em uma pilha parece desastroso.


Para extrair os mínimos dessa estrutura de dados composta, a próxima etapa é obter a lista de todos os mínimos de todos os subconjuntos, escolher aquele com o carimbo de data / hora mais antigo e remover e retornar este objeto.

rwong
fonte
Infelizmente, não vejo como encontrar com eficiência a lista de objetos comparáveis.
Conjunto parcialmente ordenado pode realmente ser visto como gráfico acíclico direcionado. Mas um dado pela tabela de adjacência (função, na verdade), em vez da lista de adjacência. Encontrar mínimos de poset dados pela lista de adjacências é fácil, mas para a tabela de adjacências é um problema.
Os mínimos também são bem definidos no conjunto original. Não vejo como encontrar os componentes conectados poderia ajudar, pois eles não são gráficos completos.
1
Parece que você supõe que o diagrama de Hasse é uma floresta de árvores unárias (gráficos de caminho equivalentes), mas a pergunta já afirma que é uma ordem de produto, portanto uma rede multidimensional.
Peter Taylor
0

Um projeto em que estou trabalhando envolve um problema semelhante (aliás, também estou usando a ordem parcial de vetores). Já tínhamos um algoritmo de tempo quadrático para classificar uma lista ordenada aleatoriamente, e desenvolvi um algoritmo de inserção observando seu comportamento quando apenas um objeto estava fora de ordem. Não sabemos se essa é a implementação mais rápida possível.

Aqui está algum pseudocódigo.

class PartialOrderPriorityQueue
   q <- empty list
   method insert (n):
     for i <- 0 to (q.length - 1):
       if q[i] <= n:
         t <- q[i]
         q[i] <- n
         n <- t
     q.append(n)

   method pop():
     return q.remove(0)
Jeremy List
fonte
-1

O comportamento usual da pilha é anexar o novo valor à parte traseira e, em seguida, peneirar enquanto ele compara maior que o pai.

Se você escrever uma comparação que retorne o mesmo para o pai e o filho não é um caso comparável , pois o pai é maior que o filho , a peneiração ainda deve terminar no ponto certo.

Isso conta como um pedido suficientemente estável para seus propósitos?


Para esclarecer, tomar o exemplo do seu comentário: a> b e c não é comparável a um ou b :

  • a então b então c => a, b, c ... isso já está em ordem de pilha e nada se move na peneiração
  • b, a, c => a, b, c ... a é peneirado no lugar correto e, novamente, estamos na ordem correta da pilha
  • a, c, b => a, c, b ... b não pode filtrar porque não é comparável com c, mas isso os deixa na ordem FIFO, como você pediu
  • c, b, a => c, a, b ... aeb estão na ordem relativa correta, mas nenhum deles pode se antecipar a c porque não pode ser comparado a ele

portanto, o resultado depende da ordem de inserção - isso parece corresponder ao que você solicita, mas não tenho certeza se é realmente o que você deseja. Caso contrário, você poderia mostrar o resultado que esperava ver?


OK, então, a partir do seu comentário (e da edição da sua pergunta), você deseja que elementos "comparáveis" ultrapassem os "não comparáveis" e encontre o local correto sob a ordem, se houver um. Eu perguntei sobre isso, porque eu não tinha certeza de como interpretar

se alguns elementos são incomparáveis, ele os retorna na ordem em que foram inseridos

(d e b são incomparáveis ​​aos pares na sua edição, mas você não os deseja na ordem em que foram inseridos).

Minha próxima pergunta seria sobre a relação entre os elementos "comparáveis" e "não comparáveis", mas vejo que você revelou agora que são vetores em ordem de produto (não ficou claro se alguns elementos eram pareados) incomparável com tudo , como NaN, ou o que).

Portanto, se eu pegar seu novo exemplo e atribuir valores de vetor, é correto que este seja um exemplo em que b não seja comparável a qualquer outra coisa:

        a (1,1)
      /      \
    b (0,4)   c (3,3)
  /
d (2,2)

e deve classificar para isso:

        a (1,1)
      /      \
    d (2,2)   c (3,3)
  /
b (0,4)

?

Sem utilidade
fonte
Mencionei explicitamente na pergunta que não funcionará, porque pensei ter um contra-exemplo, mas não tenho tanta certeza agora. Você pode provar que essa fila seria adequada (para excluir, inserir e atualizar também)? E lembre-se de que é possível que a ≤ b , mas c não seja comparável (e, portanto, compare "igual" com a regra acima) a qualquer um deles.
Bem, isso ainda não é prova. Não se preocupe com o pedido ainda e comprove que esse heap sempre tem um elemento mínimo no topo (nota: (mais) convenção comum e a necessidade real do algoritmo é mínima no topo, portanto, se a> b , b vier primeiro )
Na verdade, suspeito que exista um contra-exemplo. Suponha que um , b e c são na pilha, um ≤ b e um ≤ c , um é alto, b é filho esquerdo, c é filho direito. Agora vem d que ≤ ce incomparável com a e b . É inserido como filho de b , não é menor e fica lá. Agora vem e que é c ≤ e (assim também a ≤ e ) e incomparável a b . Então e entra como filho certo de be fica. Agora extraia um (OK, a é mínimo), e é trocado no lugar e peneirado. É incomparável a b , mas menor que c , então troca com c . Agora extraia c , ERRADO , d ≤ c .
Se você encontrar um erro no comentário anterior (que precisaria ter uma forma de desigualdade que deve ser mantida por causa da transitividade e eu perdi), você ainda teria uma chance. Caso contrário, não funcionará.
1
Ok, contra-exemplo ainda mais simples. Suponhamos que um , b e c são na pilha, uma ≤ c , b é incomparável com qualquer um. a é superior, b é filho esquerdo, c é filho direito. d entra de modo que d ≤ a (portanto d ≤ c ) e incomparável com b . Próximo slot livre é como filho esquerdo de b e d é incomparável, então ele permanece lá. Agora extraia a , ERRADO , d ≤ a . Observe que se a ≤ cou não, não importa, a situação é a mesma se forem incomparáveis.