Domanda

Sto lavorando su una funzione per stabilire l'entropia di una distribuzione.Utilizza una copula, se qualcuno la conosce.Devo riassumere i valori nell'array in base alle dimensioni "curate".

Esempio:Considera il seguente esempio...

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.

Devo farlo con una serie di dimensioni "n", che potrebbero essere 20.Inoltre, devo essere in grado di farlo, preoccupandomi di certe dimensioni e facendo crollare il resto.Sto attraversando un periodo particolarmente difficile perché non riesco a visualizzare 20 dimensioni: p.Se qualcuno potesse aiutarmi a impostare del codice c/c++ per comprimere/sommare, ne sarei molto grato.

Aggiornamento:

Appena arrivato a casa.Ecco alcune informazioni per rispondere alle tue domande:

  1. Mi scuso per aver annullato le modifiche, speravo che quando ho cliccato su Annulla mi avrebbero mostrato le modifiche in modo da poter vedere cosa avevo incasinato, un po' come Wikipedia.Non era così, come ho scoperto.
  2. @jeff - Cosa non ha senso?Sto utilizzando questo ottimo servizio per (quello che penso sia) un motivo legittimo.Voglio migliorare nel mio hobby, che è tutto, visto che sono al liceo.Molti dei miei post riguardano l'implementazione di un algoritmo genetico (questo post, sparsearray, classifica un array, manipolazione del puntatore).
  3. Sto utilizzando una rappresentazione con array sparso, poiché è possibile superare il numero di molecole nell'universo utilizzando un array tradizionale (denso).Per ora, l'implementazione dello sparsearray in sé non ha molta importanza, poiché sto lavorando per farlo funzionare con un array standard prima di passare a una rappresentazione sparsa.Per coloro che non hanno visto le mie domande precedenti, sto utilizzando un albero di ricerca binario come struttura per contenere i punti dell'array sparsi e una funzione "driver" per attraversare l'albero secondo necessità, restituendo qualunque cosa la funzione sia progettata per fare.Questo è flessibile, quindi posso ospitare molti metodi diversi per accedere all'array.
  4. La struttura è un ipercubo e il numero di dimensioni viene specificato in fase di esecuzione, così come la lunghezza di ciascuna dimensione (che sono tutte uguali, poiché si tratta di un ipercubo).

Grazie a tutti per il vostro contributo.

È stato utile?

Soluzione

Questo potrebbe avere applicazioni.Diciamo che hai implementato un Game of Life di Conway in 2D (che definisce un piano 2D, 1 per "vivo", 0 per "morto") e hai archiviato la cronologia dei giochi per ogni iterazione (che quindi definisce un cubo 3D).Se volessi sapere quanti batteri erano vivi nel corso della storia, utilizzeresti l'algoritmo sopra.Potresti utilizzare lo stesso algoritmo per una versione 3D (e 4D, 5D ecc.) della griglia di Game of Life.

Direi che questa era una domanda di ricorsione, non sono ancora un programmatore C ma so che è possibile in C.In pitone,


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. Itera su ogni elemento dell'array
  2. Se l'elemento è un altro array, richiama nuovamente la funzione
  3. Se l'elemento non è un array, aggiungilo alla somma
  4. Restituisci la somma

Lo applicheresti quindi a ciascun elemento nella dimensione "curato".

Questo è più semplice in Python grazie alla digitazione duck ...

Altri suggerimenti

@Jeff

In realtà penso che questa sia una domanda interessante.Non sono sicuro di quanto sia utile, ma è una domanda valida.

@Ed

Puoi fornire qualche informazione in più su questa domanda?Hai detto che la dimensione dell'array è dinamica, ma anche il numero di elementi è dinamico?

