Question

Je travaille sur une fonction pour établir l'entropie d'une distribution.Il utilise une copule, si certains la connaissent.Je dois résumer les valeurs du tableau en fonction des dimensions qui sont « prises en compte ».

Exemple:Prenons l'exemple suivant...

Dimension 0 (across)
_ _ _ _ _ _ _ _ _ _ _ _ _
|_ 0 _|_ 0 _|_ 0 _|_ 2 _|  Dimension 1
|_ 1 _|_ 0 _|_ 2 _|_ 0 _|   (down)
|_ 0 _|_ 3 _|_ 0 _|_ 6 _|
|_ 0 _|_ 0 _|_ 0 _|_ 0 _|

I "care about" dimension 0 only, and "don't care" about the rest (dim 1).
Summing this array with the above specifications will
"collapse" the "stacks" of dimension 1 down to a single 4 x 1 array:

_ _ _ _ _ _ _ _ _ _ _ _ _ 
|_ 1 _|_ 3 _|_ 2 _|_ 8 _|

This can then be summed, or have any operation performed.

Je dois le faire avec un tableau de « n » dimensions, qui pourraient éventuellement être de 20.De plus, je dois être capable de le faire, en me souciant de certaines dimensions et en réduisant le reste.J'ai particulièrement du mal avec ça parce que je n'arrive pas à visualiser 20 dimensions :p.Si quelqu'un pouvait m'aider à configurer du code c/c++ pour réduire/sumer, je lui en serais très très reconnaissant.

Mise à jour:

Je viens de rentrer à la maison.Voici quelques informations pour répondre à vos questions :

  1. Désolé d'avoir annulé les modifications, j'espérais que lorsque j'aurais cliqué sur Annuler, cela me montrerait les modifications afin que je puisse voir ce que j'avais raté, un peu comme Wikipédia.Ce n’était pas le cas, comme je l’ai découvert.
  2. @jeff - Qu'est-ce qui n'a pas de sens ?J'utilise cet excellent service pour (ce que je pense être) une raison légitime.Je veux m'améliorer dans mon passe-temps, c'est tout, puisque je suis au lycée.Beaucoup de mes articles concernent la mise en œuvre d'un algorithme génétique (cet article, sparsearray, classer un tableau, manipulation de pointeur).
  3. J'utilise une représentation matricielle clairsemée, car il est possible de dépasser le nombre de molécules dans l'univers en utilisant un tableau traditionnel (dense).Pour l'instant, l'implémentation du sparsearray lui-même n'a pas beaucoup d'importance, car je travaille pour le faire fonctionner avec un tableau standard avant de passer à une représentation clairsemée.Pour ceux qui n'ont pas vu mes questions précédentes, j'utilise un arbre de recherche binaire comme structure pour contenir les points du tableau clairsemé, et une fonction "pilote" pour parcourir l'arbre si nécessaire, renvoyant tout ce pour quoi la fonction est conçue.Ceci est flexible, je peux donc accepter de nombreuses méthodes différentes pour accéder au tableau.
  4. La structure est un hypercube, et le nombre de dimensions est spécifié au moment de l'exécution, ainsi que la longueur de chaque dimension (qui sont toutes identiques, car il s'agit d'un hypercube).

Merci à tous pour votre contribution.

Était-ce utile?

La solution

Cela pourrait avoir des applications.Disons que vous avez implémenté un jeu de la vie de Conway en 2D (qui définit un plan 2D, 1 pour « vivant », 0 pour « mort ») et que vous avez stocké l'historique des jeux pour chaque itération (qui définit ensuite un cube 3D).Si vous vouliez savoir combien de bactéries étaient vivantes au cours de l’histoire, vous utiliseriez l’algorithme ci-dessus.Vous pouvez utiliser le même algorithme pour une version 3D (et 4D, 5D, etc.) de la grille Game of Life.

Je dirais que c'était une question de récursion, je ne suis pas encore un programmeur C mais je sais que c'est possible en C.En python,


def iter_arr(array):
  sum = 0
  for i in array:
    if type(i) == type(list()):
      sum = sum + iter_arr(i)
    else:
      sum = sum + i
  return sum 
  1. Itérer sur chaque élément du tableau
  2. Si l'élément est un autre tableau, appelez à nouveau la fonction
  3. Si l'élément n'est pas un tableau, ajoutez-le à la somme
  4. Somme de retour

Vous appliqueriez ensuite cela à chaque élément de la dimension « soucieux ».

C'est plus facile en python en raison du typage canard cependant...

Autres conseils

@Jeff

En fait, je pense que c'est une question intéressante.Je ne sais pas à quel point c'est utile, mais c'est une question valable.

@Ed

Pouvez-vous fournir un peu plus d'informations sur cette question ?Vous avez dit que la dimension du tableau est dynamique, mais le nombre d'éléments est-il également dynamique ?

MODIFIER:Je vais quand même essayer de répondre à la question.Je ne peux pas vous donner le code par cœur (il faudrait un certain temps pour bien faire les choses sans aucun compilateur ici sur ce PC), mais je peux vous orienter dans la bonne direction...

Prenons comme exemple 8 dimensions (0-7) avec des index de 0 à 3.Vous ne vous souciez que de 1,2 et 6.Cela signifie que vous disposez de deux tableaux.D'abord, array_care[4][4][4] pour 1,2 et 6.Le array_care[4][4][4] tiendra le résultat final.

Ensuite, nous voulons itérer d'une manière très spécifique.Nous avons le tableau input[4][4][4][4][4][4][4][4] à analyser, et nous nous soucions des dimensions 1, 2 et 6.

