C ++中的组合练习看到速度递减与VBA

时间:2018-06-12 14:54:19

标签: c++ visual-studio-2017

只是为了娱乐,我以为我用monte carlo实现模拟组合问题。我在VBA中实现了一个实现,然后作为练习,我想我会尝试用C ++编写它(我是一个完整的新手)来检查速度差异等。除了我不知道高级编码技巧/技巧之外,我天真地想过只要模型尽可能忠实地转移到带有镜像函数/循环/变量类型的C ++,除了微调之外,C ++的强大功能会让我立即提速,因为我经常运行大量的sims嵌入式排序等等。嗯,恰恰相反,所以C ++实现必定存在严重错误,根据参数的不同,效率大约只有一半。他们都收敛到同一个答案,所以我们在数学上很开心他们的工作。

问题:

假设您有N天随机分配k考试,例如每天2个考试时段(上午/下午)。说2天是完整考试日的概率是多少?我想我现在有一个封闭的形式,我现在相信,所以无论如何都想用MC测试。

算法启发式:

很简单,我们说我们有18天,6次考试,每天2个插槽,我们想知道我们有2整天的概率。

(i)模拟6件制服U_i (ii)通过使用调整已经分配的时隙的制服在剩余的时隙中随机分配它们来为考试分配时隙。例如,如果考试4在34个插槽空间中分配了插槽4但是已经采用了3个和5个,那么在36个插槽空间中,Exam_4将分配插槽6(这将是重新布局后的第一个空闲插槽)。已经实现了一些嵌入式排序(在VB Bubblesort / quicksort中可以忽略不计的差异,到目前为止只在C ++中使用bubblesort)。 (iii)只需将插槽转换为天数,然后计算击中目标的模拟器。

Phew - 那就是背景。这种精神并不是真正优化算法,只是为了帮助我理解我做错了什么,以便在C ++中'镜像'时让它慢得多!!

守则!

// monte carlo

#include "stdafx.h"
#include"AllocateSlots.h"
#include<vector>
#include<string>
#include<iostream>
#include<cmath>
#include<ctime>

using namespace std;

int main()
{
    int i, j, k, m;

    int days, exams, slotsperday, filledslotsperday, targetfulldays, filleddays;

    long sims, count, simctr;

    cout << "Days?: ";cin >> days;
    cout << "Exams?: ";cin >> exams;
    cout << "Slots Per Day?: ";cin >> slotsperday;
    cout << "Filled Slots?: ";cin >> filledslotsperday;
    cout << "Target Full Days?: ";cin >> targetfulldays;
    cout << "No. of sims?: ";cin >> sims;

    system("PAUSE");

    //timer
    clock_t start;
    start = clock();

    double randomvariate;

    //define intervals for remaining slots
    vector <double> interval(exams);

    int totalslots = (days * slotsperday);

    for (k = 1; k <= exams; k++)
    {
        interval[k-1] = 1 / (static_cast <double> (totalslots - k + 1));
    }

    vector <int> slots(exams);          //allocated slots 
    vector <int> previousslots(exams);  //previously allocated slots
    vector <int> slotdays(exams);       //days on which slots fall

    srand((int) time(0)); //generates seed on current system time
    count = 0;
    for (simctr = 1; simctr <= sims; simctr++)
    {
        vector<int> daycounts(days);        //initialised at 0

        for (i = 1; i <= exams;i++)
        {
            //rand() generates integers in [0.0,32767]
            randomvariate = (static_cast <double> (rand()+1))/ (static_cast <double> (RAND_MAX+1));
            j = 1;
            while (j <= totalslots - i + 1)
            {
                if (randomvariate < j*interval[i - 1]) break;
                j++;
            }

            slots[i - 1] = j;
        }

        for (i = 2; i <= exams;i++)
        {
            previousslots.resize(i - 1);
            for (m = 1; m <= i - 1; m++)
            {
                previousslots[m - 1] = slots[m - 1];
            }

            BubbleSort(previousslots);

            for (k = 1; k <= i - 1;k++)
            {
                if (slots[i - 1] >= previousslots[k - 1]) 
                { 
                    slots[i - 1]++ ;
                }
            }
        }

        //convert slots into days
        for (i = 1; i <= exams;i++)
        {
            slotdays[i - 1] = SlottoDays(slots[i - 1], slotsperday);
        }

        //calculate the filled days
        filleddays = 0;
        for (j = 1; j <= days; j++)
        {
            for (k = 1; k <= exams; k++)
            {
                if (slotdays[k - 1] == j)
                {
                    daycounts[j - 1]++;
                }
            }

            if (daycounts[j - 1] == filledslotsperday)
            {
                filleddays++;
            }

        }

        //check if target is hit
        if (filleddays == targetfulldays)
        {
            count++;
        }

    }

    cout << count << endl;
    cout << "Time: " << (clock() - start) / (double)(CLOCKS_PER_SEC) << " s" << endl;
    //cout << (static_cast<double>(count)) / (static_cast<double>(sims));
    system("PAUSE");

    return 0;
}

以及2个辅助功能:

#include "stdafx.h"
#include"AllocateSlots.h"
#include<iostream>
#include<cmath>
#include<vector>

using namespace std;

//returns day for a given slot 
int SlottoDays(int &examslot, int &slotsperday)
{
    return((examslot % slotsperday == 0) ? examslot/ slotsperday: examslot/ slotsperday + 1);
}

//BubbleSort Algorithm
vector <int> BubbleSort(vector <int> &values)
{
    int i;
    int j;
    int tmpSort;
    int N = values.size();

    for (i = 0; i < N;i++)
    {
        for (j = i + 1; j < N; j++)
        {
            if (values[i] > values[j])
            {
                tmpSort = values[j];
                values[j] = values[i];
                values[i] = tmpSort;
            }
        }
    }
    return values;
}

所以它就像 - 就像我说这个算法对于C ++和VBA来说很常见,很高兴发布VBA但是在第一个例子中只是想知道在上面是否有明显的明显的东西。几乎第一次这样做,使用矢量等等,独立,自我'教'所以肯定搞砸了一些东西,尽管已经设法让它运行一些奇迹!非常感谢一些智慧的话 - 尝试用这样的练习来教自己C ++,但我真正想要的是速度(当然还有数学准确性!)适用于更大的项目。

我18天的例子,6次考试,每天2个插槽,2天充满它应该收敛到大约3.77%,这与VBA中38s的1mm sims和上面的实现中的145s一样x64 windows7上的duocore 2.7G i7 4GB RAM笔记本电脑。

1 个答案:

答案 0 :(得分:1)

根据评论中的讨论,您可能会在Debug模式下运行程序。这会关闭一些优化,甚至会产生一些额外的代码。

要在发布模式下运行,请在标准工具栏中查找Solution Configurations下拉列表,然后使用下拉列表从Debug更改为Release

Visual Studio Standard Tool Bar Screenshot

然后重建您的解决方案并重新运行测试。

要在Visual Studio中进一步探索程序性能,您需要使用Performance Profiler工具。有一个关于在Microsoft文档站点上使用Performance Profiler(包括视频)的教程:Profile application performance in Visual Studio。还有Quickstart: First look at profiling tools以及更多:全部在Profiling in Visual Studio部分。