web-dev-qa-db-fra.com

Mise en œuvre rapide d'algorithme pour trier la très petite liste

C'est le problème que j'ai couru il y a longtemps. Je pensais pouvoir demander à vos idées. Supposons que j'ai une très petite liste de chiffres (entiers), 4 ou 8 éléments, qui doivent être triés rapidement. Quelle serait la meilleure approche/algorithme?

mon approche consistait à utiliser les fonctions max/min (10 fonctions pour trier 4 numéros, aucune branche, ICIRC).

// s(i,j) == max(i,j), min(i,j)
i,j = s(i,j)
k,l = s(k,l)
i,k = s(i,k) // i on top
j,l = s(j,l) // l on bottom
j,k = s(j,k)

Je suppose que ma question concerne plus à la mise en œuvre, plutôt que de type d'algorithme.

À ce stade, il devient un peu du matériel, alors supposons donc un processeur Intel 64 bits avec SSE3.

Merci

38
Anycorn

Pour les petits tableaux comme celui-ci, vous devriez probablement regarder dans Tri des réseaux . Comme vous pouvez le constater sur cette page, le tri d'insertion peut être exprimé en tant que réseau de tri. Toutefois, si vous connaissez la taille de la matrice au préalable, vous pouvez concevoir un réseau optimal. Jetez un coup d'œil à - ce site Vous pouvez vous aider à trouver des réseaux de tri optimaux pour une taille de matrice donnée (bien que optimale soit garantie seulement jusqu'à une taille de 16 je crois). Les comparateurs sont même regroupés dans des opérations pouvant être effectuées en parallèle. Les comparateurs sont essentiellement identiques à ceux de la fonction S (x, y) si vous voulez vraiment que cela soit rapide, vous ne devriez pas utiliser min et max, car vous faites ensuite deux fois le nombre de comparaisons nécessaires.

Si vous avez besoin de cet algorithme de tri pour travailler sur une large gamme de tailles, vous devriez probablement simplement aller avec l'insertion Trier car d'autres ont suggéré.

36
Justin Peel

Je vois que vous avez déjà une solution qui utilise 5 comparaisons (en supposant que S (I, J) compare les deux chiffres une fois et les échange ou non). Si vous vous tenez au tri basé sur la comparaison, vous ne pouvez pas le faire avec moins de 5 comparaisons.

Cela peut être prouvé parce qu'il y a 4! = 24 façons possibles de commander 4 numéros. Chaque comparaison ne peut couper les possibilités que dans la moitié, donc avec 4 comparaisons que vous ne pouviez distinguer que de 2 ^ 4 = 16 commandes possibles.

7
mathmike

Pour trier de petites quantités de chiffres, vous voulez un simple algorithme car la complexité ajoute plus de frais généraux.

Le moyen le plus efficace de trier par exemple quatre articles serait de démêler l'algorithme de tri aux comparaisons linéaires, éliminant ainsi tous les frais généraux:

function sort(i,j,k,l) {
  if (i < j) {
    if (j < k) {
      if (k < l) return [i,j,k,l];
      if (j < l) return [i,j,l,k];
      if (i < l) return [i,l,j,k];
      return [l,i,j,k];
    } else if (i < k) {
      if (j < l) return [i,k,j,l];
      if (k < l) return [i,k,l,j];
      if (i < l) return [i,l,k,j];
      return [l,i,k,j];
    } else {
      if (j < l) return [k,i,j,l];
      if (i < l) return [k,i,l,j];
      if (k < l) return [k,l,i,j];
      return [l,k,i,j];
    }
  } else {
    if (i < k) {
      if (k < l) return [j,i,k,l];
      if (i < l) return [j,i,l,k];
      if (j < l) return [j,l,i,k];
      return [l,j,i,k];
    } else if (j < k) {
      if (i < l) return [j,k,i,l];
      if (k < l) return [j,k,l,i];
      if (j < l) return [j,l,k,i];
      return [l,j,k,i];
    } else {
      if (i < l) return [k,j,i,l];
      if (j < l) return [k,j,l,i];
      if (k < l) return [k,l,j,i];
      return [l,k,j,i];
    }
  }
}

Cependant, le code pousse beaucoup pour chaque élément supplémentaire que vous ajoutez. L'ajout d'un cinquième élément rend le code environ quatre fois plus grand. À huit articles, il s'agirait d'environ 30000 lignes, alors bien que ce soit toujours le plus efficace, c'est beaucoup de code et vous devrez écrire un programme qui écrit le code pour le corriger.

7
Guffa

Le tri d'insertion est considéré comme le meilleur pour les petits bancs. Voir Trier stable rapide pour les petites tableaux (moins de 32 ou 64 éléments

4
mathmike

Pour un tel ensemble de données, vous souhaitez aussi simple algorithme que possible. Plus susceptibles que non, une base Sort d'insertion fera aussi bien que vous le souhaitez.

Il faudrait en savoir plus sur le système qui fonctionne, combien de fois vous devez faire ce genre d'une seconde, etc ... mais la règle générale en petites sortes est de le garder simple. Quicksort et similaires ne sont pas bénéfiques.

3
bwawok

Les réseaux de tri peuvent être facilement implémentés dans SIMD, bien qu'il commence à devenir laids autour de N = 16. Pour N = 4 ou N = 8, ce serait un bon choix. Idéalement, vous avez besoin de beaucoup de petits ensembles de données pour trier simultanément, c'est-à-dire que si vous triez des valeurs 8 bits, vous souhaitez que au moins 16 ensembles de données soient triers - il est beaucoup plus difficile de faire ce genre de chose Vecteurs SIMD.

Voir aussi: Sort le plus rapide de longueur fixe 6 INT

3
Paul R