comment calculer la complexité de la recherche binaire

144

J'ai entendu quelqu'un dire que puisque la recherche binaire divise par deux l'entrée requise pour la recherche, c'est donc l'algorithme log (n). Comme je ne suis pas d'origine mathématique, je ne suis pas en mesure de m'y rattacher. Quelqu'un peut-il l'expliquer un peu plus en détail? doit-il faire quelque chose avec la série logarithmique?

Lapin
la source
1
cela pourrait vous aider: stackoverflow.com/a/13093274/550393
2cupsOfTech

Réponses:

385

Voici une façon plus mathématique de le voir, mais pas vraiment compliqué. IMO beaucoup plus clair que les informels:

La question est, combien de fois pouvez-vous diviser N par 2 jusqu'à ce que vous en ayez 1? Cela signifie essentiellement, effectuez une recherche binaire (la moitié des éléments) jusqu'à ce que vous l'ayez trouvé. Dans une formule, ce serait ceci:

1 = N / 2 x

multipliez par 2 x :

2 x = N

maintenant, faites le journal 2 :

log 2 (2 x ) = log 2 N
x * log 2 (2) = log 2 N
x * 1 = log 2 N

cela signifie que vous pouvez diviser le journal N fois jusqu'à ce que tout soit divisé. Ce qui signifie que vous devez diviser le journal N ("faire l'étape de recherche binaire") jusqu'à ce que vous trouviez votre élément.

duedl0r
la source
Je viens de le calculer en t (n) = (2 ^ 2) * K. comment faire pour se connecter au formulaire?
Shan Khan
1
le même concept expliqué graphiquement: stackoverflow.com/a/13093274/550393
2cupsOfTech
La partie qui me manque est, si vous avez un BST avec 7 entrées, quelle est sa formule? log2 (7)? J'ai fait un calcul de force brute avec tous les résultats possibles et suis arrivé à une réponse qui n'était pas égale à log2 (7), alors qu'est-ce que je fais de mal?
Perry Monschau
1
Tellement plus facile que l'explication de l'arbre binaire.
NoName
1
Très belle réponse
VHS
22

Pour la recherche binaire, T (N) = T (N / 2) + O (1) // la relation de récurrence

Appliquer le théorème de maîtrise pour le calcul de la complexité d'exécution des relations de récurrence: T (N) = aT (N / b) + f (N)

Ici, a = 1, b = 2 => log (une base b) = 1

aussi, ici f (N) = n ^ c log ^ k (n) // k = 0 & c = log (une base b)

Donc, T (N) = O (N ^ c log ^ (k + 1) N) = O (log (N))

Source: http://en.wikipedia.org/wiki/Master_theorem

résuméKarshit
la source
1
pourquoi log (une base b) est 1 quand a = 1 et b = 2, ne devrait-il pas être 0?
GAURANG VYAS
16

T (n) = T (n / 2) +1

T (n / 2) = T (n / 4) + 1 + 1

Mettez la valeur de The (n / 2) ci-dessus pour que T (n) = T (n / 4) + 1 + 1. . . . T (n / 2 ^ k) + 1 + 1 + 1 ..... + 1

= T (2 ^ k / 2 ^ k) + 1 + 1 .... + 1 jusqu'à k

= T (1) + k

Comme nous avons pris 2 ^ k = n

K = log n

La complexité du temps est donc O (log n)

Dhiren Biren
la source
10

Ce n'est pas la moitié du temps de recherche, cela ne le ferait pas enregistrer (n). Il le diminue de manière logarithmique. Pensez à cela pendant un moment. Si vous aviez 128 entrées dans une table et que vous deviez rechercher votre valeur de manière linéaire, il faudrait probablement environ 64 entrées en moyenne pour trouver votre valeur. C'est n / 2 ou temps linéaire. Avec une recherche binaire, vous éliminez la moitié des entrées possibles à chaque itération, de sorte qu'au plus il ne faudrait que 7 comparaisons pour trouver votre valeur (la base log 2 de 128 est 7 ou 2 à la puissance 7 est 128.) C'est la puissance de la recherche binaire.

Michael Dorgan
la source
Désolé pour le necropost mais 128 n'est pas un arbre uniformément rempli. J'ai utilisé un exemple de base pour comprendre cela, et j'ai trouvé que 7 entrées remplissent uniformément un arbre avec 3 couches. J'ai calculé que la complexité devrait être de 17/7 (la moyenne de la somme totale des comparaisons) qui est de 2,43. Mais log2 (7) est 2,81. Alors qu'est-ce que je manque ici?
Perry Monschau
Deux réponses - Première ici: Même s'il n'y a pas d'erreur dans les mathématiques, nous pouvons voir que la moyenne de 2,43 est toujours meilleure que la moyenne de 3,5 pour linéaire, et c'est à une valeur faible. Une fois que vous entrez dans les centaines d'entrées, log2 () est bien meilleur que linéaire. Je pense que vous voyez cela cependant, ainsi de suite.
Michael Dorgan
1
Deuxième réponse: je ne sais pas quel type d'arbre vous avez où tout est rempli. Quand je pense à un arbre parfait de 8 entrées, je vois un arbre profond de 3 niveaux avec 8 feuilles au total. Dans cet arbre, quel que soit le nombre que vous recherchez, il faut 3 comparaisons au total pour aller de la racine à la feuille. Pour 7 entrées, l'un des chemins prendrait une comparaison de moins, donc 20/7 (6 nœuds de 3 comparaisons, 1 nœud de 2 comparaisons), soit ~ 2,85. Log2 (7) est ~ 2,81. Je n'ai pas les connaissances en mathématiques pour expliquer la différence de .04, mais je suppose que cela a à voir avec le fait de ne pas avoir de bits fractionnaires disponibles ou une autre magie :)
Michael Dorgan
le nombre est le nombre de feuilles !? Pas le nombre de nœuds? Eh bien, c'était une grosse information qui me manquait .. Cela me semble étrange que la fonction soit basée sur des feuilles, alors que chaque nœud de branchement est également un point d'arrêt potentiel. Eh bien de toute façon, merci de redresser cela pour moi!
Perry Monschau
5

