Je réfléchis au problème suivant depuis un certain temps et je n'ai pas trouvé de solution polynomiale pour cela. Uniquement source brute. J'ai essayé de réduire également un problème NP-Complete sans succès.
Voici le problème :
Vous avez un ensemble trié de paires d'entiers positifs.
L'opération suivante peut être appliquée à une paire: Swap(pair)
. Il échange les éléments de la paire, donc deviendra
Lorsqu'une paire de l'ensemble est échangée, l'ensemble est automatiquement trié à nouveau (la paire échangée n'est pas à sa place et elle sera déplacée à sa place dans l'ensemble).
Le problème consiste à voir s'il existe une séquence qui, à partir d'une paire, permute l'ensemble entier, avec la condition suivante:
Après l'échange d'une paire, la paire suivante à échanger doit être soit le successeur soit la paire de prédécesseurs de l'ensemble.
Ce serait formidable de trouver une solution temporelle polynomiale à ce problème, ou une réduction d'un problème NP-Complete.
Remarque:
C'est déjà un problème de décision. Je ne veux pas savoir quelle est la séquence: seulement si une séquence existe.
Exemple de tri de l'ensemble après échange d'une paire
Si j'échange la première paire, cela devient: , et après avoir trié l'ensemble (en plaçant la paire triée dans sa nouvelle position), nous avons:
Ensuite, je dois échanger la paire (prédécesseur) ou (successeur), et répéter le processus jusqu'à ce que toutes les paires soient échangées (si possible).
Important:
vous ne pouvez pas échanger une paire déjà échangée.
S'il y a une séquence d'opérations de «permutation», alors toutes les paires doivent être renommées une fois et une seule fois.
Exemple où il n'est pas possible d'échanger toutes les paires
( 1 , 4 ) ( 3 , 2 ) ( 5
la source
Réponses:
... J'ai cherché quelques modèles pour construire une réduction à partir d'un problème de PNJ, mais je n'ai pas trouvé un moyen de représenter un "flux" avec un "fork" ...
Donc (après quelques travaux) c'est un algorithme polynomial ...
ALGORITHME
La liste de départ peut être vue comme un tableau de " trous " consécutifs . Pour chaque paire initiale ( a j , b j ) , mettez "l' élément " b j au numéro de trou a j . Chaque paire peut être considérée comme un bord dirigé de la position a j à la position b j . Un mouvement consiste à ramasser un élément b j à la position a j et à le déplacer vers sa position de destination b jN∗ 2 ( unj,bj) bj aj aj bj bj aj bj (le trou de destination devient une cheville inamovible ). Nous supprimons l'arête et choisissons le mouvement suivant qui commencera à partir de l'un des deux éléments accessibles les plus proches depuis la position b j (seuls les trous entre b j et b k sont autorisés). Il faut trouver une séquence de N coups consécutifs.bk bj bj bk N
Pour chacun considérons b j (à la position du tableau a j ) comme élément de départ s t a r t .(aj,bj) bj aj start
Pour chacun considère a k comme l'élément final e n d (le bord de la position a k à la position b k sera le bord final).(ak,bk),ak≠aj ak end ak bk
Lorsque vous effectuez un mouvement, vous fixez une cheville à la position et le tableau est divisé en deux partitions L (gauche) et R (droite) et la seule façon de passer de L à R (ou de R à L ) est d'utiliser un bord qui saute à travers la cheville. Ensemblebj L R L R R L
Cas:
A) si puis l'une des deux partitions deviendra inaccessible, arrêtez|flow|>1
Supposons maintenant que , c'est-à-dire e n d ∈ Rend>bj end∈R
B) si alors il y a un bord supplémentaire de gauche à droite, vous devez aller à gauche (choisir l'élément le plus proche de L ), sinon vous n'atteindrez jamais e n dflow=1 L end
C) si alors il y a un bord supplémentaire de droite à gauche et quel que soit le nœud que vous choisissez, vous n'atteindrez jamais e n d , arrêtezflow=−1 end
D) si vous devez aller à droite (choisir l'élément le plus proche de R ), sinon vous n'atteindrez jamais e n dflow=0 R end
Si ( e n d ∈ L ), B, C, D sont inversés.end<bj end∈L
REMARQUE: lorsque vous vous déplacez vers la gauche ou la droite, vous devez considérer comme une cheville. Par exemple, si vous devez aller à droite, mais l'élément le plus proche sur R est e n d alors le mouvement est impossible (et vous devez procéder avec une autre paire ( s t a r t , e n d ) )end R end (start,end)
Appliquez la même résonance à chaque mouvement.
COMPLEXITÉ
Les flux sur chaque trou peuvent être précalculés en O (N) et réutilisés à chaque balayage.
Les boucles sont:
Aucun choix n'est fait lors du calcul, donc la complexité de l'algorithme estO(N3)
CODE
Il s'agit d'une implémentation Java fonctionnelle de l'algorithme:
la source
Ce n'est pas une solution, mais une reformulation qui évite de mentionner explicitement les opérations de swapping et de tri. Commencez par trier la liste combinée complète des noms de fichiers et leurs versions échangées, et identifiez chaque nom de fichier avec son index dans cette liste. Ensuite, deux fichiers sont voisins si tous les anciens noms de fichiers entre eux ont déjà été détruits et si aucun des nouveaux noms de fichiers entre eux n'a encore été créé. Le problème reformulé est le suivant:
Etant donné un ensemble de arêtes orientées disjoints ( a , b ) avec un , b ∈ { 1 , 2 , ... , 2 n } , est - il un ordre ( a 1 , b 1 ) , ( a 2 , b 2 ) , . . . , ( a n , b n ) de ces arêtes telles quen (a,b) a,b∈{1,2,…,2n} (a1,b1),(a2,b2),...,(an,bn)
la source