“随机漫步”(Random Walk)模拟演示

2024-02-20 07:58

本文主要是介绍“随机漫步”(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)模拟演示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/727514

相关文章

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

【算法专场】模拟(下)

目录 前言 38. 外观数列 算法分析 算法思路 算法代码 1419. 数青蛙 算法分析 算法思路 算法代码  2671. 频率跟踪器 算法分析 算法思路 算法代码 前言 在前面我们已经讲解了什么是模拟算法,这篇主要是讲解在leetcode上遇到的一些模拟题目~ 38. 外观数列 算法分析 这道题其实就是要将连续且相同的字符替换成字符重复的次数+

研究人员在RSA大会上演示利用恶意JPEG图片入侵企业内网

安全研究人员Marcus Murray在正在旧金山举行的RSA大会上公布了一种利用恶意JPEG图片入侵企业网络内部Windows服务器的新方法。  攻击流程及漏洞分析 最近,安全专家兼渗透测试员Marcus Murray发现了一种利用恶意JPEG图片来攻击Windows服务器的新方法,利用该方法还可以在目标网络中进行特权提升。几天前,在旧金山举行的RSA大会上,该Marcus现场展示了攻击流程,

模拟实现vector中的常见接口

insert void insert(iterator pos, const T& x){if (_finish == _endofstorage){int n = pos - _start;size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;reserve(newcapacity);pos = _start + n;//防止迭代

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT