Newsgroup: it.comp.lang.c
Titolo: Funzione Random

Il mio problema, ringrazio anticipatamente chi mi puņ aiutare, č quello di 
azzerare  n elementi di un vettore (vs) con una funzione random sull'indice, 
cioč l'indice viene generato nell'insieme  0 - dimensione (ramite la 
funzione rand).
La cosa da garantire č che vengano generati esttamente n indici diversi.
La procedura sotto mi va in loop, avete qualche altra strada tenendo fermi i 
seguenti due punti:
1. Generazione esatta di n indici diversi
2.Utilizzo della funzione rand
do
       {
         controllo=0;
         numero=rand()%(dimensione+1);
         for(k=0;k<elementi;k++)
            if(verifica[k]==numero)
               controllo++;
         if (controllo==0)
            {
             verifica[i]=numero;
             i++;
            }
        }
      while(i<n);
for(i=0;i<elementi;i++)
              {
               numero=verifica[i];
               vs[numero]=0;
              }
Ormai sono disperato grazie

se il tuo problema e' generare i numeri da 0 a dimensione
in ordine casuale e senza ripetizioni, allora
basta che prendi un array (che ovviamente avra' dimensione+1 elementi)
tipo
int rai[dimensione+1];
poi ci metti dentro i numeri
for (i=0; i<=dimensione; i++) rai[i]=i;
e poi li mescoli, scambiando
ogni elemento con uno a caso
for (i=0; i<=dimensione; i++)
{
   r=rand()%(dimensione+1);
   t = rai[r];
   rai[r]=rai[i];
   rai[i]=t;
}
v.

In realtà non è questo il problem mi spiego:
Io ho due vettori, vs in cui ci sono 100 elementi, devo generare un vettore 
sparso (cioè la maggior parte dei suoi elementi deve zero), devo mantenere 
un coefficiente di sparsità pari al 70%, cioè 70 elementi di vs devono 
essere 0.
L'imposizione data dalla traccia è quella di generare 70 indici con la 
funzione  rand() definita tra 0 e 100, quindi non posso usare la funzione da 
te, molto gentilmente proposta, perchè inizializzando l'array rai[] così 
come hai fatto tu esclude gli altri 30 indici dalla possibilità di 
generazione, o mi sbaglio?
"vanvera" <van...@acaso.cas> ha scritto nel messaggio 
news:qft0e.1108123$35.41...@news4.tin.it...


non capisco bene...
tu hai 2 vettori di 100 elementi...
nel primo vettore cosa ci devi mettere ?
e nel secondo ? 

 In realtà non è questo il problem mi spiego:
Devo dire che non hai proprio il dono della chiarezza .... :-)
Diciamo che vuoi generare 70 numeri compresi tra 0 e 100 e tutti
diversi tra loro?
Allora fai come ti si e' detto prima, ovvero generi
un array che contiene tutti i numeri da 0 a 100 in ordine
casuale.
Dopo di che, consideri i primi 70 numeri di questo array:
in questo modo avrai 70 numeri tra 0 e 100 e tutti distinti.
Questi numeri saranno, se ho capito bene i, i tuoi indici.
quindi, se in rai[0]...raip[100] ci sono
i numeri da 0 a 100 in ordine casuale, dopo per azzerare
70 posizioni a caso di vs basta che fai
for (i=0; i<70; i++) vs[rai[i]]=0;
g.

questo e' un primo spunto
#include <stdio.h>
#include <stdlib.h>
void main ()
{
 int vs [101], indice;
 for (indice=0;indice<=100;indice++)  // questo ciclo riempie tutto il 
vettore di numeri a caso compresi tra 0 e 100 (o 99 non ricordo bene) //
 {
  vs[indice]=rand()%100;
 }
 /* qui manca la parte che genera dei numeri da 1 a 70
 e riempie le corrispettive caselle del vettore (da 1 a 70)
 di 0, pensa che questa parte tu sia in grado di farla da solo */
 for (indice=0;indice<=100;indice++) // questo ciclo visualizza il vettore 
numero per numero //
 {
  printf ("\n");
  printf ("%d\t%d",indice, vs[indice]);
 }
} 

