[C] Assegnazioni valori ad un numero determinato di elementi

bad.alex
Ciao ragazzi.
Sto provando a risolvere il seguente problema: ho 15 soggetti. Ciascun soggetto riceve nell'istante di tempo t due segnali, con possibili valori 1 e 0.
A me interesserebbe assegnare a 7 soggetti la coppia di segnali (1,1); a 6 soggetti la coppia di segnali (1,0) (o alternativamente (0,1)); a 2 soggetti la coppia (0,0).
Tuttavia, un errore di $+-1$ sul numero di soggetti mi andrebbe anche bene.
Avevo provato ad utilizzare la funzione rand() nel seguente modo:

for(i=0;i<15; i++){
if(rand()/RAND_MAX<0.60) signal1[i]=1;
else signal1[i]=0;

if(rand()/RAND_MAX<0.60) signal2[i]=1;
else signal2[i]=0;

}


o anche

for(i=0;i<15; i++){
if(rand()/RAND_MAX<0.60) signal1[i]=1;

if(rand()/RAND_MAX<0.60) signal2[i]=1;

}


Vorrei in qualche modo 'forzare' la casualità dovuta a rand() con un margine di errore molto piccolo... ma non so quanto risulti fattibile.
Avevo pensato di creare un vettore di 3 elementi, con valori 0, 0.6 e 1 così da 'pescare' tra questi soli tre valori (che, peraltro, se inseriti come indice di un array, devono avere valore intero, e quindi avrei che 0 è uguale a 0.6 :? ), ma non sono riuscito a fare il passo successivo, ovvero assegnare (1,1) a soli 7 elementi etc..

Qualche consiglio?

Vi ringrazio

Risposte
apatriarca
Il modo più semplice è quello di creare un array di 15 elementi, con 7 elementi uguali a 0, 6 uguali a 1 e 2 uguali a 2 (0, 1 e 2 sono numeri a caso che rappresentano rispettivamente (1,1), (1,0) e (0, 0) nel tuo esempio). Dopodiché "mischi" gli elementi dell'array (cerca random shuffle algorithm) e assegni al soggetto i-esimo il valore in questo array mischiato.

Volendo uscire dall'ambiente informatico: è come se creassi un mazzo con le possibili scelte nel numero corretto e poi lo mischiassi e dessi ad ognuno una carta. Il numero di soggetti con la carta (1, 1) saranno esattamente uguali al numero di carte di questo tipo nel mazzo originale.

bad.alex
Ti ringrazio, apatriarca.
Seguendo il tuo consiglio, ho provato a scrivere in questo modo:

#define VOL 15

