Résolution de la relation de récurrence avec deux appels récursifs

10

J'étudie le pire cas d'exécution de quicksort à la condition qu'il ne fasse jamais une partition très déséquilibrée pour différentes définitions de très .

Pour ce faire, je me pose la question de savoir quel serait le runtime dans le cas où quicksort arrive toujours à partitionner en une fraction telle que éléments sont dans la partition gauche et sont dans la partition droite (laissant élément, le pivot, au milieu).T ( n , p ) T(n,p)0 < p 120<p12p(n-1)p(n1)(1-p)(n-1)(1p)(n1)11

Il ne devrait pas être difficile de voir que donne une limite supérieure pour le pire des cas où est la partition autorisée au maximum déséquilibrée, car toute partition avec une fraction sera plus équilibrée et aura un temps d'exécution plus petit, et toute fraction n'est pas autorisée.T ( n , p ) T(n,p)p p> p >p< p<p

Il est évident que est le meilleur des cas et est le pire des cas de tri rapide. Les deux ont des relations de récurrence faciles que l'on trouve dans n'importe quelle ressource éducative. Mais je ne sais pas comment étudier en général. La relation évidente serait:T ( n , 12 )T(n,12)T(n,0)T(n,0)T(n,p)T(n,p)

T(n,p)=n+T(p(n1),p)+T((1p)(n1),p)

T(n,p)=n+T(p(n1),p)+T((1p)(n1),p)

Ici, je suis coincé. J'ai essayé de chercher autour, mais toute la littérature que je pouvais comprendre sur les algorithmes de division et de conquête a pris la "division" littéralement et "trompé" l'analyse en utilisant le fait que les partitions sont toujours de taille égale, fusionnant les termes en une fois par constant.

Je ne sais pas comment gérer deux appels récursifs et je ne sais pas s'il est sûr de supprimer l'arrondi. Est-ce possible de résoudre analytiquement, et si oui, comment?

PS: je ne suis pas intéressé par les asymptotiques (ce qui est facile à montrer pour toute constante ). Je suis intéressé par le ralentissement du tri rapide à mesure que p diminue, par exemple, je suis intéressé par le rapport T (n, 0,25) \ sur T (n, 0,5) .Θ(nlogn)Θ(nlogn)ppppT(n,0.25)T(n,0.5)T(n,0.25)T(n,0.5)

PPS: En tant qu'étudiant de premier cycle, je m'excuse si j'ai fait des choses évidentes trop longues ou non triviales. Et même si je ne sais pas si cela est regardé ici autant que d'autres sites SE, je noterai que c'est un intérêt personnel, pas des devoirs.

orlp
la source

Réponses:

9

Comme vous le mentionnez, le théorème d'Akra – Bazzi montre que la solution à la récurrence est pour tout . Cependant, cela ne révèle pas la nature de la dépendance à l'égard de . Pour déterminer ce dernier, nous pouvons utiliser une approche d'arbre de récursivité.T ( n , p ) O ( n log n ) p ( 0 , 1 ) pT(n,p)O(nlogn)p(0,1)p

À la racine de l'arbre de récursivité se trouve l'intervalle . Ses deux enfants sont les intervalles et , dont la longueur totale est à nouveau . Chacun de ces nœuds a deux enfants (en supposant que est suffisamment grand), et ainsi de suite. Pour simplifier, nous ignorons les erreurs d'arrondi, c'est-à-dire que nous supposons que est un entier; c'est juste une technicité, et je ne m'en inquiéterais pas. Nous arrêtons le processus chaque fois qu'un nœud a une longueur maximale de . La complexité de l'algorithme est proportionnelle à la longueur totale des intervalles dans l'arbre. Lorsque , les feuilles{ 1 , n } { 1 , , p n } { p n + 1 , , n }{1,n}{1,,pn}{pn+1,,n} n n p n 1 p 1 / 2nnpn1p1/2 (nœuds où nous arrêtons le processus) ont une profondeur différente, ce qui rend plus difficile la détermination de la complexité globale.

