Numérotation des couples (i,j) avec j > i

Bonjour,
J'ai une telle double boucle :
for(int i = 0; i < 4 ;i++){
  for(int j = i+1; j < 5; j++){
    ......
  }
}
Il me faut, pour chacun des dix couples (i,j) de cette boucle, un entier k qui va de 0 à 9. Vous allez me dire que je peux faire:
int k = -1;
for(int i = 0; i < 4 ;i++){
  for(int j = i+1; j < 5; j++){
    k = k + 1;
    ......
  }
}
Mais je ne peux pas m'en sortir comme ça, car l'intention est de prendre la k-ième composante V[k] d'un vecteur V, et c'est un programme en WebGL, qui ne permet pas de prendre un tel indice variable.

J'ai donc fait une fonction :
int f(int i, int j){
      if(i == 0){
        if(j == 1) return 0;
        if(j == 2) return 1;
        if(j == 3) return 2;
        if(j == 4) return 3;
      }else if(i == 1){
        if(j == 2) return 4;
        if(j == 3) return 5;
        if(j == 4) return 6;
      }else if(i == 2){
        if(j == 3) return 7;
        if(j == 4) return 8;
      }else{
        return 9;
      }
    }
et je fais V[f(i,j)] dans ma boucle. Ça marche de cette façon. Je pourrais simplifier cette fonction ainsi :
int f(int i, int j){
      if(i == 0){
        return j - 1;
      }else if(i == 1){
        return j + 2;
      }else if(i == 2){
        return j + 4;
      }else{
        return 9;
      }
    }
Cette méthode est spécifique aux limites sur i et j. Si maintenant j'ai une double boucle telle la suivante, pour n un entier quelconque :
for(int i = 0; i < n-1 ;i++){
  for(int j = i+1; j < n; j++){
    ......
  }
}
alors comment puis-je programmer f(i,j) ?
J'ai l'impression de passer à côté d'un truc simple...

Réponses

  • sage: def F(k):
    ....:     return floor((sqrt(-1+8*k)+1)/2)
    ....: 
    sage: [(k-F(k)*(F(k)-1)/2,F(k)+1) for k in range(1,29)]
    [(1, 2),
     (1, 3), (2, 3),
     (1, 4), (2, 4), (3, 4),
     (1, 5), (2, 5), (3, 5), (4, 5),
     (1, 6), (2, 6), (3, 6), (4, 6), (5, 6),
     (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7),
     (1, 8), (2, 8), (3, 8), (4, 8), (5, 8), (6, 8), (7, 8)]
    
  • Bonjour,
    Il faut regarder du côté de la numérotation des couples d'entiers de Cantor.
    Par exemple, là :
    https://culturemath.ens.fr/print.php?nid=3712&print=yes
    Bonne journée,
    Aline
  • @Math Coss, je ne comprends pas où tu veux en venir. Il faut que j'entre i et j, et que j'obtienne alors k.
  • Il me semble que la fonction que tu cherches est : \[f(i,j,n) = \frac{i\times (2n-i-1)}{2}+j-1\]
  • @bisam,

    Je crois que ça ne marche pas. $f(1,2,5) = 5$ alors qu'il faudrait $4$. Ceci dit, ça n'a pas l'air loin, je vais tester pour voir si je peux corriger.
  • @bisam,

    Je crois que c'est $$f(i,j,n) = \frac{i\times (2n-i-1)}{2}+j-i-1.$$

    J'espère que WebGL accepte la division d'entiers maintenant.
  • Quelle souplesse ! Ce que je te propose, c'est de remplacer les deux boucles imbriquées par une seule portant sur k variant entre 1 et n(n+1)/2, et la fonction F te permet de retrouver i et j en fonction de k.
  • @Saturne : On n'avait pas pris le même "n", ce qui explique le décalage.
  • @Math Coss: Ah ok ! C'était effectivement évident.

    Merci à tous !
Connectez-vous ou Inscrivez-vous pour répondre.