cpp: 随机漫步者的位移与步数的关系模型实现

关于随机漫步的介绍参见:随机漫步理论

通过cpp实现随机漫步的关系模型。(计算移动目标位移需要随机漫步多少步)

通过实践才能知道自己的不足,仅仅是看书难免会感觉生疏。

下面是实现:
一共3个文件,分别是Vector.h–> 矢量类定义,Vector.cpp–>矢量类的具体实现,main.cpp–>随机漫步模型的具体实现。

//
// Created by cat on 2018/1/1.
//

#ifndef CPP02_STEP_H
#define CPP02_STEP_H

#include <iostream>
#include <cmath>
#include <math.h>

#define Math_PI 3.1415927
/**
 * 矢量类
 */
namespace VECTOR {
    class Vector {

    public:
        enum Mode {
            /*正坐标*/ RECT,/*极坐标*/ POL
        };
    private:
        Mode currentMode;
        double angle; // 角度 (0~360度)
        double length; // 步长��(1~3m)
        double xLen; // x 方向的位移
        double yLen; // y 方向的位移

        Vector set2RECT() const; // 转成正坐标
        Vector set2POL() const; // 转成级坐标

        double radian2Angle(double radian) const // 弧度转角度
        {
            return 1.0 * radian / Math_PI * 180;
        }

        double angle2Radian(double angle) const // 角度转弧度
        {
            return 1.0 * angle * Math_PI / 180;
        }

    public:
        Vector(double num1 = 0, double num2 = 0, Mode currentMode = POL);

        Vector(const Vector &data);

        double getLength() {
            return this->length;
        };

        virtual ~Vector();

        void reset(double num1 = 0, double num2 = 0, Mode currentMode = POL);

// operator
        Vector operator*(double factor);

        Vector operator*=(double factor);

        Vector operator-();

        // friend operator
        friend std::ostream &operator<<(std::ostream &os, Vector &obj); // toString

        friend Vector operator+(const Vector &one, const Vector &another);

        friend Vector operator+=(Vector &one, const Vector &another);

        friend Vector operator-(const Vector &one, const Vector &another);

        friend Vector operator-=(Vector &one, const Vector &another);

        friend Vector operator*(double factor,  Vector &obj);

        friend Vector operator*=(double factor, Vector &obj);
    };


}

#endif //CPP02_STEP_H

//
// Created by cat on 2018/1/1.
//

#include "Vector.h"
#include <cmath>

namespace VECTOR {


    Vector::Vector(const Vector &data) {

        this->xLen = data.xLen;
        this->yLen = data.yLen;
        this->angle = data.angle;
        this->length = data.length;
        this->currentMode = data.currentMode;
    }


    Vector::Vector(double num1,
                   double num2,
                   Vector::Mode currentMode) {
        reset(num1, num2, currentMode);
    }

    void Vector::reset(double num1,
                       double num2,
                       Vector::Mode currentMode) {
        this->currentMode = currentMode;
        if (this->currentMode == POL) {
            this->angle = num1;
            this->length = num2;

            this->xLen = sin(radian2Angle(num1)) * num2;
            this->yLen = cos(radian2Angle(num1)) * num2;
        } else if (this->currentMode == RECT) {
            this->xLen = num1;
            this->yLen = num2;

            this->angle = radian2Angle(atan2(this->yLen, this->xLen));
            double len2 = pow(this->xLen, 2) + pow(this->yLen, 2);
            this->length = pow(len2, 0.5);
        } else {
            throw "error!";
        }
    }

    Vector::~Vector() {
        this->currentMode = POL;
        this->angle = 0;
        this->length = 0;
        this->xLen = 0;
        this->yLen = 0;

    }

    Vector Vector::set2RECT() const {
        Vector v = Vector(*this);
        if (this->currentMode == Vector::RECT) {
            return v;
        } else if (this->currentMode == Vector::POL) {
            v.currentMode = Vector::RECT;
            v.xLen = this->length * cos(this->angle2Radian(this->angle));
            v.yLen = this->length * sin(this->angle2Radian(this->angle));
        }
        return v;

    }

    Vector Vector::set2POL() const {
        Vector v = Vector(*this);
        if (this->currentMode == Vector::POL) {
            return v;
        } else {
            v.currentMode = Vector::POL;
            v.angle = radian2Angle(atan2(this->yLen, this->xLen));
            double len2 = pow(this->xLen, 2) + pow(this->yLen, 2);
            v.length = pow(len2, 0.5);
        }
        return v;
    }

    Vector operator+(const Vector &a, const Vector &b) {
        Vector obj;
        Vector one, another;
        one = a.set2RECT();
        another = b.set2RECT();

        obj = Vector(one.xLen + another.xLen, one.yLen + another.yLen, Vector::RECT);
        return obj;
    }

    Vector VECTOR::operator+=(Vector &one, const Vector &another) {
        one = operator+(one, another);
        return one;
    }


    Vector operator-(const Vector &a, const Vector &b) {
        Vector one, another;
        Vector::Mode mode = one.currentMode;
        one = a.set2RECT();
        another = b.set2RECT();
        Vector v = Vector(one.xLen - another.xLen, one.yLen - another.yLen, Vector::RECT);
        v.currentMode = mode;
        return v;
    }

    Vector operator-=(Vector &one, const Vector &another) {
        one = operator-(one, another);
        return one;
    }

    Vector Vector::operator*(double factor) {
        Vector obj;
        Vector::Mode mode = this->currentMode;
        this->set2RECT();
        obj = Vector(this->xLen * factor, this->yLen * factor, Vector::RECT);
        obj.currentMode = mode;
        return obj;
    }

