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