La complexité temporelle de l'algorithme de recherche binaire appartient à la classe O (log n). On appelle cela grande notation O . La façon dont vous devez interpréter cela est que la croissance asymptotique du temps que la fonction prend pour s'exécuter étant donné un ensemble d'entrée de taille n ne dépassera paslog n .

Ceci est juste un jargon mathématique formel afin de pouvoir prouver des déclarations, etc. Il a une explication très simple. Lorsque n devient très grand, la fonction log n augmentera plus le temps nécessaire pour exécuter la fonction. La taille du "jeu d'entrées", n, est juste la longueur de la liste.

En termes simples, la raison pour laquelle la recherche binaire est en O (log n) est qu'elle divise par deux le jeu d'entrées à chaque itération. Il est plus facile d'y penser dans la situation inverse. Sur x itérations, combien de temps l'algorithme de recherche binaire peut-il examiner au maximum? La réponse est 2 ^ x. De cela, nous pouvons voir que l'inverse est qu'en moyenne l'algorithme de recherche binaire a besoin de log2 n itérations pour une liste de longueur n.

Si pourquoi c'est O (log n) et non O (log2 n), c'est parce que simplement répété - L'utilisation des grandes constantes de notation O ne compte pas.

vidstige
la source
4

Voici l' entrée wikipedia

Si vous regardez l'approche itérative simple. Vous éliminez simplement la moitié des éléments à rechercher jusqu'à ce que vous trouviez l'élément dont vous avez besoin.

Voici l'explication de la manière dont nous élaborons la formule.

Dites d'abord que vous avez N nombre d'éléments, puis ce que vous faites est «N / 2» comme première tentative. Où N est la somme de la borne inférieure et de la borne supérieure. La première valeur temporelle de N serait égale à (L + H), où L est le premier index (0) et H est le dernier index de la liste que vous recherchez. Si vous avez de la chance, l'élément que vous essayez de trouver sera au milieu [par exemple. Vous cherchez 18 dans la liste {16, 17, 18, 19, 20} puis vous calculez ⌊ (0 + 4) / 2⌋ = 2 où 0 est la borne inférieure (L - index du premier élément du tableau) et 4 est la borne supérieure (H - indice du dernier élément du tableau). Dans le cas ci-dessus L = 0 et H = 4. Maintenant, 2 est l'indice de l'élément 18 que vous recherchez. Bingo! Tu l'as trouvé.