Partiamo da 0
Problema:
Generare un vettore (vs) sparso di n elementi (il vettore sparso ha la 
maggior parte dei suoi valori uguale a zero)
Memorizzazione a coordinate del vettore sparso: Hai bisogno di due vettori 
D1 e V1
Dove D1 ha come suoi elementi l'indice di vs laddove l'elemento di vs sia 
diverso da 0 e V1 memorizza il valore di vs puntato da D1.
Si deve garantire il coefficiente di sparsità, cioè il 30%, ciò significa 
che su 100 elementi solo 30 non dovranno essere 0 quindi la dimensione di D1 
e V1 è 30
1. Generazione degli elementi di vs sull'insieme [-1;1]
 for (i=0; i<100;i++)
      {
       srand((int)i);
       x_numero_casuale=-1.0F+2.0F*(float)rand()/(float)RAND_MAX; 
/*Assegnazione di numeri casuali al vettore*/
       if(x_numero_casuale==0)conta++;
       vs[i]=x_numero_casuale;
      }
Tale ciclo genera in modo casuale il vettore vs (il ciclo può assegnare 
anche valori 0 ovviamente) facendomi perdere il vincolo del coefficiente di 
sparsità (Primo problema)
2. Generazione di 30 indici in modo rand()
for(i=0;i<nz;i++)
       {
         srand((int)i);
         numero= rand()%(dimensione+1);
         D1[i]=numero;
       }
Questo ciclo spesso genra lo stesso indice (secondo problema) facendomi 
perdere il vincolo del coefficiente di sparsità.
Grazie
Bibop 

 perdere il vincolo del coefficiente di sparsità.
altro problema facilmente risolvibile... risolvibile in 2 modi:
-    immettendo l'istruzione srand ( (unsigned) time(NULL)); e la libreria 
time.h potrai generare 70 indici diversi in cui inserire 0...
-    in maniera piu' semplice far generare l'indice, tenerne traccia, 
controllare se contiene 0 e, tramite la traccia, controllare se ogni indice 
e diverso dall'altro...
sinceramente ti consiglio la prima, piu' semplice e meno laboriosa 
macchinosa...
se hai ancora problemi non esitare a scrivere sul NG... ciao...

 ciclo=dimensione-nz;
      do
       {
         srand ((unsigned) time(NULL));
         numero= rand()%(dimensione+1);
         printf("%d numero", numero);
         vs[numero]=0;
         i++;
       }
       while (i<ciclo);
Continu a generarmi sempre lo stesso indice.........

 srand ((unsigned) time(NULL));
      for(i=0;i<nz;i++)
       {
         numero= rand()%(dimensione+1);
         nnull[i]=numero;
       }
Ok così funziona mi genera gli indici diversi grantendomi il coefficiente di 
sparsità.
Adesso sono talmente fuso che non so come assegnare 0 alla restante parte di 
vs

