Random walk: gas reticolare

di Anonimizzato29902 il
8 risposte
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

  • 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.
  • 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.
  • 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
  • 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
  • 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...
  • 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?
  • 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.
  • 
    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