MODIFICARE:Proverò comunque a rispondere alla domanda.Non posso darti il ​​codice a mente (ci vorrebbe un po' per farlo bene senza alcun compilatore qui su questo PC), ma posso indicarti la giusta direzione...

Usiamo come esempio 8 dimensioni (0-7) con indici da 0 a 3.Ti interessano solo 1,2 e 6.Ciò significa che hai due array.Primo, array_care[4][4][4] per 1,2 e 6.IL array_care[4][4][4] manterrà il risultato finale.

Successivamente, vogliamo iterare in un modo molto specifico.Abbiamo la matrice input[4][4][4][4][4][4][4][4] da analizzare, e ci preoccupiamo delle dimensioni 1, 2 e 6.

Dobbiamo definire alcuni indici temporanei:

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

Dobbiamo anche memorizzare l'ordine in cui vogliamo aumentare gli indici:

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

Questo ordine è importante per fare ciò che hai richiesto.

Definire un flag di terminazione:

bool terminate=false;

Ora possiamo creare il nostro ciclo:

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;
}
}

Dovrebbe funzionare per 8 dimensioni, preoccupandosi di 3 dimensioni.Ci vorrebbe un po' più di tempo per renderlo dinamico, e non ho tempo.Spero che questo ti aiuti.Mi scuso, ma non ho ancora imparato i markup del codice.:(

Questo genere di cose è molto più semplice se usi contenitori STL, o forse Boost.MultiArray.Ma se devi usare un array:

#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";
    }
}

In realtà, comprimendo le colonne le hai già sommate, quindi la dimensione non ha alcuna importanza per il tuo esempio.Mi sono perso qualcosa o tu?

Penso che la cosa migliore da fare qui sarebbe una o entrambe le due cose:

  1. Ripensa il design, se è troppo complesso, trova un modo meno complesso.
  2. Smetti di provare a visualizzarlo..:P Memorizza semplicemente le dimensioni in questione che devi sommare, quindi eseguile una alla volta.Una volta che hai il codice di base, cerca di migliorare l'efficienza del tuo algoritmo.

Mi permetto di dissentire, c'è SEMPRE un altro modo..

E se davvero non può refactoring, è necessario suddividere il problema in parti più piccole.Come ho detto, stabilisci quali dimensioni devi sommare, quindi selezionale una alla volta..

Inoltre, smetti di cambiare le modifiche, stanno correggendo i tuoi errori di ortografia, stanno cercando di aiutarti ;)

Lo stai facendo in c/c++...quindi hai un array di array di array...non è necessario visualizzare 20 dimensioni poiché non è così che i dati sono disposti in memoria, per un bidimensionale:

[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,...]
 .           .
 .           .
 .           .

quindi, perché non puoi scorrere il primo sommandone i contenuti?Se stai cercando di trovare la taglia, allora sizeof(array)/sizeof(int) è un approccio rischioso.È necessario conoscere la dimensione per poter elaborare questi dati e impostare la memoria, in modo da conoscere la profondità della ricorsione da sommare.Ecco uno pseudo codice di ciò che sembra che dovresti fare,

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:
      .....
  }
}

(Scusate, non ho potuto resistere.)

Se ho capito bene, vuoi sommare tutti i valori nella sezione trasversale definita in ciascun "contenitore" lungo 1 dimensione.Suggerisco di creare un array 1D per la tua destinazione, quindi scorrere ogni elemento dell'array aggiungendo il valore alla destinazione con l'indice della dimensione di interesse.

Se stai utilizzando un numero arbitrario di dimensioni, devi avere un modo per indirizzare gli elementi (sarei curioso di sapere come lo stai implementando).La tua implementazione influenzerà il modo in cui imposti l'indice di destinazione.Ma un modo ovvio sarebbe con le istruzioni if ​​controllate nei cicli di iterazione.

Quando dici di non sapere quante dimensioni ci sono, come definisci esattamente le strutture dei dati?

Ad un certo punto, qualcuno deve creare questo array e, per farlo, deve conoscere le dimensioni dell'array.Puoi forzare il creatore a passare questi dati insieme all'array.

A meno che la questione non sia definire una tale struttura di dati...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top