蒙特卡洛模拟-蚂蚁爬格子

An ant is trying to get from point A to point B in a grid; see Figure 2. The coordinates of point A is (1,1) (this is top left corner), and the coordinates of point B is (n,n) (this is bottom right corner, n is the size of the grid).

Once the ant starts moving, there are four options, it can go left, right, up or down (no diagonal movement allowed). If any of these four options satisfy the following:

(a) The new point should still be within the boundaries of the n×n grid

(b) Only the center point (4, 4) is allowed to be visited zero, one or two times, while the remainder points should not be visited previously (are allowed to be visited zero or one time).

If P is the probability of the ant reaching point B for a 7×7 grid, use Monte Carlo simulation to compute P. Pick the answer closest to P in value (assume 20,000 simulations are sufficient enough to compute P).

用蒙特卡洛模拟法计算蚂蚁从格子上的点A爬到点B的概率,其中,格子中心点最多只能经过两次,其它点最多只能经过一次。

C语言实现代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#define N 7                        //grid dimension
#define CL 2                       //center point visit limit
/*-------- Global variable -------------------------------------------------------------*/
bool visit_limit[N][N];            /*visit permission flag for all position             */
bool next_step[4];                 /*permission flag of next move                       */
								   /*0 for up, 1 for down, 2 for left, 3 for right.     */
/*---------End of global variable ------------------------------------------------------*/
int nextn_check(int, int);         // function to check amount of option of next move
void move_loop(int *, int *);      //function to simulate every simulation loop
int nextid_generator(int );        //function to select next movement id


int main(void){
	srand((unsigned)time(NULL));   //generate seed for rand function
	int success_count = 0;         //count of loops reach (7,7)
	int x=0, y=0;                  //declare variable for point position
	float p_val=0.0;               //probability result
	for(int i=0; i<20000; i++){    //simulate 20000 loops
		move_loop(&x, &y);         //call functioin to for one loop
		if(x==N-1 && y==N-1) 
			success_count++;       //count loops reach (7, 7)
	}
	p_val = success_count/20000.0; //calculate probability
	printf("P=%f.\n", p_val);
	return 0;
}

/*----------------function to evaluate one loop ---------------------------------------*/
/* Return the stop position coordinate, direactly stored in the input pointer location */
void move_loop(int *stop_x, int *stop_y){
	/*----------- Initiate -----------------------------------------------------*/
	int x=0, y=0;                  //start position of point,  (0, 0)
	int center_visit=0;            //center point visit count.         
	int next_move_id=0;            //selected next move id
	for(int i=0; i<N; i++){
		for(int j=0; j<N; j++){
			visit_limit[i][j]=true;//initiate all visit_limit to true
		}
	}
    /*------------End of initiate------------------------------------------------*/
	int next_step_count =nextn_check(x,y);  //amount of options of next move
	while(next_step_count > 0){
		if(!(x==3 && y==3))            //current position is not center point
		visit_limit[x][y]=false;       //current point can't be visited again
		else{					       //current position is center point
			center_visit++;            //center point visit count increase
			if(center_visit== CL ) visit_limit[x][y]=false; 
		//center position visit permission set to false after visited two times
		}
		//call nextid_generator function to calculate next_move_id
		next_move_id=nextid_generator(next_step_count);
		switch(next_move_id){          //change point position accordint to next_move_id
			case 0: x--; break;
			case 1: x++; break;
			case 2: y--; break;
			case 3: y++; break;
		}
	if(x==N-1 && y==N-1) break;        //reached target position, break while loop
	next_step_count=nextn_check(x,y);  //calculate amount of options of next move 
	}                                  //end of while loop
	*stop_x = x;                       //return x coordinate of stop point
	*stop_y = y;                       //return y coordinate of stop point
}

/*----------------function to calculate amount of options of next move-----------------*/
/* Return amount of options of next move, and set possible move position to true------ */
int nextn_check(int i, int j){
	int res=0;                         //declare and initiate output result variable
	if(i-1>=0 && visit_limit[i-1][j]){
	 res++;
	 next_step[0]=true;                //can move up in next move
	}else next_step[0]=false;
	if(i+1<N && visit_limit[i+1][j]){ 
		res++;
		next_step[1]=true;             //can move down in next move
	}else next_step[1] = false;
	if(j-1>=0 && visit_limit[i][j-1]){ 
		res++;
		next_step[2] = true;           //can move left in next move
	}else next_step[2]=false;
	if(j+1<N && visit_limit[i][j+1]){
	 res++;
	 next_step[3]=true;
	}else next_step[3]=false;          //can move right in next move
	return res;
}

/*----------------function to choose next move id--------------------------------------*/
/* Return selected id of next move --------------------------------------------------- */
int nextid_generator(int n){
	if(n==1){                          //when there is only one option for next move
		for(int i=0; i<4; i++){        //check which one is true
			if(next_step[i])  return i;
		}
	}
	//when there is more than one option for next move
	int n_rand = rand()%n+1;           //generate a random integer
	int i=0;
	for(int k=0; i<4 && k<n_rand; i++){
			if(next_step[i]) k++;      //k is number of true next_step[i]
	}//when k==n_rand, we get the No. n_rand possible move
	return i-1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值