Compte tenu de cet algorithme de tri, comment exprimez-vous sa complexité temporelle?
Présenté à l'origine ici (archive partielle) .
#!/bin/bash
function f() {
sleep "$1"
echo "$1"
}
while [ -n "$1" ]
do
f "$1" &
shift
done
wait
example usage:
./sleepsort.bash 5 3 6 3 6 3 1 4 7
Je pense que paxdiablo est le plus proche, mais pas pour la bonne raison. La complexité temporelle ignore les problèmes sur le matériel réel tels que les tailles de cache, les limites de mémoire et dans ce cas le nombre limité de processus et le fonctionnement du planificateur.
Sur la base de la page Wikipedia pour la complexité temporelle je dirais que la réponse est que vous ne pouvez pas déterminer la complexité d'exécution car si elle est définie comme:
La complexité temporelle est généralement estimée en comptant le nombre d'opérations élémentaires effectuées par l'algorithme, où une opération élémentaire prend un temps fixe à effectuer. Ainsi le temps nécessaire et le nombre d'opérations élémentaires effectuées par l'algorithme diffèrent au maximum d'un facteur constant.
Ensuite, nous ne pouvons pas parler de la complexité d'exécution de cet algorithme car le temps que prennent les opérations élémentaires est tellement différent, que le temps pris différerait de plus d'un facteur constant.
O(max(input)+n)
La complexité semble simplement difficile à exprimer car la plupart des algorithmes de tri sont indépendants des données. Leur temps dépend de la quantité de données, pas des données elles-mêmes.
FWIW, comme indiqué ici , ce n'est pas un algorithme fiable pour trier les données.
Personne ne semble avoir abordé la façon dont ces sleep
sont implémentés. En fin de compte, ils se retrouvent quelque part dans un planificateur, et la complexité opérationnelle dépendra de l'algorithme de planification utilisé. Par exemple, si les sleep
sont placés comme événements dans une file d'attente prioritaire, vous vous retrouverez probablement avec quelque chose d'équivalent à heapsort, avec une complexité O (n log n). Un algorithme de planification naïf pourrait entraîner O (n ^ 2).
La complexité temporelle et la complexité du processus de cet algorithme sont toutes deux O(braindead)
:
(2,9,9,9,9,9,...,9,9,1)
ne triera pas le 1
et 2
correctement.La complexité temporelle n'est pas pertinente dans ce cas. Vous ne pouvez pas obtenir moins optimisé que "faux". Il est normal d'utiliser l'analyse de complexité pour comparer les algorithmes à mesure que la taille de l'ensemble de données change, mais pas lorsque les algorithmes sont ridicules en premier lieu :-)
Bien que cela semble linéaire, je pense que la complexité est toujours O(log(n) * max (entrée)).
Lorsque nous parlons de complexité temporelle asymptotique, cela signifie combien de temps est nécessaire lorsque n devient infiniment grand.
Un algorithme de tri basé sur la comparaison ne peut pas être plus rapide que O (n * log (n)), et le Sleep-Sort est en fait basé sur la comparaison:
Les processus dorment n secondes et se réveillent. Le système d'exploitation doit trouver le moins de temps de sommeil restant de tout le processus de sommeil et réveiller celui s'il est temps.
Cela nécessitera une file d'attente prioritaire, ce qui prend O(logN) le temps d'insertion d'un élément, et O(1) trouver l'élément minimum, et O(logN) suppression de l'élément minimum.
Lorsque n devient très grand, il faudra plus d'une seconde pour réveiller un processus, ce qui le rend plus grand que O (n).
Si vous lisez le fil, vous verrez que votre question a déjà reçu une réponse. La complexité temporelle est O(max(input))
et la complexité opérationnelle (nombre d'opérations) est O(n)
.
Je suis avec Jordan, sauf que je pense que la complexité de l'horloge murale est mieux exprimée par O (2 ^ m) où m est la taille de chaque élément, plutôt que O (max (entrée)).
Si chaque élément a la taille m, le plus grand élément aura la valeur entière 2 ^ m (moins un, mais personne ne s'en soucie). Par construction, l'algorithme nécessite que le temps de configuration soit inférieur à 1, une constante.
Donc complexité de l'horloge murale O (2 ^ m), complexité du nombre d'opérations O (n).
Un algorithme modifié prenant en compte le temps de mise en place aurait probablement une complexité d'horloge murale O (2 ^ m + n). Par exemple, il pourrait noter l'heure actuelle au début, calculer base_time = start_time + k*len(list)
(pour une constante k appropriée), puis laisser les threads dormir jusqu'à l'heure base_time+i
. Alors k*len(list)
est clairement O(n) et i
est O (2 ^ m) comme avant, pour un total de O (2 ^ m + n).