On peut obtenir une borne supérieure simple en notant que l'arbre a au plus des niveaux : chaque nœud est au moins un facteur plus petit que son parent. Tout comme dans l'analyse pour , la longueur totale des intervalles à n'importe quel niveau est au plus , et nous obtenons une limite supérieure de sur la temps de course. Puisque et pour les petits , nous pouvons écrire ceci comme .log 1 - p ( 1 / n ) 1 - p p = 1 / deux n O ( n log 1 - p ( 1 / n ) ) log 1 - p ( 1 / n ) = log n / log ( 1 - p ) - 1 journal ( 1 - p ) - 1log1p(1/n)1pp=1/2nO(nlog1p(1/n))log1p(1/n)=logn/log(1p)1= - log ( 1 - p ) = p ± O ( p 2 ) p O ( n log n / p )log(1p)1=log(1p)=p±O(p2)pO(nlogn/p)

Voici un calcul plus précis. Considérez le niveau . Supposons que nous n'arrêtons pas le processus en atteignant un petit intervalle. Nous pouvons générer un sommet aléatoire en prenant étapes, dans chacune desquelles nous allons à gauche (disons) avec la probabilité et à droite (disons) avec la probabilité . Chaque fois que nous faisons un pas à gauche, le log de la longueur de l'intervalle diminue de , et chaque fois que nous faisons un pas à droite, il diminue de . Un sommet se trouve dans l'arborescence réelle du log de la longueur diminuée d'au plus . Le poids total des intervalles au niveaut t p 1 - p - log p - log ( 1 - p ) log n t log n D - log p p - log ( 1 - p ) 1 - p X 1 , , X tD t Pr [ X 1 + + X tlog n ] tttp1plogplog(1p)logntde l'arbre est exactement la probabilité qu'un sommet généré selon ce processus corresponde à une diminution d'au plus . Autrement dit, si est la distribution qui est égale à avec la probabilité et à avec la probabilité , et sont indépendants, alors le le poids total du niveau est . Pour super-constante , la variable aléatoire est à peu près normale de moyenne et la variance linéairelogn- journalpp- journal( 1 - p )1 - pX1, , XtDtPr [ X1+ + Xtlogn ]t X 1 + + X t [ - p log p - (X1+ + Xt 1 - p ) log ( 1 - p ) ] t t t [ - p log p - ( 1 - p ) log ( 1 - p ) ] t ( log n ) / 2 1 t [ - p log[ - p logp - ( 1 - p ) log(1p)]tt, donc pour satisfaisant , disons, la probabilité sera très proche de , tandis que pour satisfaisant , par exemple, il sera très proche de zéro. En définissant (connu sous le nom de fonction d'entropie binaire), nous concluons que le temps d'exécution est (uniforme en , comme ). Comme nous avons , et donc notre estimation précédente n'était pas serrée.t[plogp(1p)log(1p)]t(logn)/21tp - ( 1 - p ) log ( 1 - p ) ] t 2 log n h ( p ) = - p log p - ( 1 - p ) log ( 1 - p ) Θ ( n log n / h ( p ) ) p n p 0 h ([plogp(1p)log(1p)]t2lognh(p)=plogp(1p)log(1p)Θ(nlogn/h(p))pnp0p ) - p log ph(p)plogp

Une autre façon de voir la même analyse consiste à avoir une séquence infinie de variables aléatoires indépendantes comme précédemment, et à définir un temps d'arrêt comme étant la première fois tel que . Le temps d'exécution est alors proportionnel à . Le théorème de renouvellement élémentaire déclare alors que , ce qui implique que le la taille totale des intervalles est égale à . Plus précisément, pour chaque constante la taille totale des intervalles est , oùX 1 , X 2 , T t X 1 + + X tlog n n E [ T ]X1,X2,TtX1++XtlognnE[T]lim n E [ T ] / log n = 1 / E [ D ] = 1 / h ( p ) ( 1 + o ( 1 ) ) n log n / h ( p ) p ( 1 + α p ( n ) ) n log n / h ( p ) αlimnE[T]/logn=1/E[D]=1/h(p)(1+o(1))nlogn/h(p)p(1+αp(n))nlogn/h(p)p ( n ) = o ( n )αp(n)=o(n) . La convergence dans le théorème de renouvellement élémentaire est exponentielle dans le paramètre de temps - dans notre cas - devrait donc être polynomiale dans , c'est-à-dire . La convergence est également probablement uniforme pour pour tout .log n n α p ( n ) = O ( n - C p ) p ( δ , 1 - δ ) δ > 0lognnαp(n)=O(nCp)p(δ,1δ)δ>0