Si le cas était un tableau différent {15,16,17,18,19} mais que vous recherchiez toujours 18, vous n'auriez pas de chance et vous feriez d'abord N / 2 (qui est ⌊ (0 + 4) / 2⌋ = 2 puis réalisez que l'élément 17 à l'index 2 n'est pas le nombre que vous recherchez. Vous savez maintenant que vous n'avez pas à rechercher au moins la moitié du tableau lors de votre prochaine tentative de recherche de manière itérative. l'effort de recherche est divisé par deux. Donc, fondamentalement, vous ne recherchez pas la moitié de la liste des éléments que vous avez recherchés précédemment, chaque fois que vous essayez de trouver l'élément que vous n'avez pas pu trouver lors de votre précédente tentative.

Donc le pire des cas serait

[N] / 2 + [(N / 2)] / 2 + [((N / 2) / 2)] / 2 .....
soit:
N / 2 1 + N / 2 2 + N / 2 3 + ..... + N / 2 x … ..

jusqu'à ce que ... vous ayez terminé la recherche, où dans l'élément que vous essayez de trouver se trouve à la fin de la liste.

Cela montre que le pire des cas est lorsque vous atteignez N / 2 x où x est tel que 2 x = N

Dans les autres cas N / 2 x où x est tel que 2 x <N La valeur minimale de x peut être 1, ce qui est le meilleur des cas.

Or, puisque le pire des cas mathématiques est celui où la valeur de
2 x = N
=> log 2 (2 x ) = log 2 (N)
=> x * log 2 (2) = log 2 (N)
=> x * 1 = log 2 (N)
=> Plus formellement ⌊log 2 (N) + 1⌋

RajKon
la source
1
Comment obtenez-vous exactement la version la plus formelle?
Kalle
Une fonction de sol est utilisée. Les détails sont dans la section sur les performances du lien wiki ( en.wikipedia.org/wiki/Binary_search_algorithm ) fourni dans la réponse.
RajKon
2

Disons que l'itération dans la recherche binaire se termine après k itérations. À chaque itération, le tableau est divisé par moitié. Supposons donc que la longueur du tableau à toute itération soit n à l'itération 1,

Length of array = n

À l'itération 2,

Length of array = n⁄2

À l'itération 3,

Length of array = (n⁄2)⁄2 = n⁄22

Par conséquent, après l'itération k,

Length of array = n⁄2k

De plus, nous savons qu'après k divisions, la longueur du tableau devient 1 Par conséquent

Length of array = n⁄2k = 1
=> n = 2k

Application de la fonction de journal des deux côtés:

=> log2 (n) = log2 (2k)
=> log2 (n) = k log2 (2)
As (loga (a) = 1)

Par conséquent,

As (loga (a) = 1)
k = log2 (n)

Par conséquent, la complexité temporelle de la recherche binaire est

log2 (n)
SirPhemmiey
la source
1

Une recherche binaire fonctionne en divisant le problème en deux à plusieurs reprises, quelque chose comme ceci (détails omis):

Exemple de recherche de 3 dans [4,1,3,8,5]

  1. Commandez votre liste d'articles [1,3,4,5,8]
  2. Regardez l'élément du milieu (4),
    • Si c'est ce que vous cherchez, arrêtez
    • S'il est plus grand, regardez la première moitié
    • Si c'est moins, regardez la seconde moitié
  3. Répétez l'étape 2 avec la nouvelle liste [1, 3], trouvez 3 et arrêtez

C'est un bi recherche annuelle lorsque vous divisez le problème en 2.

La recherche ne nécessite que des étapes log2 (n) pour trouver la valeur correcte.

Je recommanderais Introduction aux algorithmes si vous souhaitez en savoir plus sur la complexité algorithmique.

Silas Parker
la source
1

Puisque nous réduisons une liste de moitié à chaque fois, nous avons donc juste besoin de savoir en combien d'étapes nous obtenons 1 lorsque nous divisons une liste par deux. Dans le calcul ci-dessous, x désigne le nombre de fois où nous divisons une liste jusqu'à ce que nous obtenions un élément (dans le pire des cas).

1 = N / 2x

2x = N

Prendre log2

log2 (2x) = log2 (N)

x * log2 (2) = log2 (N)

x = log2 (N)

Abdul Malik
la source
1

T (N) = T (N / 2) + 1

T (N) = T (N / 2) + 1 = (T (N / 4) + 1) + 1

...

T (N) = T (N / N) + (1 + 1 + 1 + ... + 1) = 1 + logN (base 2 log) = 1 + logN

La complexité temporelle de la recherche binaire est donc O (logN)

TizeeU0U
la source
0
ok see this
for(i=0;i<n;n=n/2)
{
i++;
}
1. Suppose at i=k the loop terminate. i.e. the loop execute k times.

2. at each iteration n is divided by half.

2.a n=n/2                   .... AT I=1
2.b n=(n/2)/2=n/(2^2)
2.c n=((n/2)/2)/2=n/(2^3)....... aT I=3
2.d n=(((n/2)/2)/2)/2=n/(2^4)

So at i=k , n=1 which is obtain by dividing n  2^k times
n=2^k
1=n/2^k 
k=log(N)  //base 2
Piyush Jain
la source
0

Permettez-moi de vous faciliter la tâche à tous avec un exemple.

Par souci de simplicité, supposons qu'il y ait 32 éléments dans un tableau dans l'ordre trié dans lequel nous recherchons un élément à l'aide de la recherche binaire.

1 2 3 4 5 6 ... 32

Supposons que nous recherchons 32. après la première itération, il nous restera

17 18 19 20 .... 32

après la deuxième itération, il nous restera

25 26 27 28 .... 32

après la troisième itération, il nous restera

29 30 31 32

après la quatrième itération, il nous restera

31 32

Dans la cinquième itération, nous trouverons la valeur 32.

Donc, si nous convertissons cela en une équation mathématique, nous obtiendrons

(32 X (1/2 5 )) = 1

=> n X (2 -k ) = 1

=> (2 k ) = n

=> k log 2 2 = log 2 n

=> k = log 2 n

D'où la preuve.

Sumukha HS
la source
0

Voici la solution utilisant le théorème maître, avec LaTeX lisible.

Pour chaque récurrence dans la relation de récurrence pour la recherche binaire, nous convertissons le problème en un sous-problème, avec le temps d'exécution T (N / 2). Par conséquent:

T (n) = T (n / 2) +1

En se substituant au théorème maître, on obtient:

T (n) = aT (n / b) + f (n)

Maintenant, comme logbaest 0 et f (n) est 1, nous pouvons utiliser le deuxième cas du théorème maître car:

f (n) = O (1) = O (n0) = O (nlogba)

Cela signifie que:

T (n) = O (nlogbalogn) = O (n0logn) = O (logn)

id01
la source