醉酒螳螂问题

醉酒螳螂问题
        记得去年上概率论的时候最后一章讲述的是马尔科夫过程,当时只会做题。完全不知道这是干甚么。其实就是矩阵的遍历性问题。今天介绍的醉酒螳螂也是关于遍历性的问题。
        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 MAX 5000
//房间的长和宽
#define X 10
#define Y 10
#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值