“隨機漫步”(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 10000

void 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;否則,返回false
    if(p.x < 0 || p.y < 0 || p.x > l.width || p.y > l.length)
        return false;
    else
        return 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


 

 

發佈了55 篇原創文章 · 獲贊 8 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章