Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda bad.alex » 06/04/2017, 16:46

Ciao ragazzi.
Vi espongo il mio problema: sto costruendo una rete in cui ho 20 vertici. Questi vertici sono gli alunni di una classe. La maestra assegna a 5 di loro -scelti casualmente- un tema ("La prima guerra mondiale", che indichiamo con PGM) mentre ai restanti assegna come tema "La seconda guerra mondiale" (SGM). Questi alunni sono "tentati" dal passarsi il compito tra di loro: per questo motivo occorre verificare se svolgeranno oppure no lo stesso tema.

Ho pensato di risolverlo in questo modo, ma non so se può andare bene: creo il mio grafo di dimensione DIM 20 e inserisco da tastiera il numero di vertici (20). Ho quindi la rete[DIM][DIM].
Scelgo casualmente 5<DIM di loro, ricorrendo a un ciclo for. Tuttavia, se scrivo in questo modo

Codice:
for(i=0;i<5;i++){
alunni_PGM[i]=(rand()%5)+1;
 }
(richiamando srand() nel main).

non sto forse assegnando dei valori casuali, senza selezionare casualmente questi alunni dalla mia rete?
Infine, come dovrei assegnare a loro il tema e verificare se hanno lo stesso tema oppure no con i loro primi vicini? Pensavo naturalmente ad uno switch, ma non riuscendo a selezionare questi 5 alunni diciamo che sono soltanto parole al vento :oops:

I vostri consigli mi saranno certamente di grande aiuto, giusto per capire come impostare il problema e quali statements saranno fondamentali per poterlo impostare.

Alex
bad.alex
Senior Member
Senior Member
 
Messaggio: 1061 di 1283
Iscritto il: 10/01/2007, 19:01

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda apatriarca » 06/04/2017, 17:55

Stai scegliendo numeri casuali in \(\{0, 1, 2, 3, 4\},\) non \(5\) nodi (i cui identificativi vanno da \(0\) a \(19\)).
apatriarca
Moderatore
Moderatore
 
Messaggio: 4587 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda bad.alex » 07/04/2017, 02:33

Era ciò che sospettavo.
Quindi per poter selezionare casualmente 5 alunni all'interno della rete e assegnare loro il tema 1 così da confrontarli con gli altri studenti, su cosa dovrei lavorare? Sul vettore alunni oppure sull'indice?
Io e le azioni 'random' siamo ancora dei perfetti sconosciuti.
bad.alex
Senior Member
Senior Member
 
Messaggio: 1062 di 1283
Iscritto il: 10/01/2007, 19:01

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda apatriarca » 07/04/2017, 10:19

Ho appena notato che c'era anche il "+1", per cui i valori erano in effetti da 1 a 5. In ogni caso erano sbagliati. Crea un array di lunghezza pari al numero dei nodi inizializzato a 0 (no tema). A questo punto scegli valori nell'intervallo corretto usando rand()%20 e assegna il tema uno agli indici che hai scelto. L'unica cosa a cui devi prestare attenzione è quella di non assegnare il tema a persone a cui è già stato assegnato un tema.. In alternativa, se ogni persona deve avere un tema puoi usare uno "shuffle" su un array inizializzato con il corretto numero di valori per ogni tema.
apatriarca
Moderatore
Moderatore
 
Messaggio: 4588 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda bad.alex » 07/04/2017, 10:55

Quindi, vediamo se è corretto in questo modo:

[EDIT]
Codice:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{

int alunni[20]={0}
int i, random;

srand(time(NULL));

for(i=0;i<20;i++){
random=alunni[rand()%20] // In questo passaggio dovrei assegnare alla variabile random un alunno scelto casualmente (l'indice viene scelto con rand()]

}
return 0;

}



Per quanto riguarda l'assegnazione dei temi, non ho ben capito come fare (sempre che questa parte vada bene). Più che altro non mi è chiaro come assegnare a 15 di loro il tema A e agli altri 5 il tema B, se scelti casualmente. Ricorrendo ad un ciclo for, avrei potuto/potre assegnare direttamente a 15 studenti il tema A, ma penso occorra capire prima quali sono gli indici a cui toccherà svolgere un particolare tema :?
bad.alex
Senior Member
Senior Member
 
Messaggio: 1063 di 1283
Iscritto il: 10/01/2007, 19:01

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda apatriarca » 07/04/2017, 11:14

L'idea principale è quella di creare una array di 20 elementi, in cui i primi 15 valori hanno valore uguale ad 'A' (o qualsiasi altro valore che indica il tema) e i restanti 5 avranno valore 'B'. A questo punto puoi mischiare il tuo array usando l'algoritmo Fisher-Yates Shuffle e avrai un array in cui per ogni nodo/indice hai un valore uguale ad 'A' o 'B' con la frequenza che desideri e distribuiti in modo casuale.
apatriarca
Moderatore
Moderatore
 
Messaggio: 4589 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda bad.alex » 07/04/2017, 11:32

Non conoscevo questo algoritmo. Ti ringrazio!

Quindi, ricapitolando:

Codice:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DIM 20