En résumé, la longueur totale des intervalles dans l'arbre de récursivité, qui est proportionnelle au temps d'exécution, est de la forme suivante pour chaque : où et sont pris à la même base et est une fonction dépendant de et tendant vers avec .p T ( n , p ) = ( 1 + o ( 1 ) ) n log nph ( p ) ,lognh(p)=-plogp-(1-p)log(1-p)o(1)p0n

T(n,p)=(1+o(1))nlognh(p),
lognh(p)=plogp(1p)log(1p)o(1)p0n

De plus, il est probablement vrai que pour tout et tout il est vrai que la longueur totale des intervalles est de la forme où et la grande constante O cachée ne dépendent que de . En particulier, il devrait être le cas pour toutes les constantes , et la convergence est polynomialement rapide.δ>0δ>0p(δ,1δ)p(δ,1δ)T(n,p)=(1+O(nCδ))nlognh(p),

T(n,p)=(1+O(nCδ))nlognh(p),
Cδ>0Cδ>0δδp1,p2p1,p2limnT(n,p1)T(n,p2)=h(p2)h(p1),
limnT(n,p1)T(n,p2)=h(p2)h(p1),
Yuval Filmus
la source
Merci pour votre réponse rapide Yuval. Je suis un peu troublé par le fait que vous ayez utilisé dans votre résumé. est une constante, et cela ne signifie-t-il pas que ce n'est pas pertinent sous ? J'ai décidé d'écrire un petit programme de test , qui a montré que pour comparaison de entre la méthode analytique et une méthode informatique donnait une erreur de 0,03. Cela semble assez important, ou est-ce à prévoir? ΘΘh(p)h(p)ΘΘn=100000000000000n=100000000000000T(n,0.1)/T(n,0.5)T(n,0.1)/T(n,0.5)
orlp
La constante dans le est uniforme en . Plus précisément, pour certaines constantes il se trouve que pour chaque il existe tel que pour , . Vous pouvez probablement obtenir une déclaration encore plus forte de la forme pour chaque fixe , où le petit o est par rapport à ( mais pourrait dépendre de ); ne devrait pas dépendre de . ΘΘppc,Cc,CppNpNpnNpnNpcnlogn/h(p)T(n,p)Cnlogn/h(p)cnlogn/h(p)T(n,p)Cnlogn/h(p)T(n,p)=(1+o(1))Cnlogn/h(p)T(n,p)=(1+o(1))Cnlogn/h(p)ppnnppCCpp
Yuval Filmus
La convergence vers la limite dépend de , donc vous aurez peut-être besoin de pour être grand afin d'obtenir une très bonne approximation. D'un autre côté, une erreur relative de 0,03 ne semble pas si importante. Vous pouvez essayer de fixer et de tracer le temps de course en fonction de , en le comparant à . lognlognlognlognnnpp1/h(p)1/h(p)
Yuval Filmus
Oh, je suis désolé, je ne voulais pas une erreur relative de 0,03, mais une erreur absolue (2.13222 vs 2.10339). Le tracé de en fonction de , par rapport à donné une différence relative de 4%, avec étant 96% de . T(n,p)p1/h(p)T(1011,0.05)h(0.05)T(1011,0.4)h(0.4)
orlp
1
La super-constante est une fonction tendant vers l'infini par rapport à la variable pertinente (dans ce cas ). C'est la même chose que . nω(1)
Yuval Filmus