    Vector Vector::operator*=(double factor) {
        return operator*(factor);
    }

    Vector operator*(double factor, Vector &obj) {
        return obj * factor;
    }

    Vector operator*=(double factor, Vector &obj) {
        return operator*(factor, obj);
    }


    Vector Vector::operator-() {
        Mode mode = this->currentMode;
        this->set2RECT();
        Vector v = Vector(-this->xLen, -this->yLen, Vector::RECT);
        v.currentMode = mode;
        return v;
    }


    std::ostream &operator<<(std::ostream &os, Vector &obj) {
        std::ios_base::fmtflags pref;
        std::streamsize preC;
        pref = os.setf(std::ios_base::fixed);  // store prev
        preC = os.precision(1); // store prev

        os << "Vector:(" << obj.xLen << " , " << obj.yLen << ")|[RECT]\t";
        os.precision(2);
        os << "Vector:(" << obj.angle << " , " << obj.length << ")|[POL]\t";

        if (obj.currentMode == Vector::RECT) {
            os << "{RECT}\n";
        } else {
            os << "\t{POL}\n";
        }
        os.setf(pref);  // reset
        os.precision(preC); // reset
        return os;
    }


}
#include <iostream>
#include <sstream>
#include <random>
#include <stdlib.h>
#include "Vector.h"

void end();

void resetCin();

void executeFromUser();

void execute(double length, double step);

void executeTimes(unsigned int times);

const unsigned int MAX_FREE = 10;

bool USER_INPUT = false; // 是否每次都让用户输入

static int usedTimes = 0;

static int currentSteps = 0;

int main() {
    using namespace std;
    using VECTOR::Vector;
    Vector v1 = Vector(20, 30, Vector::RECT);
    Vector v2 = Vector(40, 50, Vector::RECT);

    v1 += v2;
    cout << v1 << endl;

//    executeFromUser();
    executeTimes(100);
    return 0;
}

void executeTimes(unsigned int times) {
    using namespace std;
    using VECTOR::Vector;

    cout << "随机漫步模拟.\n";

    double avg = 0;
    double length; // 总位移
    double eachLen;// 单步长度
    string input;
    stringstream ostr;

    cout << "请输入总位移长度(退出请按q):";
    getline(cin, input);
    ostr << input;
    while (1) {
        if (ostr >> length) {
            cout << "length==" << length;
            ostr.clear();
            cout << "请输入单步位移长度(退出请按q):";
            getline(cin, input);
            ostr << input;
            if (ostr >> eachLen) {
                cout << "todo: SUCCESS\n";
                for (int pos = 0; pos < times; ++pos) {
                    execute(length, eachLen);
                    avg += currentSteps;
                }
                goto fuck;
            } else {
                cout << "输入不合法, 请重新输入!\n";
            }
        } else {
            cout << "输入不合法, 请重新输入!\n";
        }
    }
    fuck:;

    avg = avg / times;
    streamsize precision = cout.precision(2);
    cout << "随机漫步目标位移为" << length << "时的平均步数为:" << avg << "\n";
    cout.precision(precision);
}

void execute(double length, double step) {
    using namespace std;
    using VECTOR::Vector;
    Vector init{};
//    cout << "init.Length=" << init.getLength() << " , length=" << length << endl;
    while (init.getLength() < length) {
        currentSteps++;
        double angle = random() % 360;
        double el = step;
        Vector each = Vector(angle, el);
//                    cout << "........each:" << each;
        init += each;
    }
    streamsize precision = cout.precision(2);
    cout << "RESULT:" << init;
    cout << "这一次走完目标距离(" << length << ")一共用了[" << currentSteps << "]步,";
    cout << "目前距离长度为:" << init.getLength() << " > 目标长度:" << length << endl;
    usedTimes++;
    cout << "还有(" << (MAX_FREE - usedTimes) << ")次机会\n";
    cout.precision(precision);
}

void executeFromUser() {
    using namespace std;
    using VECTOR::Vector;
    cout << "随机漫步模拟.\n";
    double length; // 总位移
    double eachLen;// 单步长度

    string input;
    stringstream ostr;
    while (usedTimes <= MAX_FREE) {
        cout << "请输入总位移长度(退出请按q):";
        getline(cin, input);
        ostr << input;
        if (ostr >> length) {
            cout << "length==" << length;
            ostr.clear();
            cout << "请输入单步位移长度(退出请按q):";
            getline(cin, input);
            ostr << input;
            if (ostr >> eachLen) {
                cout << "todo: SUCCESS\n";
                execute(length, eachLen);
                if (!USER_INPUT) {
                    goto fuck;
                }
            } else {
                cout << "输入不合法, 请重新输入!\n";
            }
        } else {
            cout << "输入不合法, 请重新输入!\n";
        }
    }

    if (usedTimes > MAX_FREE) {
        cout << "体验机会已经用光,继续体验请充值~^_^\n";
    }
    end();
    fuck:;
}

void end() {
    resetCin();
    std::cout << "Bye.\n";
}

void resetCin() {
    std::cin.clear();
    while (std::cin.get() != '\n')continue;
}

完整的项目可以参见:随机漫步关系模型cpp实现

当然,这个代码写得不好,没有去优化内存。

可以看一下输出效果:

随机漫步模拟.
请输入总位移长度(退出请按q):100
请输入单步位移长度(退出请按q):1
随机漫步目标位移为100.00时的平均步数为:497246.73

从输出结果可以看到,通过1000次的模拟,得出的平均数是49万步,才能前进100米。(假设步长是固定的,为1米)。

ps: 这个结果也不一定正确,说不定程序逻辑有问题。~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值