Velocidade média em função da velocidade máxima

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

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

/*  declaracao var global   */
#define tempo_max 100
#define num_carros 10
#define comprimento_rua 100

//maximo valor que a velocidade maxima assume
#define veloc_max_max 40

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

//z_max = numero de amostragens
int z, z_max = 100000;

//probab_vel = probabilidade de reducao da velocidade
double probab_vel = 0.3;

//print: precisamos primeiro coletar todos os resultados, fazermos a media, para so entao printarmos
double print[veloc_max_max], v_media;

void main(void)
{
	//srand48(time(NULL));
	
	FILE *vm;
	char arq[30];
	sprintf(arq, "1_lane_v_med_max_dens_0%.0lf.dat", 10*((double)num_carros)/comprimento_rua);
	vm = fopen(arq, "w+");

	for(veloc_max = 0; veloc_max < veloc_max_max; veloc_max++)
	{
		print[veloc_max] = 0;
	}

	for(z = 0; z < z_max; z++)
	{

		for(veloc_max = 1; veloc_max < veloc_max_max; veloc_max ++)
		{
			v_media = 0;
			inicializacao();
		
			for(t = 0; t < tempo_max; t++)
			{			
				passo();
					
			}
			
			//calculo da velocidade media
			for(j = 0; j < num_carros; j++)
			{
				v_media += vel[j];
			}
			v_media /= num_carros;
			print[veloc_max] += v_media;
		
		}
	}
	
	for(veloc_max = 1; veloc_max < veloc_max_max; veloc_max++)
	{
		fprintf(vm, "%d %lf\n", veloc_max, print[veloc_max]/z_max);
	}
	
	fclose(vm);
}

void inicializacao(void){

   	// 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;

	}
	
		
}

void passo(void)
{
	
    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++;
				
		}
	
		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]]);
								
			//atualizando posicoes

			atualizar_posicao();

			//pula para o proximo carro
			i+=dist;	
		}	
	}
		
}


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 'x'    	*/ 

		/*	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 j = i + 1 = comprimento_rua, e usamos   */
		/*	rua[j], sendo que j < 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;
}