本文主要是介绍“随机漫步”(Random Walk)模拟演示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
(1)、任务描述
有一类问题总称为“随机漫步”(Random Walk)问题,这类问题长久以来吸引着数学界的兴趣。所有这些问题即使是最简单的解决起来也是极其困难的。而且它们在很大程度上还远没有得到解决。一个这样的问题可以描述为:
在矩形的房间里,铺有n×m块瓷砖,现将一只(醉酒的)蟑螂放在地板中间一个指定方格里。蟑螂随机地从一块瓷砖“漫步”到另一块瓷砖(可能是在找一片阿司匹林)。假设它可能从其所在的瓷砖移动到其周围八块瓷砖中的任何一个(除非碰到墙壁),那么它把每一块瓷砖都至少接触一次将花费多长时间?
虽然这个问题可能很难用纯粹的概率技术来解决,但是使用计算机的话却十分容易。使用计算机解决此问题的技术称为“模拟”。这种技术广泛应用于工业中,用来预测运输流量,存货控制等等。
现在,利用所学的C语言程序设计和数据结构基础知识,建立一个“随机漫步”(Random Walk)模拟演示系统,并将得到的模拟结果(模拟产生的数据)保存,以供研究使用。
(2)、设计目的
利用二维数组解决复杂的实际问题;了解实际问题到计算机问题的转化;了解算法设计中边界条件的重要性。
(3)、基本要求
程序必须满足:
①能够处理所有的n和m值, n和m满足:2<n≤40,2≤m≤20;
②能够对“n = 15,m = 15,起始点为(10,10)”和“n = 39,m = 19,起始点为(1,1)”进行实验。
③具有迭代限制,即实验过程中蟑螂进入方块的最大次数为MAX =50000时,程序能够终止。
对于每次试验,打印:
①蟑螂进行的合法移动的总次数。
②最终的计数器数组,显示出漫步的“密度”,即输出在实验中每一块瓷砖被接经过的次数。
代码清单:
(1)MAIN.cpp
#include <iostream>
using namespace std;#include "RandWalk.h"int main(void)
{RandWalk();system("PAUSE");return 0;
}
(2)RandWalk.h
#ifndef RANDWALK_H_INCLUDED
#define RANDWALK_H_INCLUDED
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h> //头文件区#include "Operation.h"
#include "Simulate.h"void RandWalk(void)
{//功能:进入Rand Walk模拟演示系统,选择操作system("color 0E");bool quit = false;while(!quit){system("cls");menu();int choose;scanf("%d",&choose);switch(choose){case 1:displayExplanation();break;case 2:quit = simulate();break;case 3:quit = true;break;default:printf("\t您的输入不合法!\n\t ");system("PAUSE");break;}}
}#endif // RANDWALK_H_INCLUDED(3)Operation.h
#ifndef OPERATION_H_INCLUDED
#define OPERATION_H_INCLUDED#define PREINSTALL_SIZE 10000void menu(void)
{//功能:打印菜单puts(" 欢迎进入\"Random Walk\"模拟演示系统:");puts("\t\t===================================================");puts("\t\t_1.查看演示说明.");puts("\t\t_2.进行模拟演示.");puts("\t\t_3.对此演示不感兴趣,退出程序.");puts("\t\t====================================================");printf(" 输入序号,进行选择:");
}void displayExplanation(void)
{//操作:读取文件displayExplanation.txt//功能:对Random Walk模拟演示系统进行解释说明FILE* fp = fopen("displayExplanation.txt","rw");if(!fp){fprintf(stderr,"EEOR:打开文件出错!\n");exit(EXIT_FAILURE);}char Exp[PREINSTALL_SIZE],ch;int index = 0;while(ch = fgetc(fp),ch != EOF)Exp[index++] = ch;MessageBox(NULL,TEXT(Exp),TEXT("演示说明:"),0);fclose(fp);
}void inputPrompt(void)
{puts("\t地板上铺有n×m块瓷砖,请您确定m、n的值:");printf("\t注:n和m满足:<n≤,≤m≤: ");
}#endif // OPERATION_H_INCLUDED
(4)Simulate.h
#ifndef SIMULATE_H_INCLUDED
#define SIMULATE_H_INCLUDED#define ITERATIVE_MAX 50000 //迭代限制struct coordinate
{//功能;确定对象的坐标位置int x,y;
};struct layout
{//功能:表示矩形的房间,并将模拟得到的数据保存于二维数组中int length,width;int **array;//二维数组计数器
};struct situation
{//功能:表示当前时刻模拟系统所处的局面情形struct layout tile; //漫游布局struct coordinate position; //对象所处位置int passed; //已走过的瓷砖数目int iteration; // 迭代限制
};void InitLayout(struct layout &e)
{//功能:初始化二维数组计数器e.array,使其初始值均为e.array = (int**)calloc(e.length,sizeof(int*));for(int i = 0; i < e.length; ++i){e.array[i] = (int*)calloc(e.width,sizeof(int));for(int j = 0; j < e.width; ++j)e.array[i][j] = 0;}
}void DestoryLayout(struct layout &e)
{//功能:销毁结构体e,释放初始化过程中申请的内存if(!e.array){for(int i = 0; i < e.length; ++i)free(e.array[i]);free(e.array);}e.array = NULL;e.length = e.width = 0;
}bool judgePosition(struct coordinate p,struct layout l)
{//功能:判断蟑螂的坐标位置是否合法//若合法,返回true;否则,返回falseif(p.x < 0 || p.y < 0 || p.x > l.width || p.y > l.length)return false;elsereturn true;
}void InitSituation(struct situation &e)
{//操作:提示并输入蟑螂所在坐标位置(x,y)//功能:初始化当前时刻模拟系统所处的局面情形inputPrompt();scanf("%d%d",&e.tile.length,&e.tile.width);InitLayout(e.tile);printf("\t请输入蟑螂所在坐标位置(x,y): ");scanf("%d%d",&e.position.x,&e.position.y);while(!judgePosition(e.position,e.tile)){printf("\t您输入的值不合法!\n\t请重新输入坐标位置(x,y):");scanf("%d%d",&e.position.x,&e.position.y);}e.iteration = 0;e.passed = 0;
}void DestorySituation(struct situation &e)
{//功能:销毁结构体e,释放初始化过程中申请的内存DestoryLayout(e.tile);e.iteration = 0;e.passed = 0;e.position.x = e.position.y = 0;
}void manage(struct situation &e)
{//功能:模拟的基本操作过程,并得到相应的结果int imove[8] = {-1,0,1,1,1,0,-1,-1},jmove[8] = {1,1,1,0,-1,-1,-1,0};while(1){int iTemp = rand()%8;if(e.position.x + imove[iTemp] > 0 && e.position.y + jmove[iTemp] > 0 && e.position.x + imove[iTemp] <= e.tile.width && e.position.y + jmove[iTemp] <= e.tile.length)//判断移动的方向是否合法{e.position.x += imove[iTemp];e.position.y += jmove[iTemp];e.iteration++;if(!e.tile.array[e.position.y - 1][ e.position.x - 1])e.passed++;e.tile.array[e.position.y - 1][ e.position.x - 1]++;}if(e.passed == e.tile.width*e.tile.length || e.iteration == ITERATIVE_MAX)break;}
}void displayLayout(struct layout e)
{//功能:输出模拟过程中得到的数据for(int i = 0; i < e.length; ++i){for(int j = 0; j < e.width; ++j)printf("%d ",e.array[i][j]);puts("");}
}void dispalyFormate(int m)
{//功能:格式化输出int型数据char s[5];s[4] = '\0';int i = 0;while(m){s[i++] = (char)(m%10 + '0');m = m/10;}int j = i - 1,k = 0;while(j > k){char cTemp = s[k];s[k] = s[j];s[j] = cTemp;j--,k++;}while(i != 3)s[i++] = ' ';printf("%s",s);
}void dispalyFormateLayout(struct layout e)
{//功能:格式化输出模拟过程中得到的数据,//并将数据存入到RandomWalk_Data.txt记事本文件中FILE* fp;//fp = fopen("RandomWalk_Data.txt","w");//fp = fopen("RandomWalk_Data.xls","w");fp = fopen("RandomWalk_Data.dat","w");if(!fp)printf("ERROR!\n");for(int i = 0; i < e.length; ++i){for(int j = 0; j < e.width; ++j){dispalyFormate(e.array[i][j]);//将数据读入文件中fprintf(fp,"%d ",e.array[i][j]);}puts("");fprintf(fp,"\n");}fclose(fp);
}
bool conclusion(void)
{MessageBox(NULL, TEXT("模拟已结束,模拟数据已存入相应的记事本中.\n\t如果想观看,请输入\"1\"." "\n\t输入\"2\",重新进入演示系统.\n\t输入其他字符将退去本系统."),TEXT("提示信息:"),0);int iTemp;printf("继续:");scanf("%d",&iTemp);switch(iTemp){case 2:return false;case 1://system("start RandomWalk_Data.txt");//system("start RandomWalk_Data.xls");system("start RandomWalk_Data.dat");default:return true;}
}bool simulate(void)
{struct situation EXAMPLE;InitSituation(EXAMPLE);displayLayout(EXAMPLE.tile);manage(EXAMPLE);dispalyFormateLayout(EXAMPLE.tile);printf("Iteration:%d\n",EXAMPLE.iteration);printf("Passed:%d\n",EXAMPLE.passed);DestorySituation(EXAMPLE);return conclusion();
}#endif // SIMULATE_H_INCLUDED
这篇关于“随机漫步”(Random Walk)模拟演示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!