int main(){

    srand((unsigned int) time(NULL));
float array[VOL]={0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1,0};
    float signal1[VOL], signal2[VOL];
if(VOL>1)
{
    int i,j,t=10;
    for(i=0; i<VOL;i++)
    {
         j=i+rand()/((float)RAND_MAX/(VOL-i)+1.);
        t=array[j];
        array[j]=array[i];
        array[i]=t;
        printf("array: %f\n", array[i]);
        if(array[i]==1){
          signal2[i]=0;
        signal1[i]=10;
        printf("array[i]=%f signal1[i]=%f signal2[i]=%f\n", array[i], signal1[i], signal2[i]);
        }
        else if(array[i]==0){
            signal2[i]=0;
        signal1[i]=0;
        printf("array[i]=%f signal1[i]=%f signal2[i]=%f\n", array[i], signal1[i], signal2[i]);
        }
        else if (array[i]==2){
                signal1[i]=10;
                signal2[i]=10;
                printf("array[i]=%f signal1[i]=%f signal2[i]=%f\n", array[i], signal1[i], signal2[i]);

        }
    }
}


Ho inserito questa parte di codice in una funzione. Però, poiché devo lavorare sui segnali, potresti dirmi come fare affinché possano essere 'restituiti'?

Al momento ho:

if(a!=0){
shuffle(array1[VOL]);
}
else if(b!=0){
shuffle(array2[VOL]);
}


Ma mi servirebbe svolgere anche le seguenti operazioni:

            tot_sig= signal1[i]+signal2[i];
if(tot_sign==....){ // La parte non riportata di codice all'interno dell'if lascia intendere la corposità del codice  :lol: 
}
else if(tot_sign<...){
}
else if (tot_sign>...){
}


Ti ringrazio sin da ora per l'aiuto.

apatriarca
È sufficiente scrivere i valori che vuoi restituire nel numero corretto nei due array dei segnali e poi mischiare quelli invece di mischiare un terzo array...

bad.alex
Perfetto, apatriarca. Ti ringrazio per l'aiuto e per i suggerimenti. Finalmente funziona! Buona serata :wink:

bad.alex
Ragazzi, vi chiedo scusa se riporto alla vostra attenzione questo post, ma facendo alcune prove mi sono reso conto che sto sbagliando qualcosa e, purtroppo, non riesco a capire cosa. La funzione

void shuffle(float array[VOL]){
    
    if(VOL>1)
    {
        int i,j,t;
        for(i=0; i<VOL;i++)
        {
            j=i+rand()/((float)RAND_MAX/(VOL-i)+1.);
            t=array[j];
            array[j]=array[i];
            array[i]=t;
            
            if(array[i]==1){
                signal2[i]=MIN;
                signal1[i]=MAX;
            }
             if(array[i]==0){
                if(MIN!=a){
                    signal2[i]=MIN;
                    signal1[i]=MIN;
                }
                 else if(MAX!=a)
                {
                    signal2[i]=MAX;
                    signal1[i]=MAX;
                }
            }
             if (array[i]==2){
                if(MIN==a){
                   signal2[i]=MIN;
                   signal1[i]=MIN;
                }
                  else if(MAX==a){
                    signal2[i]=MAX;
                    signal1[i]=MAX;
                }
            }
            printf("array[%d]=%f signal1[i]: %d signal2: %d\n", i, array[i], signal1[i], signal2[i]);

        }
    }
}


seleziona correttamente i valori agli elementi dell'array, dichiarato globalmente,
float random_sign_low[]={2,2,2,2,2,2,2,1,1,1,1,1,1,0,0};


Però, quando richiamo questa funzione all'interno di un'altra funzione, i valori li perdo:

for(i=0; i<VOL;i++){

if(L_PR_!=0){
            shuffle(random_sign_low);
        }
        
        tot_sig=signal1[i]+signal2[i];

if(tot_sig==(MIN+MAX)){ 

           net[i]= 0; 
            
            p_cor+=1;
            p_incor+=1;
            
             fprintf(finfo,"[0]   %d   %d     \t%d \t\t%d \t\t%d   \t%.2f\n", i, net[i], tot_sig, signal1[i], signal2[i],  L_PR);
}

if((tot_sig==2*MAX&&MAX!=a)||(tot_sig==2*MIN&&MIN!=a)){
            
            net[i]=-2; 
            
            p_cor+=0;
            p_incor+=2;
            
            if(tot_sig==2*MAX){
                p_info1+=2;
                p_info0+=0;
                }

         else if(tot_sig==2*MIN){
                p_info0+=2;
                p_info1+=0;
              }
             fprintf(finfo,"[-2]   %d   %d     \t%d \t\t%d \t\t%d   \t%.2f\n", i, net[i], tot_sig, signal1[i], signal2[i],  L_PR);
        } 

if((tot_sig==2*MAX&&a==MAX)||(tot_sig==2*MIN&&a==MIN)){
            
            net[i]=2; 
            
            p_cor+=2;
            p_incor+=0;
            
            if(tot_sig==2*MAX){
                p_info1+=2;
                p_info0+=0;
              
            }
            
            else if(tot_sig==2*MIN){
                p_info0+=2;
                p_info1+=0;
            
            }
                     fprintf(finfo,"[+2]   %d   %d     \t%d \t\t%d \t\t%d   \t%.2f\n", i, net[i], tot_sig, signal1[i], signal2[i],  L_PR);
        } // chiude if(tot_sig==...)
        
    } // chiude for(i=0;i<VOL;i++) 


Potreste aiutarmi a capire dove sto sbagliando? Vi ringrazio.

apatriarca
Sarebbe utile vedere tutto il codice. Non è ad esempio chiaro se il codice viene effettivamente eseguito. Lo shuffle sembra inoltre fatto nel posto sbagliato, ma per capirlo devo capire meglio che cosa stai facendo.

bad.alex
Ti ringrazio per la tua risposta. Riportare l'intero codice è praticamente impossibile, in quanto sono ben 37 pagine in pdf :|
In pratica, ciò che sto facendo (o che vorrei fare) è di andare ad assegnare a 7 soggetti una coppia di segnali (1,1), ovvero entrambi i segnali uguali a 1 rispettivamente (informazione corretta), a 6 soggetti una coppia di segnali (1,0) mentre ad altri due soggetti una coppia di segnali (0,0) (informazione sbagliata). E, per fare ciò, mi sto servendo di questa funzione shuffle, la quale dovrebbe permettermi di assegnare questi valori secondo tali proporzioni. E tutto funzionerebbe se mi fermassi a questa funzione. Infatti, stampando i valori all'interno di shuffle, vi sono 6 soggetti con segnali (0,1), 7 con (1,1) e solo 2 cn (0,0). Tuttavia, devo assegnare delle svolgere alcune operazioni, a seconda della somma dei segnali (1+1, 1+0, o 0+0) sia uguale o meno ad un valore 'a' prefissato.
Qui purtroppo trovo l'errore, poiché non è vero che i segnali restituiti dalla funzione shuffle sono distribuiti nel modo seguente: 7 con (1,1), 6 con (1,0) e 2 con (0,0). A questo punto ciò che mi servirebbe 'capire' è se io stia sbagliando a riportare la funzione shuffle, oppure a non utilizzare eventuali puntatori, o se gli operatori logici siano ridondanti o utilizzati in modo errato rispetto a quello che mi sono prefissato di fare.
La parte di codice che è interessata è tutta riportata nel mio messaggio precedente: ciò che eseguo prima o dopo viene correttamente eseguito, ma non ha nulla a che vedere con la mia funzione shuffle e le restanti condizioni (anche la matrice che utilizzo, infatti, è stata ben collaudata) :wink:

apatriarca
Ho riguardato il codice e sono sempre più convinto che il problema è che shuffle sia nel posto sbagliato. L'array va infatti mischiato una sola volta, non ad ogni ciclo. Per capirlo considera l'esempio del mazzo di carte che ti ho fatto prima e considera i due casi:
1. Mischi il mazzo una volta e mostri l'i-esima carta all'i-esimo giocatore.
2. Per ogni giocatore, mischi il mazzo e gli mostri l'i-esima carta.
Tu stai implementando la strategia 2, mentre quella che vuoi è strategia 1..

bad.alex
"apatriarca":
Ho riguardato il codice e sono sempre più convinto che il problema è che shuffle sia nel posto sbagliato.

Potresti spiegarmi meglio in che senso shuffle si trova nel posto sbagliato? Considera che la struttura della funzione, all'interno della quale richiamo shuffle, è:

for(i=0;i<15;i++){

int ...;
float ...;
double ...;

for(i=0;i<15;i++){

if(L_PR!=0) // L_PR è in tal caso diverso da zero in quanto uguale a 0.5
{
  shuffle(random_sign_low);
        }
        tot_sig=signal1[i]+signal2[i];

if(tot_sig==...){
...
}

if(tot_sig==...){
...
}
if(tot_sig==...){
...
}
} // chiude for()


Non saprei, effettivamente, in che altro posto richiamarlo. :( E credimi che non vi è molta alternativa, iniziando praticamente dal ciclo for la mia funzione (quindi si tratterebbe di un problema da "dentro o fuori" lo stesso ciclo)

"apatriarca":
Tu stai implementando la strategia 2, mentre quella che vuoi è strategia 1..

In che senso?

(scusami ma di questi tempi sono parecchio tonto!)

EDIT: L'intero codice, invece, è strutturato nel seguente modo:

int main(){

treatment();
return 0;
}

treatment(){

for(n=0; n<TOT_SIM;n++){
matrix(); // qui definisco la rete, costituita dai 15 elementi. Tuttavia non utilizzo random_signals_low  :? 
init_all();
function(); // all'interno di function() richiamo shuffle();
}
}

apatriarca
Nel ciclo più interno fai lo shuffle e poi consideri solo l'elemento corrente. Lo shuffle deve essere al di fuori di quel ciclo per funzionare.

bad.alex
Dici in questo modo?

 if(H_PR!=0){
        shuffle(random_sign_high);
    }
    if(L_PR!=0){
        shuffle(random_sign_low);
    }
    
    for(i=0;i<VOL;i++){
        
        signal1[i]=0; // No signal
        signal2[i]=0; // No signal
        
        tot_sig=signal1[i]+signal2[i];

.... // condizioni if
}


Così mi stampa soltanto valori uguali (solo coppie di segnali uguali) :?

apatriarca
Stai sovrapponendo i segnali all'inizio del ciclo..

bad.alex
intendi signal1 e signal2 definiti in shuffle con quelli all'interno del ciclo for che inizializzo?

apatriarca
Quelli nel for.. sono già stati settati in shuffle, se li cambi non saranno più corretti

bad.alex
Avevi ragione sin dall'inizio di questo post ragione sulla posizione sbagliata di shuffle, e mi dispiace che io abbia compreso soltanto ora il perché :oops:
Grazie mille, apatriarca!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.