下面的问题是我在此wiki page上遇到的一个问题。



我的算法:

  • 使用随机薪水值填充两个数组(女性和男性)。
  • 将女性与随机的男性配对并比较薪水。如果是女性
    工资低于男性,增加结婚柜台。设置双方女性
    并将男性isMarried值设置为true。
  • 继续约会,直到未婚男性的最高工资是
    低于未婚女性的最低工资。

  • 这是我的实现:
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
    
        srand(time(NULL));
    
    
        int min = 1;
        int max = 1000000;
        Male male[100];
        Female female[100];
        double count = 0;
        bool done = false;
    
    
    
    
    
        //Fill array of Females and Males with random salaries ranging from 1 to 10
        for(int i=0; i<100; i++){
            int output = min + (rand() % (int)(max - min + 1));
            male[i].salary = output;
        }
        for(int i=0; i<100; i++){
            int output = min + (rand() % (int)(max - min + 1));
            female[i].salary = output;
        }
    
    
        //Start dating
        //Keep dating until the maximum salary of males is lower than minimum salary of females
    
        do{
            random_shuffle(begin(male), end(male));               //Shuffle array of males
            random_shuffle(begin(female), end(female));           //Shuffle array of females
    
    
            for(int i=0; i<100; i++){                              //Compare a female and male from both arrays
                if(female[i].salary < male[i].salary)
                    if(!female[i].isMarried && !male[i].isMarried){
                        count++;
                        female[i].isMarried = true;
                        male[i].isMarried = true;
                        cout << "Female salary: " << female[i].salary << endl;
                        cout << "Male salary: " << male[i].salary << endl;
                    }
            }
    
            int maxMen = 0;
            for(int i=0; i<100; i++){
                if(male[i].salary > maxMen && !male[i].isMarried)
                    maxMen = male[i].salary;
            }
    
            int minWomen = 1000000;
            for(int i=0; i<100; i++){
                if(female[i].salary < minWomen && !female[i].isMarried)
                    minWomen = female[i].salary;
            }
    
            if(maxMen <= minWomen)
                done = true;
    
    
        }while(!done);
    
    
        cout << "Percentage: " << count/100;
        cout << endl;
    
        int unmarried = 0;
        cout << "Number of unmarried females: ";
        for(int i=0; i<100; i++)
            if(!female[i].isMarried)
                unmarried++;
        cout << unmarried << endl;
    
        unmarried = 0;
        cout << "Number of unmarried males: ";
        for(int i=0; i<100; i++)
            if(!male[i].isMarried)
                unmarried++;
        cout << unmarried << endl;
    
        cout << endl;
    
    
    
    
        return a.exec();
    }
    

    我在Programmers.SE,显然是I should be getting 68%上问了这个问题。
    我得到的百分比值范围从35%到40%。我究竟做错了什么?

    最佳答案

    1)您的条件变量已统一化:

    bool done=false;
    

    这可能会导致循环比计划的更早退出,因为只有在maxMen < minWomen时才将其设置为可预测的值。

    2)您的结束条件设置不正确:

    您只有在maxMen < minWomen时才完成。但是,如果maxMen == minWomen没有女人可以结婚了,那么您将陷入无限循环。如果您的工资规模很小,这种现象很可能发生。如果从1到1000,这种情况的可能性较小。但是为了避免不可能的情况,将该子句更改为:
        if (maxMen <= minWomen)   // no new wedding in sight
            done = true;
    

    结合先前的问题,您的循环条件是错误的。只要未完成,就应该循环播放(如果maxMen> minWomen,则仍然可以进行婚礼)。因此,将其重写为:
    ...
    } while (! done);
    

    结论

    通过这3个更改,当我几次重新运行程序时,我得到的百分比从55%到74%,大多数值在65%到70%之间。

    其他建议

    您应该避免使用硬编码数字。代替10,但更喜欢max+1。在开头const int N=100;定义,然后将所有文字100替换为N。这样,更容易使用模拟参数(使用不同的薪水范围或更大的人口)。

    您可以将模拟放在返回百分比作为值的单独函数中,然后在main()中多次运行模拟(100,1000?),计算百分比的平均值和标准偏差。与手动运行和粗略估计相比,这提供了更准确的结果。

    如果您对模拟感兴趣,那么值得一看 <random> :它提供了多种随机生成器和随机分布的选择,比rand()功能强大得多。例子:
        mt19937 generator(time(NULL));  // mersene twister generator seeded with time
        ...
        uniform_int_distribution<int> distribution(min, max);  // after declaration of your min and max
        ...
        male[i].salary = distribution(generator);   // and same for female
    

    顺便说一句,您可能对 std::count_if std::min() std::max()感兴趣,它们可以轻松地节省for循环的重复编码。

    09-05 13:36