Random walk: gas reticolare

di il
8 risposte

Random walk: gas reticolare

Salve. Non sono molto esperta quindi mi scuso per eventuali strafalcioni. Questo programma ha la pretesa di simulare i cammini aleatori di N particelle in due dimensioni. Impongo che posizionando le particelle nessuna abbia la stessa posizione iniziale(dovrei imporlo anche nel cammino ma non ho ancora bene razionalizzato come procedere quindi posticipo il problema).Simulo il cammino e verso la fine calcolo lo spostamento quadratico medio, ma mi escono dei valori discretamente insensati. Deduco ci siano errori, ma purtroppo non riesco a capire dove. Chi sa aiutarmi? Riporto il codice (è la prima volta che scrivo spero di aver utilizzato il formato giusto).

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
int casuale(int L);
int main(){
  int N,i,k,xa,ya,*x,*y,*xt,*yt,*y0,*x0,L,T,*dr,somma=0,v;
  float drmedio;
  //float d;
  printf("inserire N,L e T interi");
  if(N>L*L){
    printf("N deve essere minore di LxL!\n");
    exit(EXIT_FAILURE);
  }
  scanf("%d",&N);
  scanf("%d",&L);
  scanf("%d",&T);
x=malloc(N*sizeof(int));
y=malloc(N*sizeof(int));
x0=malloc(N*sizeof(int));
y0=malloc(N*sizeof(int));
xt=malloc(N*sizeof(int));
yt=malloc(N*sizeof(int));
dr=malloc(N*sizeof(int));
 if(x==NULL){
   printf("malloc di x fallita\n");
   exit(EXIT_FAILURE);}
 if(y==NULL){
   printf("malloc di y fallita\n");
   exit(EXIT_FAILURE);}
 if(xt==NULL){
   printf("malloc di xt fallita\n");
   exit(EXIT_FAILURE);}
 if(yt==NULL){
   printf("malloc di yt fallita\n");
   exit(EXIT_FAILURE);}
if(x0==NULL){
   printf("malloc di x0 fallita\n");
   exit(EXIT_FAILURE);}
if(y0==NULL){
   printf("malloc di y0 fallita\n");
   exit(EXIT_FAILURE);}
if(dr==NULL){
   printf("malloc di dr fallita\n");
   exit(EXIT_FAILURE);}
   xa=N+1;
   ya=N+1;
srand(time(NULL));
for(i=0;i<N;i++){
  for(k=0;k<=i;k++){
    while(x[k]==xa&&y[k]==ya){
      xa=casuale(L);
      ya=casuale(L);
  x[i]=xa;
  y[i]=ya;
  xt[i]=xa;
 yt[i]=ya;
  x0[i]=xa;
  y0[i]=ya;
    }}}
for(k=0;k<T;k++){
      for(i=0;i<N;i++){  
	v=(rand()/(RAND_MAX));
	if(v<=0.25){
	  x[i]++;
	  xt[i]++;}
	else if(v<=0.5){
	  x[i]--;
	  xt[i]--;}
	else if(v<=0.75){
	    y[i]++;
	    yt[i]++;}
	else{
	  y[i]--;
	  yt[i]--;}
	if(x[i]==L+1){
	  x[i]=0;}
	  if(x[i]==-1){
	    x[i]=L;}
	  if(y[i]==L+1){
	    y[i]=0;}
	  if(x[i]==-1){
	    y[i]=L;}}}
	  for(i=0;i<N;i++){
	    dr[i]=pow((xt[i]-x0[i]),2)+pow((yt[i]-y0[i]),2);
				    somma+=dr[i];}
	      drmedio=somma/N;
	      printf("%f",drmedio);}
				   
	  int casuale(int L)
	  {
	    return (rand()/(RAND_MAX)*L);}
	  

8 Risposte

  • Re: Random walk: gas reticolare

    SEMPLIFICA il codice:

    1) niente patametri da tastiera, ma costanti pre definite. Ci sono mofi piu' intelligenti per passare I parametri da tastiera che leggerli in modo inerattivo ogni volta.

    2) ELIMINA I test sulla riuscita/fallimento dell'allocazione. Hai un pc con GIGABYTE di ram e stai allocando qualche migliaio di byte: praticamente una minuscola MILIONESIMA parte della ram disponibile. Avere problemi a questo livello vuol dire avere SERI PROBLEMI in ben altri luoghi.

    Piu' in generale: il controllo dell'allocazione della memoria viene fatto SOLOA in applicazioni che allocano GRANDI quantita' di memoria, come elaborazione audio/video/immagini. In tutti gli altri casi, di puo' tranquillamente supporre di avere memoria infinita.
  • Re: Random walk: gas reticolare

    Grazie, ma mi serve che legga i parametri in input da tastiera e non conosco altri modi apparte inserirli in fase di compilazione. Per quale ragione è meglio? Poi devo pure mediare i drmedi quindi l'utente deve dirmi su quanti cammini mediare. Per l'allocazione è chiaro, mi sono fidata del mio libro che mi dice di controllare sempre che la memoria sia allocata correttamente.
  • Re: Random walk: gas reticolare

    Intendeva (e sono l'accordo)
    
    int x[N];
    
    Eccetera. Lascia perdere la malloc() per il momento

    Inoltre
    
    if(N>L*L)
    
    Quando chiami questa riga N e L sono indefinite.

    Risolvi tutti questi problemi di base, altrimenti non riuscirai mai a risolvere problemi più complessi
  • Re: Random walk: gas reticolare

    Weierstrass ha scritto:


    Intendeva (e sono l'accordo)
    
    int x[N];
    
    Eccetera. Lascia perdere la malloc() per il momento

    Inoltre
    
    if(N>L*L)
    
    Quando chiami questa riga N e L sono indefinite.

    Risolvi tutti questi problemi di base, altrimenti non riuscirai mai a risolvere problemi più complessi
    Giusto, devo mettere la scanf prima. Per la malloc: è sbagliato? Potreste dirmi dove? Sennò è inutile. E se mi dite che ci sono modi più intelligenti mi potreste dire anche quali dato che non ho idea di come definire l'array se N non è costante?
    int x[N] 
    non è quello che devo fare. Posso fare una prova per vedere se funziona. Devo studiare dr e drmedio al variare dei parametri, metterlo costante implica che devo andare a cambiarlo ogni volta
  • Re: Random walk: gas reticolare

    Che compilatore usi? È una limitazione di più di vent'anni fa quella che dici.

    Comunque anche x[k] è indefinito al primo giro. Con variabili indefinite capisci bene che è inutile analizzare la logica...
  • Re: Random walk: gas reticolare

    Weierstrass ha scritto:


    Che compilatore usi? È una limitazione di più di vent'anni fa quella che dici.

    Comunque anche x[k] è indefinito al primo giro. Con variabili indefinite capisci bene che è inutile analizzare la logica...
    Gcc. Perché è indefinito?
  • Re: Random walk: gas reticolare

    Il punto è: ho premesso che non sono esperta, vi ringrazio delle risposte ovviamente ma se mi dite si può fare in altri modi o non è una limitazione senza approfondire non mi è molto utile.
  • Re: Random walk: gas reticolare

    
    int N;
    scanf(" %d", &N);
    int x[N] = {0};
    
    Così hai un array di N interi inizializzato tutto a zero
Devi accedere o registrarti per scrivere nel forum
8 risposte