ciclo per riempire tutto il vettore di numeri casuali
srand ((unsigned) time (NULL));
 for (indice=0;indice<=100;indice++)
 {
  while ((vs[indice]>100)||(vs[indice]<=0))
  {
   vs[indice]=rand()%100;


il programma quasi completo e' questo:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void main ()
{
 int vs [101], indice ,contatore;
 for (indice=0;indice<=100;indice++)
 {
  while ((vs[indice]>100)||(vs[indice]<=0)) // cosi sei sicuro che non ci 
siano ne 0 ne numeri negativi //
   vs[indice]=rand()%100;
 }
 printf ("\n");
 printf ("\n\tvettore con numeri casuali\n");
 for (indice=0;indice<=100;indice++)
 {
  printf ("\n");
  printf ("%d\t%d",indice, vs[indice]);
 }
 for (indice=0, contatore=0;contatore<70;contatore++)
 {
  while ((vs[indice]>100)||(vs[indice]<0))
  {
   indice=rand()%100;
   vs[indice]=0;
  }
 }
 printf ("\n");
 printf ("\n\tvettore con inserimento 0\n");
 for (indice=0;indice<=100;indice++)
 {
  printf ("\n");
  printf ("%d\t%d",indice, vs[indice]);
 }
}
il problema e' che non butta dentro gli 0, non capisco perche'...
risolvi tu 

Penso di aver risolto, guarda un po'
Questo è il programma completo, devo un esame all'università e ho buttato il 
sangue, ti ringrazio per i tuoi suggerimenti, se trovi qualcosa che non va 
ti prego di farmelo sapere, a fine listato ti inserisco anche la traccia del 
problema.
Ancora grazie
Bibop
/* vs: Vettore Originale
   D1: Vettore Indice
   V1: Vettore Elementi non Null
   dimensione: Elementi totali di vs
   nz: Elementi non Null di vs                     */
void caricamento(void);
void assegna_null(void);
void ordina(void);
void stampa(void);
int nz,dimensione;
float vs[100];
int D1[30];
float V1[30];
int main()
{
   printf ("Inserire il numero degli elementi del vettore \n");
   scanf("%d",&dimensione);
   if (dimensione==100 || dimensione==50 || dimensione==80)
   {
      nz=dimensione*30/100;
      caricamento();
      assegna_null();
      ordina();
      stampa();
   }
   else
     {
      printf("Inserire 100 o 80 o 50 \n")  ;
     }
      system("PAUSE");
      return 0;
}
/*Tale procedura caricano il vetore vs di elementi casuali e non null*/
void caricamento (void)
 {
   float x_numero_casuale;
   int i,indice;
   srand ( (unsigned) time(NULL));
   i=0;
  do
        {
        /*Generazione di numeri casuali */
         x_numero_casuale=-1.0F+2.0F*(float)rand()/(float)RAND_MAX;
         /*Per garantire che non vengano inseriti valori null che 
potrebbero*/
                  /*Alterare il coefficiente di sparsità*/
         if (x_numero_casuale!=0)
             {
              vs[i]=x_numero_casuale;
              i++;
             }
        }
   while(i<dimensione);
 }
/*In questa procedura si provvede a generare in modo casuale gli indici */
/*del vettore D1*/
void assegna_null(void)
 {
    int i,numero,k, controllo;
    /*int nnull[70]; */
     /*La funzione srand così inizializzata serve a garantire la 
generazione*/
    /*di indici diversi le funzioni rand e srand vanno usate insieme per 
garantire*/
   /*la casualita degli elementi generati*/
     srand ((unsigned) time(NULL));
      for(i=0;i<nz;i++)
       {
         numero= rand()%(dimensione);
         D1[i]=numero;
         for(k=0;k<i;k++)
            if(numero==D1[k])
              i--;
       }
  /*Azzera gli elementi di vs che non sono puntati da D1*/
      for(k=0;k<dimensione;k++)
         {
          controllo=0;
          for(i=0;i<nz;i++)
             if(k==D1[i])controllo++;
          if(controllo==0)
            vs[k]=0;
         }
      for (i=0;i<nz;i++)
           V1[i]=vs[D1[i]];
     system("PAUSE");
  }
/*Procedura di ordinamento per scambio oltre a due variabili appoggio    */
/*ho dovuto usare anche un vettore di appoggio per garantire l'ordinamento 
su D1    */
/*in base a V1    */
void ordina (void)
  {
    int i,k,appoggio;
    float app[30];
    float appoggio1;
    for (i=0;i<nz;i++)
        app[i]= V1[i];
    for (i=0;i<nz-1;i++)
     {
        for(k=i+1;k<nz;k++)
           {
            if (app[k]<app[i])
               {
                appoggio=D1[k];
                D1[k]=D1[i];
                D1[i]=appoggio;
                appoggio1=app[k];
                app[k]=app[i];
                app[i]=appoggio1;
               }
           }
     }
  }
 /*Output dei vettori manipolati   */
 void stampa (void)
  {
   int i;
   printf("Vettore Originale \n");
   for (i=0;i<dimensione;i++)
       {
        printf("%1.3f    Indice %d   ", vs[i],i);
        printf("\n");
       }
   printf("\n Vettore D1 elemento \n");
   for (i=0;i<nz;i++)
       printf("%d ",D1[i]);
   printf("\n Vettore V1 \n");
   for (i=0;i<nz;i++)
       printf("%1.3f ",V1[i]);
   printf("\n");
  }
Traccia
  1.. algoritmo per generare un vettore sparso di float, memorizzato nel 
formato a coordinate. Il numero complessivo n di componenti del vettore 
(componenti nulle e non nulle) è un dato di input. L'algoritmo genera 
direttamente la rappresentazione a coordinate del vettore sparso. Il formato 
a coordinate memorizza un vettore utilizzando due array 1D, uno di tipo 
float per i valori degli elementi non nulli del vettore e l'altro di tipo 
int per gli indici degli elementi non nulli. Entrambi gli array hanno nnz 
componenti, dove nnz è il numero di componenti non nulle del vettore. Usare 
la function rand(), il cui prototipo è in  <stdlib.h>, per generare gli 
elementi non nulli del vettore (devono essere numeri float  nell'intervallo 
[-1,1]): si ricorda che, se x_numero_casuale è dichiarata di tipo float, 
allora l'istruzione
x_numero_casuale=-1.0F+2.0F*(float)rand()/(float)MAX_RAND;
genera un numero casuale float (distribuzione uniforme) nell'intervallo 
[-1,1].  Gli indici degli elementi non nulli del vettore sono anch'essi 
casuali (numeri interi  nell'insieme 0,1,2,...,n): si ricorda che, se 
i_numero_casuale è dichiarata di tipo int, allora la chiamata;
i_numero_casuale=rand()%(n+1); genera un numero casuale intero 
(distribuzione uniforme) nell'insieme (0,1,2,..,n).  L'array 1D degli indici 
deve poi essere ordinato. Nei test usare vettori con un numero di componenti 
n (compresi gli elementi nulli) pari a 50, 80, 100. Il coefficiente di 
sparsità dei vettori da usare nei test deve essere del 70%, ovvero i due 
array 1D per la rappresentazione avranno solo il 30% di elementi rispetto al 
numero n di componenti del vettore.

 problema.
ora che hai dato la traccia il problema e' chiaro (e anche molto
semplice).
Putroppo la tua soluzione e' sbagliata, non so praticamente,
ma sicuramente concettualmente lo e' (io all'esame ti segherei....),
perche' ad esempio, tu allochi tutto il vettore pieno, e poi
lo sparsifichi. Questo in generale e' assurdo, visto
che i vettori sparsi servono proprio per non sprecare memoria
e nel testo si richiede esplicitamente di usare degli array
dimensionati opportunamente in base al numero di elementi
non nulli.
Cioe' gli array sparsi si memorizzano in questo modo:
supponi di avere un array di un milione di posizioni,
nel quale solo le posizioni di indice 11, 33444 e 578000 sono
diverse da zero e valgono rispett. 0.2133 0.9999 1.35353
allora i tue due vettori che rappresentano il vettore sparso
devono avere 3 elementi ciascuno
ind[0]=11
ind[1]=33444
ind[2]=578000
e i valori sono memorizzati analogamente
val[0]=0.2133
val[1]=0.9999
val[2]=1.35353
Stai inoltre attento ad inizializzare con srand solo una volta.
Prova a capire questo listato che sicuramente e' piu' vicino
a quello che ti chiedono:
(ho ignorato il test sul fatto che il numero generato sia
uguale a 0 perche' tanto statisticamente e' una eventualita'
molto scarsa).
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
float *val;
int   *ind;
/* usata per il sort con qsort */
int comp(const void *a, const void *b)
{
   return *((int *)a) - *((int *)b);
}
int main(int argc, char *argv[])
{
   int i,j,nonzeri, ntot;
   /* inizializzo i numeri casuali
      UNA SOLA VOLTA ALL'INIZIO DEL PROGRAMMA */
   srand(time(0));
   /* controllo se mi e' stato passata la
      dimensione a linea di comando */
   if (argc<2) exit(0);
   /* dimensione totale array e controllo */
   ntot = atoi(argv[1]);
   if (ntot!=50 && ntot !=80 && ntot!=100) exit(0);
   /* calcolo dimensione sparsa */
   nonzeri=(ntot*30)/100;
   /* alloco SOLO gli elementi necessari */
   val=malloc(sizeof(float)*nonzeri);
   ind=malloc(sizeof(int)*nonzeri);
   /* controllo (inutilmente...) se ho allocato bene */
   if (!val || !ind) exit(0);
   /* genero i valori non nulli */
   for (i=0; i<nonzeri;i++)
     val[i]=-1.0+2.0*(float)rand()/(float)RAND_MAX;
   /* genero gli indici, controllando via via
      che siano tutti diversi */
   i=0;
   while (i<nonzeri)
     {
       ind[i]=rand()%ntot;
       for (j=0; j<i;j++) if (ind[i]==ind[j]) break;
       if (j==i) i++;
     }
   /*ordino gli indici usando la qsort (in stdlib) */
   qsort(ind,nonzeri,sizeof(int),comp);
   /* stampo il vettore sparso */
   for (i=0; i<nonzeri; i++)
     printf("%3d -> %8.5f\n",ind[i],val[i]);
   return 0;
}

Forse hai usato delle funzioni che per un esame di Programmazione I ancora 
non sono state fatte (argv etc).
Non volevo espormi su un ng dove magari anche il professore poteva essere 
iscritto, ma considerando che alla fine la soluzione l'ho travata con 
qualche aiuto del gentilissimo Fabio ho potuto inserire sia traccia che 
soluzione.
Grazie comunque
Bibop 

come ultima cosa in bocca al lupo per l'esame...
p.s.: stasera apro un thread, visto che ho un problema con un programma su 
code e liste, e non riesco a risolverlo...
magari mi puoi dare una mano... 

 ha scritto nel messaggio 
news:MOD0e.20245$kC3...@tornado.fastwebnet.it...
