J'ai quelques objets avec priorité qui sont de type composé et qui ne sont que partiellement ordonnés . Je dois sélectionner les objets dans l'ordre de cette priorité (c.-à-d. Produire un élément minimal à chaque fois). Mais plutôt que de terminer arbitrairement la commande, je préférerais que la file d'attente soit stable en ce sens que s'il y a plus d'un élément minimal, il devrait renvoyer le plus ancien en premier.
Existe-t-il une structure de données de tas qui fonctionnerait avec un ordre partiel? Ou une modification de la file d'attente prioritaire régulière pour fonctionner avec elle? Le choix commun pour l'algorithme dont j'ai besoin est un tas binaire simple ou 4-aires, mais cela ne fonctionne pas avec un ordre partiel.
Les valeurs de priorité prennent en charge:
- partiel à l'aide de l'opération . Il s'agit d'un ordre partiel, il est donc possible que a \ preccurlyeq b soit faux et b \ preccurlyeq a soit également faux. J'écris un \ not \ lesseqgtr b dans ce cas.a ≼ ba ⋚ ̸ b
- Trouver infima (glb) et suprema (lub). est le y maximal tel que . Le calcul de l'infimum de valeurs prend du temps . Infimum (et supremum) de chaque ensemble existe.
- Une extension linéaire pour l'ordre partiel pourrait être définie. L'utiliser pour la file d'attente prioritaire est la solution la plus simple car l'algorithme fonctionne de cette façon. Mais l'ordre affecte les performances et l'ordre d'insertion semble être le meilleur pour éviter les pires cas.
De plus, l'algorithme dans lequel je veux l'utiliser doit connaître l'infimum de toutes les priorités dans la file d'attente.
Les priorités ont une signification concrète, mais sont sujettes à changement, il ne semble donc pas viable de s'appuyer sur d'autres propriétés qu'elles pourraient avoir.
Remarque: les tas binaires ne fonctionnent pas avec un ordre partiel. Supposons un tas binaire avec , et , où et et . Ils sont positionnés dans cet ordre, donc
a (0)
/ \
b (1) c (2)
maintenant d est inséré. La prochaine position libre est 3, l'enfant gauche de , donc nous obtenons
a (0)
/ \
b (1) c (2)
/
d (3)
Si (ce qui implique de transitivité, mais ne dit rien sur et ) et , alors n'est pas échangé avec , car ce n'est pas moins. Mais il est en fait inférieur à , mais il n'est pas comparé à lui, donc maintenant l'invariant du tas principal ne tient pas; le sommet n'est pas minimal.d ≼ c d b d ⋚ ̸ b d b
Je soupçonne qu'une forêt de tas quelque peu dans le style d'un tas binomial pourrait être mise en place. Fondamentalement, il est important de toujours comparer les nouvelles valeurs avec root et de ne lier que des éléments comparables. Cela rendrait les arbres de la forêt de taille aléatoire et rendrait ainsi la complexité dépendante du nombre d'ensembles mutuellement incomparables dans le tas. Je soupçonne quelque peu que la complexité ne peut pas être corrigée (nous devons continuer à comparer jusqu'à ce que nous atteignions un élément comparable) J'ai peut-être manqué quelque chose, alors je laisse cela ouvert.
Remarque: l'ordre est partiel et bien qu'il existe des moyens de lui définir des extensions linéaires, l'ajout d'un horodatage et son utilisation comme critère secondaire n'en fait pas partie. Supposons que nous ayons affecté l'horodatage pour chaque et défini l'ordre comme ssi ou ( et . Supposons alors que nous ayons , , distincts , tels que et . Alors eta ≼ ′ a ≼ ′ b a ≼ b b ⋠ a t ( a ) ≤ t ( b ) a b c t ( a ) ≤ t ( b ) ≤ t ( c ) c ≤ a a ≼ ′ b b ≼ ′ c c ≼ ′ a , mais , donc la relation n'est pas transitive et n'est donc pas du tout un ordre. Ce type d'extension ne fonctionne que pour les commandes faibles, mais pas partielles.
Edit: je me suis rendu compte que non seulement l'infimum d'un ensemble était défini, mais que je devais en fait pouvoir obtenir efficacement l'infimum des éléments actuellement dans la file d'attente. Donc, je me demande maintenant si l'ajout de nœuds spéciaux contenant des infima de sous-arbres à une structure de tas commune serait utile.
la source
Réponses:
Bien que le problème exact posé dans la question d'origine semble être difficile (et je serais intéressé par une solution à ce problème, en particulier la partie de recherche d'infima). Je voulais juste noter que si l'ensemble partiellement ordonné se compose en effet de vecteurs utilisant une commande de produit, et s'il suffit d'avoir la garantie que la file d'attente prioritaire renvoie les valeurs dans un ordre "compatible" avec l'ordre partiel ( c'est-à-dire que les éléments plus petits sont toujours renvoyés avant les éléments plus grands), il existe alors un moyen assez simple de le faire.
L'idée est essentiellement de trouver un ordre topologique de l'ensemble partiellement ordonné. Autrement dit, un ordre total ' ' tel que . Pour les vecteurs utilisant une commande de produit, cela est assez simple: utilisez simplement un ordre lexicographique ' ', où le premier "composant" est la somme de tous les composants utilisés pour la commande de produit (les autres composants sont essentiellement arbitraires, vous pouvez donc vous en tenir à un ordre faible). On peut alors voir que et a ≤ b≤T ≤ S a < ba≤b⟹a≤Tb ≤S a = b
la source
Quel est le problème avec la finalisation de votre commande partielle?
Si vous préférez «le plus ancien d'abord», alors votre commande est effectivement terminée; les articles «incomparables» sont comparables selon l'âge.
Ajoutez un horodatage (ou tout autre entier à croissance monotone) à chaque élément et utilisez-le si une comparaison «réelle» est impossible.
la source
EDIT: cela semble être un problème intéressant, et j'ai eu quelques recherches à ce sujet. Je vous suggère de lire ce qui suit:
Je vous suggère de lire cet article: Daskalakis, Constantinos, et al. "Tri et sélection en posets." SIAM Journal on Computing 40.3 (2011): 597-622.
Les auteurs présentent ici une structure de données appelée ChainMerge qui accepte un poset et une décomposition en chaîne du poset en chaînes. La taille de la structure de données est O ( n q ) . Les auteurs présentent un algorithme pour trouver les minimas qui s'exécutent dans O ( w n ) où w est une limite supérieure sur la largeur du poset. .. J'ai pensé que c'était peut-être intéressant.q O(nq) O(wn) w
Remarque: j'ai supprimé une réponse naïve précédente. Veuillez cliquer sur modifier pour le voir.
la source
Mon utilisation de la terminologie peut être incorrecte. Veuillez modifier ma réponse directement pour résoudre les problèmes que vous rencontrez.
Premièrement, des ensembles mutuellement incomparables doivent être détectés à partir des entrées.
Par exemple, il peut y avoir 5 objets
a, b, c, d, e
, mais leur ordre partiel forme deux graphiques déconnectés:a ≤ b ≤ c
d ≤ e
{a, b, c}
est incomparable avec aucun{d, e}
.Ces ensembles mutuellement incomparables doivent d'abord être détectés, avant que les objets puissent être stockés dans une structure de données appropriée. Cela peut être fait avec un algorithme de recherche Union
Pour être efficace, l'insertion d'un nouvel objet doit avoir un moyen efficace de trouver "la liste des objets existants qui sont comparables avec ce nouvel objet".
Maintenant, au sein de chaque sous-ensemble (respectivement
{a, b, c}
et{d, e}
), les minima doivent être bien définis. (Pour chaque sous-ensemble, il peut y avoir un ou plusieurs minima, en raison d'une commande partielle.)Je vois cela comme un graphique acyclique dirigé . Essayer de l'intégrer dans un tas semble désastreux.
Pour extraire les minima de cette structure de données composite, l'étape suivante consiste à obtenir la liste de tous les minima de tous les sous-ensembles, de choisir celui avec l'horodatage le plus ancien, de supprimer et de renvoyer cet objet.
la source
Un projet sur lequel je travaille implique un problème similaire (d'ailleurs, j'utilise également l'ordre partiel des vecteurs). Nous avions déjà un algorithme temporel quadratique pour trier une liste ordonnée de façon aléatoire, et j'ai développé un algorithme d'insertion en observant son comportement lorsqu'un seul objet était en panne. Nous ne savons pas si c'est la mise en œuvre la plus rapide possible.
Voici un pseudocode.
la source
Le comportement de segment de mémoire habituel consiste à ajouter la nouvelle valeur à l'arrière, puis à passer au crible pendant qu'elle se compare plus que son parent.
Si vous écrivez une comparaison qui retourne la même chose pour le parent et l'enfant ne sont pas des cas comparables car pour le parent est supérieur à l'enfant , le tri devrait toujours se terminer au bon point.
Est-ce que cela compte comme une commande suffisamment stable pour vos besoins?
Pour clarifier, prenez l'exemple de votre commentaire: a> b , et c n'est pas comparable à a ou b :
donc, le résultat dépend de l'ordre d'insertion - cela semble correspondre à ce que vous demandez, mais je ne sais pas si c'est vraiment ce que vous voulez. Si ce n'est pas le cas, pourriez-vous montrer le résultat que vous espériez voir?
OK, donc à partir de votre commentaire (et de la modification de votre question), vous voulez que les éléments "comparables" dépassent ceux "non comparables" et trouvent le bon endroit sous la commande, s'il y en a un. J'ai posé des questions à ce sujet parce que je ne savais pas comment interpréter
(d et b sont deux par deux incomparables dans votre montage, mais vous ne les voulez pas dans l'ordre où ils ont été insérés).
Ma prochaine question aurait porté sur la relation entre les éléments "comparables" et "non comparables", mais je vois que vous avez maintenant révélé qu'ils sont des vecteurs dans l'ordre des produits (il n'était pas clair si certains éléments étaient appariés- incomparable avec tout , comme NaN, ou quoi).
Donc, si je prends votre nouvel exemple et que j'assigne des valeurs vectorielles, est-il exact que c'est un exemple où b n'est comparable à rien d'autre:
et il devrait trier ceci:
?
la source