首页 > 代码库 > 醉酒螳螂问题

醉酒螳螂问题

醉酒螳螂问题
        记得去年上概率论的时候最后一章讲述的是马尔科夫过程,当时只会做题。完全不知道这是干甚么。其实就是矩阵的遍历性问题。今天介绍的醉酒螳螂也是关于遍历性的问题。
        1.问题叙述:
            在矩形的房间里,铺有m * n块瓷砖,现将一只(醉酒的)螳螂放在地板中间一个指定的方格里,螳螂在房间中随机的从一块瓷砖漫步到另一块瓷砖(可能是在找一块奶酪,呵呵)。假设它可能从其他所在的瓷砖移动到其周围八块瓷砖中的任何一块(除非碰到墙壁),那么它至少接触每块瓷砖一次,将花费多少时间?
       2. 强调:
            这个算法有什么用?使用计算机解决此问题的技术称为模拟,这种技术广泛应用于工业中,用来预测运输流量,存货控制等问题。
      3.解决思路:
            用一个m * n数组作为计数器来表示螳螂到达每一块瓷砖的次数,每个数组单元的初始化值均为0,螳螂在地板的位置用坐标表示(x, y)(可以直接用整型值,也可以用结构体,二者随意),则螳螂的八种可能移动用(x + xmove[choose], y + ymove[choose])的瓷砖表示,其中0 <= choose <= 7,    并且:
                    xmove[0] =   -1          ymove[0] =  1
                    xmove[1] =   0          ymove[1] =   1
                    xmove[2] =    1         ymove[2] =   1
                    xmove[3] =    1         ymove[3] =   0
                    xmove[4] =     1        ymove[4] =  -1
                    xmove[5] =      0       ymove[5] =  -1
                    xmove[6] =     -1        ymove[6] =  -1
                    xmove[7] =     -1        ymove[7] =   0  
           螳螂向其相邻的八个方格的随机漫步通过产生一个随机数choose来模拟,而且,螳螂不能爬出房间,螳螂每进入一次方格,该方格计数器加1,当所有的方格全部为非零时,说明螳螂已经遍历完整个矩阵,是不是和马尔科夫过程非常像的。。。。
            

4.代码如下:


#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

//总共移动的最多次数
#define MAX5000
//房间的长和宽
#define X10
#define Y10
#define NOTEND-1

int matrix[X][Y];

int judgeMatrixEnd(void);//判断矩阵是否每个方格进入一次
void showMatrix(void);//显示矩阵

void showMatrix(void)
{
    int i, j;

    for(i = 0; i < X; i ++)
    {
        for(j = 0; j < Y; j++)
            printf("%3d", matrix[i][j]);
        printf("\n");
    }
}

int judgeMatrixEnd(void)
{
    int i, j;

    for(i = 0; i < X; i++)
        for(j = 0; j < Y; j++)
        {
             if(matrix[i][j] <= 0)
                 return NOTEND;//没有结束
        }

    return END;//结束
}

int main(void)
{
    int x, y;
    int moveCount = 0;//移动次数
    clock_t start = 0, end = 0;//移动起始和终止时间
    double moveTime;//移动时间
    int choose;//选择的方向
    int lastx, lasty;//最后一次合理的坐标

    //下面的两个数组成对出现代表着随机点对应的八个方向
    int xmove[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
    int ymove[8] = {1, 1, 1, 0, -1, -1, -1, 0};
    /* 右  右 右 下 左  左  左  上
      上  边 下 边 下  边  上  边
     */ 
    memset(matrix, 0, sizeof(matrix));//把矩阵初始化为0
    x = rand() % X;//随机定位横坐标
    y = rand() % Y;//随机定位纵坐标
    matrix[x][y]++;//随机定位的次数加1
    showMatrix();
    //当某个位置出现的次数超过最大次数或者每个方格至少进入一次时,实验结束
    while(moveCount < MAX && judgeMatrixEnd() == NOTEND)
    {
        choose = rand() % 8;

        //蟑螂的移动位置不能超过四个边界
        if(x + xmove[choose] >= 0 && y + ymove[choose] >= 0
        && x + xmove[choose] < X && y + ymove[choose] < Y)
        {
             //改变蟑螂的位置
              x += xmove[choose];
              y += ymove[choose];
              matrix[x][y]++;//该位置次数加1
             //保存当前坐标
             lastx = x;
             lasty = y;
        }
        else
        {
             //如果不合理则返回到上一次位置
             x = lastx;
             y = lasty;
             continue;
        }

        system("CLS");
        showMatrix(); 
       moveCount++;
    }
 
    end = clock();

    moveTime = (double)(end - start) / CLK_TCK;
    printf("\n移动的次数为:%d", moveCount);
    printf("\n所花费的时间为:%lf", moveTime);
    getch();
    return 0;
}