int main()
{
int alunni[DIM]={0};
int i;

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

printf("Assegna il tema A a 15 alunni");
temaA=alunni[i];

printf("Tema A assegnato all'alunno %d\n", alunni[i]);
}

for(i=0;i<20;i++){
for(j=i+1;j<20;j++)
{
if (alunni[i]==alunni[j]) {printf("L'alunno %d e l'alunno %d svolgeranno lo stesso tema\n", alunni[i], alunni[j]);}
else { temaB=alunni[j];
printf("L'alunno %d svolgerà il tema B\n", alunni[j]);}

}

return 0;
}


Mi sono fermato prima dello shuffle, sempre che vada bene quanto ho scritto naturalmente, perché sto cercando di capire come funziona.

[EDIT]
Se volessi considerare temaA come un vettore composto da tutti gli alunni selezionati, cosa dovrei fare? Perché il passo successivo dovrebbe consentirmi di vedere se l'alunno i ha lo stesso tema dei suoi primi vicini ( e penso che questo si debba fare con un ciclo for del tipo:

Codice:
for(int i=0; i<20; i++) {
for(int j=i+1;j<20;j++){

if (alunno[i]==alunno[j]) printf("Gli alunni %d e %d hanno lo stesso tema\n", i, j);


Tuttavia, essendo una rete, come faccio a sapere quanti primi vicini ha (ovvero quelli con cui è collegato da un edge? Questo, ancora ora, resta un problema incomprensibile per me :(
bad.alex
Senior Member
Senior Member
 
Messaggio: 1064 di 1283
Iscritto il: 10/01/2007, 19:01

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda apatriarca » 09/04/2017, 19:32

Il codice che hai scritto non ha molto senso:
1. temaA, temaB e j non sono stati dichiarati da nessuna parte.
2. alunni[i] e alunni[j] hanno inizialmente valore 0, che senso ha assegnare tale valore alle variabili temaA o temaB?
3. Non è chiaro cosa dovrebbero fare temaA e temaB..
4. Manca una parentesi graffa.

Il codice che avevo in mente era qualcosa come il seguente:
Codice:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// Restituisce un intero tra 0 and high-1.
// Rimuove la mancanza di uniformità presente nel codice rand()%high.
int rand_range(int high)
{
    int remainder = RAND_MAX % high;
    for (;;) {
        int r = rand();
        if (r < (RAND_MAX - remainder)) { return r % high; }
    }
}

int main(void)
{
    // Inizializza il tema degli alunni (15 'A' e 5 'B')
    // Ho usato una stringa per comodità, ma ho quindi avuto bisogno di
    // aggiungere un carattere alla fine per il terminatore di stringhe..
    // Puoi usare un array di interi e inizializzare diversamente.
    char alunni[21] = "AAAAAAAAAAAAAAABBBBB";
   
    // Inizializza il generatore di numeri casuali
    srand((unsigned)time(NULL));

    // Algoritmo di Fisher-Yates per assegnare casualmente i compiti
    for (int i = 19; i > 0; --i) {
        int j = rand_range(i+1); // 0 <= j <= i
        char tmp = alunni[i];
        alunni[i] = alunni[j];
        alunni[j] = tmp;
    }

    for (int i = 0; i < 20; ++i) {
        printf("Alunno %d fa il tema %c\n", i+1, alunni[i]);
    }
}
apatriarca
Moderatore
Moderatore
 
Messaggio: 4590 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda bad.alex » 09/04/2017, 21:43

Ti ringrazio, apatriarca. Sebbene io abbia impiegato due giorni per arrivarci, sono riuscito a riscriverlo in questo modo:
Codice:
int rand_int(int num_alunni){
    int limit=RAND_MAX-RAND_MAX%num_alunni;
    int rnd;
   
    do{
        rnd=rand();
    }while(rnd>=limit);
    return rnd%num_alunni;
     }
}



Codice:
for(i=DIM-1;i>0; --i) //Algoritmo di Fisher-Yates
{
    j=rand_int(i+1);
    temp=alunni[j];
    alunni[j]=alunni[i];
    alunni[i]=temp;
   
}
printf("\n Array dopo lo shuffle: \n");
for(i=0; i<DIM; i++){
printf("L'alunno %d ha il tema %d\n", i+1, alunni[i]);
}


Da quanto ho visto, differisce nella definizione della funzione (ma avevo cercato su internet qualcosa che la spiegasse) e per gli indici nel ciclo for.
Volendo adesso considerare soltanto quei cinque alunni, per poterli successivamente confrontare con gli altri 20, come posso effettuare i cicli for (per quanto riguarda gli indici i/j)?
bad.alex
Senior Member
Senior Member
 
Messaggio: 1065 di 1283
Iscritto il: 10/01/2007, 19:01

Re: Assegnare un tema ad un numero di alunni scelti casualmente [C]

Messaggioda apatriarca » 10/04/2017, 14:12

Devi semplicemente iterare su alunni e se trovi il tema B allora fai quello che desideri con tale tema.
apatriarca
Moderatore
Moderatore
 
Messaggio: 4591 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite