rendre efficace la copie de la masortingce symésortingque en c #

Je veux stocker dans un tableau une masortingce symésortingque

pour une masortingce je faisais ça

double[,] mat = new double[size,size]; for (int i = 0; i < size; i++) { for (int j = 0; j <= i; j++) mat[i, j] = mat[j, i] = (n * other_matrix[i,j]); } 

Si je veux stocker dans un tableau

 double[] mat = new double[size*size]; 

au lieu de

  double[,] mat 

Quel serait le moyen le plus efficace?

en utilisant mat[i*n+j] ?

Oui.

Stockez les éléments par rangée, où la rangée i et la colonne j sont stockées dans l’indice k=i*NC+j avec NC le nombre de colonnes. Ceci s’applique à une masortingce générale non symésortingque.

Pour stocker une masortingce symésortingque de taille N vous n’avez besoin que de N*(N+1)/2 éléments dans le tableau. Vous pouvez supposer que i<=j tel que les index de tableau vont comme ceci:

 k(i,j) = i*Ni*(i+1)/2+j i<=j //above the diagonal k(i,j) = j*Nj*(j+1)/2+i i>j //below the diagonal 

avec

 i = 0 .. N-1 j = 0 .. N-1 

Exemple lorsque N = 5, les index de tableau vont comme ceci

 | 0 1 2 3 4 | | | | 1 5 6 7 8 | | | | 2 6 9 10 11 | | | | 3 7 10 12 13 | | | | 4 8 11 13 14 | 

Le total des éléments nécessaires est 5*(5+1)/2 = 15 et les indices vont donc de 0..14 . Vérifier

La i ème diagonale a l'indice k(i,i) = i*(N+1)-i*(i+1)/2 . La 3ème ligne ( i=2 ) a donc un index diagonal k(2,2) = 2*(5+1)-2*(2+1)/2 = 9 . Vérifier

Le dernier élément de la i ème ligne a un indice = k(i,N) = N*(i+1)-i*(i+1)/2-1 . Le dernier élément de la 3ème ligne est donc k(2,4) = 5*(2+1)-2*(2+1)/2-1 = 11 . Vérifier

La dernière partie dont vous pourriez avoir besoin est de savoir comment passer de l’indice de tableau k à la ligne i et à la colonne j . Encore une fois en supposant que i<=j (au-dessus de la diagonale), la réponse est

 i(k) = (int)Math.Floor(N+0.5-Math.Sqrt(N*(N+1)-2*k+0.25)) j(k) = k + i*(i+1)/2-N*i 

Pour vérifier ce qui précède, je l'exécute pour N=5 , k=0..14 et j'ai obtenu les résultats suivants:

Tableau d'index

Qui est correct! Vérifier

Pour faire la copie, utilisez simplement Array.Copy() sur les éléments, ce qui est très rapide. De plus, pour effectuer des opérations telles que l'addition et la mise à l'échelle, il vous suffit de travailler sur les éléments réduits du tableau et non sur la masortingce N*N complète. La multiplication masortingcielle est un peu délicate, mais faisable. Peut-être que vous pouvez poser une autre question à ce sujet si vous le souhaitez.

En ce qui concerne la réponse choisie, à moins que je ne sois un idiot complet, le code n’est pas correct:

Essaye ça:

 i = 2, j = 1 therefore we use: k(i,j) = j*Nj*(j-1)/2+i to find the index k, solving: k(i,j) = 1*5 - 1*(1-1)/2 + 2 k(i,j) = 5 - 0 + 2 = 7 

Dans la masortingce de la réponse sélectionnée, nous voyons que (2,1) n’est pas 7, il semble être 6. En fait (puisque cela semble être 0 base), 7 apparaît à (3,1) ou (1, 3) La deuxième formule pour i> j semble être inexacte, sauf si quelque chose me manque.

METTRE À JOUR:

Cela semble fonctionner si vous modifiez la formule i> j en:

 k(i,j) = j*(N-1)-j*(j-1)/2+i 

Si n est la taille de la masortingce carrée, vous avez besoin de n * (n + 1) / 2 valeurs totales pour une masortingce symésortingque. C’est la sum de 1 + 2 + 3 + … (n – 2) + (n – 1) + n.

Un mot de prudence, cependant, il va être très pénible d’essayer de calculer toujours le bon index pour une ligne et une colonne données, et je m’éloignerais du tableau 2D, plus intuitif, si les masortingces doivent être gros, et la mémoire va être un problème.