Simulação

De Física Computacional
Ir para: navegação, pesquisa
#include<stdio.h>
#include<stdlib.h>
#include<math.h> 

/* declaracao de funcoes */
void passo(FILE *arq);
void inicializacao(FILE *arq);
void atualizar_posicao(void);
int mudar_velocidade(int(v));
int calculo_distancia(void);

/*  declaracao var global   */
#define tempo_max 100
#define num_carros 30
#define comprimento_rua 60
#define veloc_max 6

/*  velocidade: numero de posições   */
/*  que o carro andará num passo     */
int rua[comprimento_rua], vel[num_carros];
int prim_carro, dist;
int i, j, t;

//probab_vel = probabilidade de reduzir a velocidade
double probab_vel = 0.3;

void main(void)
{
	//srand48(time(NULL));
	
	FILE *arq;
	
	arq = fopen("1_lane.dat", "w+");

	inicializacao(arq);
	
	for(t = 0; t < tempo_max; t++)
	{			
		passo(arq);
				
	}
	
	
	fclose(arq);
}

void inicializacao(FILE *arq){

   	// zerando vetores
   	//-1 significa que a posicao esta vazia

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

			rua[i] = -1;
	}
	
	//iniciando os carros - rua[i] representa o indice do carro, atraves do qual acessaremos sua velocidade em vel[rua[i]]
	for(i = 0; i < num_carros; i++)
	{
		vel[i] = 0;
		rua[i*comprimento_rua/num_carros] = i;

	}

	//printando a condição inicial, no terminal e no arquivo
		for (i = 0; i < comprimento_rua; i++){
			if(rua[i] == -1){

			printf(".");
			fprintf(arq, "-1 ");
			
			}
			else{
				printf("%d", vel[rua[i]]);
				fprintf(arq, "%d ", vel[rua[i]]);
			}
		}	
		printf("\n");
		fprintf(arq, "\n");
		
}

void passo(FILE *arq)
{
    i = 0;//posicoes na rua
	prim_carro = -1; //para que caso ainda nao haja um primeiro carro, prim_carro assuma um valor que nao se confunda com nenhum indice de carro (que vao de 0 a num_carros)
		
	while(i < comprimento_rua){

  		/*  Para descobrir a posicao do primeiro carro */
    	/*  tem carro na posição 'i'?          		   */
		
		if (rua[i] == -1){	
	
		/*	não, não tem carro em 'i'	*/
		/*	vai pra prox posicao 'i'   	*/

			i++;
			printf(".");
			fprintf(arq, "-1 ");


		}
	
		else{
	
			/*	caso for o primeiro carro,	*/
			/*	salvar sua posicao para    	*/
			/*	calcularmos a distancia do 	*/
			/*	ultimo carro ao primeiro   	*/

			if(prim_carro == -1){

				prim_carro = i;
			}
				

			//calculando distancia ate o proximo carro

			dist = calculo_distancia();

			//mudando velocidades

			vel[rua[i]] = mudar_velocidade(vel[rua[i]]);
			
			printf("%d", vel[rua[i]]);
			fprintf(arq, "%d ", vel[rua[i]]);

	
			for(j = i+1; (j < i+dist) && (j < comprimento_rua); j++)
			{
				printf(".");
				fprintf(arq, "-1 ");
			}
								
			//atualizando posicoes

			atualizar_posicao();

			//pula para o proximo carro
			i+= dist;	
		}	
	}
	printf("\n");
	fprintf(arq, "\n");
		
}


void atualizar_posicao(void){

	/*	atualiza apenas se a velocidade	*/
	/*	for diferente de zero        	*/

	if( vel[rua[i]] != 0 ){

		//para o ultimo carro, condicoes de contorno periodicas
		if( i + vel[rua[i]] >= comprimento_rua ){

			rua[(i+ vel[rua[i]]) % comprimento_rua] = rua[i];
		}
		else{

			rua[i + vel[rua[i]]] = rua[i];
		}
			
		rua[i] = -1;
	}
				
}




int calculo_distancia(void){

		/*	RETORNA A DISTANCIA ENTRE O	*/
		/*	CARRO 'i' E O QUE ESTA NA   */
		/*	SUA FRENTE NA FAIXA     	*/ 

		/*	caso não for o ultimo carro	*/
		/*	procura posição do prox. e	*/
		/*	calcula a distancia até ele	*/

		/* temos que isolar o caso i = comprimento_rua - 1,		*/
		/*	já que seria j = i + 1 = comprimento_rua, e usamos  */
		/*	rua[j], sendo que j deve ser < comprimento_rua.		*/
		
		if( i + 1 < comprimento_rua ){

			j = i + 1;

			while ( (rua[j] == -1) && (j < comprimento_rua) ){

				j++;	
			}
		
			if ( j != comprimento_rua ){

				dist = j - i;
			}
			
		}
		

		/*	para o ultimo carro a distan-	*/
		/*	cia é calculada em relacao ao	*/
		/*	primeiro, pois são C.C. perio-	*/
		/*	dicas.                       	*/

		//ultimo carro, e existe um primeiro carro
		if( ((i == comprimento_rua - 1) || (j == comprimento_rua)) && (prim_carro != -1)){

			dist = comprimento_rua - (i - prim_carro);
		}	

		//caso so haja um carro ou a pista esteja vazia
		else if(((i == comprimento_rua - 1) || (j == comprimento_rua)) && (prim_carro == -1))
		{
			dist = comprimento_rua;
		}
		return dist;

}

int mudar_velocidade(int(v)){

	int x;
	/*   	RETORNA NOVA VELOCIDADE  	*/	

	/*	            Regra 1         	*/
	/*	caso dê pra acelerar, acelere	*/
	if( ( v < veloc_max ) && ( dist > v + 1 ) ){

		x = v + 1;
	}

	/*	           Regra 2           	*/
	/*	caso pouco espaço, desacelere	*/
	else if( dist < v + 1 ){

		x = dist - 1;
	}
	else
	{
		x = v;
	}
	
	/*	           Regra 3              */
	/*	redução de velocidade randomica	*/
	if( ( x > 0 ) && ( drand48() < probab_vel )){

		x--;
	}
	
	return x;
}