Nous devons définir quelques index temporaires :

int dim[8] = {0,0,0,0,0,0,0,0};

Nous devons également stocker l'ordre dans lequel nous voulons augmenter les index :

int increase_index_order[8] = {7,5,4,3,0,6,2,1};
int i = 0;

Cette commande est importante pour faire ce que vous avez demandé.

Définissez un indicateur de fin :

bool terminate=false;

Nous pouvons maintenant créer notre boucle :

while (terminate)
{
array_care[dim[1]][dim[2]][dim[6]] += input[dim[0]][dim[1]][dim[2]][dim[3]][dim[4]][dim[5]][dim[6]][dim[7]];

while ((dim[increase_index_order[i]] = 3) && (i < 8))
{
dim[increase_index_order[i]]=0;
i++;
}

if (i < 8) {
dim[increase_index_order[i]]++; i=0;
} else {
terminate=true;
}
}

Cela devrait fonctionner pour 8 dimensions, en prenant soin de 3 dimensions.Il faudrait un peu plus de temps pour le rendre dynamique, et je n'en ai pas le temps.J'espère que cela t'aides.Je m'excuse, mais je n'ai pas encore appris les balises de code.:(

Ce genre de chose est beaucoup plus facile si vous utilisez des conteneurs STL, ou peut-être Boost.MultiArray.Mais si vous devez utiliser un tableau :

#include <iostream>
#include <boost/foreach.hpp>
#include <vector>

int sum(int x) {
    return x;
}

template <class T, unsigned N>
int sum(const T (&x)[N]) {
    int r = 0;
    for(int i = 0; i < N; ++i) {
        r += sum(x[i]);
    }
    return r;
}

template <class T, unsigned N>
std::vector<int> reduce(const T (&x)[N]) {
    std::vector<int> result;
    for(int i = 0; i < N; ++i) {
        result.push_back(sum(x[i]));
    }
    return result;
}

int main() {
    int x[][2][2] = {
        { { 1, 2 }, { 3, 4 } },
        { { 5, 6 }, { 7, 8 } }
    };

    BOOST_FOREACH(int v, reduce(x)) {
        std::cout<<v<<"\n";
    }
}

En fait, en réduisant les colonnes, vous les avez déjà additionnées, donc la dimension n'a aucune importance pour votre exemple.Ai-je raté quelque chose ou c'est vous ?

Je pense que la meilleure chose à faire ici serait une/les deux choses :

  1. Repensez la conception, si elle est trop complexe, trouvez une méthode moins complexe.
  2. Arrêtez d'essayer de le visualiser.:P Stockez simplement les dimensions en question que vous devez additionner, puis faites-les une à la fois.Une fois que vous avez le code de base, envisagez d’améliorer l’efficacité de votre algorithme.

Je ne suis pas d'accord, il y a TOUJOURS un autre moyen.

Et si tu es vraiment ne peut pas refactorisez, vous devez alors diviser le problème en parties plus petites.Comme je l'ai dit, déterminez les dimensions que vous devez additionner, puis frappez-les une à la fois.

Aussi, arrêtez de modifier les modifications, ils corrigent vos fautes d'orthographe, ils essaient de vous aider ;)

Vous faites cela en c/c++...vous avez donc un tableau de tableau de tableau...vous n'êtes pas obligé de visualiser 20 dimensions puisque ce n'est pas ainsi que les données sont disposées en mémoire, pour un 2 dimensions :

[1] --> [1,2,3,4,5,6,...]
[2] --> [1,2,3,4,5,6,...]
[3] --> [1,2,3,4,5,6,...]
[4] --> [1,2,3,4,5,6,...]
[5] --> [1,2,3,4,5,6,...]
 .           .
 .           .
 .           .

alors, pourquoi ne pouvez-vous pas parcourir le premier en résumant son contenu ?Si vous essayez de trouver la taille, alors sizeof(array)/sizeof(int) est une approche risquée.Vous devez connaître la dimension pour pouvoir traiter ces données et configurer la mémoire afin de connaître la profondeur de récursion à additionner.Voici un pseudo-code de ce que vous devriez faire,

sum( n_matrix, depth )
  running_total = 0
  if depth = 0 then
    foreach element in the array
      running_total += elm
  else 
     foreach element in the array
       running_total += sum( elm , depth-1 )
  return running_total
x = number_of_dimensions;
while (x > 1)
{
  switch (x)
  {
    case 20:
      reduce20DimensionArray();
      x--;
    break;
    case 19:
      .....
  }
}

(Désolé, je n'ai pas pu résister.)

Si je comprends bien, vous souhaitez additionner toutes les valeurs de la section transversale définie à chaque "bac" le long d'une dimension.Je suggère de créer un tableau 1D pour votre destination, puis de parcourir chaque élément de votre tableau en ajoutant la valeur à la destination avec l'index de la dimension d'intérêt.

Si vous utilisez un nombre arbitraire de dimensions, vous devez disposer d'un moyen d'adresser les éléments (je serais curieux de savoir comment vous implémentez cela).Votre implémentation de ceci affectera la façon dont vous définissez l’index de destination.Mais un moyen évident serait de vérifier les instructions if dans les boucles d'itération.

Lorsque vous dites que vous ne savez pas combien il y a de dimensions, comment définissez-vous exactement les structures de données ?

À un moment donné, quelqu’un doit créer ce tableau, et pour ce faire, il doit connaître les dimensions du tableau.Vous pouvez forcer le créateur à transmettre ces données avec le tableau.

A moins que la question ne soit de définir une telle structure de données...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top