【问题标题】:The results of my simulation are non-intuitive我的模拟结果不直观
【发布时间】:2018-08-21 15:04:58
【问题描述】:

一个简单的问题一直困扰着我,我不知道如何用数学来证明它,所以我编写了一个简单的 Perl 程序来近似答案,但我不同意它的结果。

是我错了还是我的脚本缺少什么?

问题

10 双相同的袜子,但它们不是左就是右。如果它们是随机配对的,那么正确配对与不正确配对的概率是多少?

更新

我的意思是,如果蒙上眼睛,我将抽屉里的 20 只袜子全部配对,那么正确配对与错误配对的比例是多少?

我的脚本显示正确与错误的比例约为 1.12:1。

对吗?

#!/usr/bin/perl
#SockCruncher

#use strict;
use warnings;
use List::Util 'shuffle';

my @tumble_dryer = (R,R,R,R,R,R,R,R,R,R,L,L,L,L,L,L,L,L,L,L);
my @rand_socks = shuffle(@tumble_dryer);
my $sock_pop1;
my $sock_pop2;
my $pair_counter = 1;
my @rev_rand_socks;
my $good_pair = 0;
my $bad_pair = 0;
my $counter = 0;

open (OUT,'>pairing.txt') or die ("Can't open pairing.txt for writing\n");
print OUT "Sock Sorter\n-----------\n\n";
print OUT "10 pairs of socks all identical appart from them being either left or right.  10 left & 10 right.\n";
print OUT "The 20 socks are shuffled in an array and the first 2 popped out.\n";
print OUT "The remaining socks are shuffled again and the first 2 popped out..... and so on.\n\n";

while ($counter < 100000) {

    while ($pair_counter <= 10) {
        print OUT "Socks : ";
        print OUT join(",", @rand_socks);
        @rev_rand_socks = reverse @rand_socks;  #Just done so the output file looks better. The LHS 2 elements are popped and eventually spliced off.
        $sock_pop1 = pop @rev_rand_socks;
        $sock_pop2 = pop @rev_rand_socks;
        print OUT " (P$pair_counter : $sock_pop1.$sock_pop2)   ";
        if (($sock_pop1 eq "L") && ($sock_pop2 eq "R")) {$good_pair = $good_pair +1;}
        if (($sock_pop1 eq "R") && ($sock_pop2 eq "L")) {$good_pair = $good_pair +1;}
        if (($sock_pop1 eq "L") && ($sock_pop2 eq "L")) {$bad_pair = $bad_pair +1;}
        if (($sock_pop1 eq "R") && ($sock_pop2 eq "R")) {$bad_pair = $bad_pair +1;}
        splice @rand_socks, 0, 2;
        @rand_socks = shuffle(@rand_socks);
        $pair_counter = $pair_counter + 1;
    }
    print OUT "  Good pairs : $good_pair   Bad pairs : $bad_pair\n";
    $counter = $counter + 1;
    $pair_counter = 1;
    @tumble_dryer = (R,R,R,R,R,R,R,R,R,R,L,L,L,L,L,L,L,L,L,L);
    @rand_socks = shuffle(@tumble_dryer);
}
my $ratio = $good_pair/$bad_pair;
print "\nGood pairs = $good_pair  Bad pairs = $bad_pair    Good pair to bad pair ratio : $ratio.\n";
close (OUT);

【问题讨论】:

  • 我投票决定将此问题作为离题结束,因为它与特定的编程问题无关。在 Code Review 上会更合适。
  • @Borodin 我猜问题是,如果您一次取出所有 20 只袜子 2 对,您多久会得到 all 对?但这肯定不是很清楚,这不是代码的作用
  • 我不明白为什么这会困扰你。拿了一只袜子后,剩下的十只袜子匹配,九只不匹配。比率是 10:9 或 1.11...但是您的代码需要一些工作,您应该将其提交给Code Review 以便编写更好的代码。特别是,在程序顶部的块中声明 every 变量是有害的,并且表明了一种非常老式的风格。它几乎抵消了use strict 的优势,它只能被私下注释掉,而不必担心被打断!
  • @ysth:啊,我明白了。谢谢,我已经变得像绵羊一样,并假设了以前所有袜子/球/大理石盲抽问题的另一种变体。正如您所说,问题没有正确定义。我想“如果他们随机配对” 需要详细说明。但不在这里!
  • @Pete:“我不像你们那样是程序员” 编写软件让你成为程序员,你在 Stack Overflow 上的问题是接受与其他任何人相同的审查。你不能躲在“不是真正的程序员”的盾牌后面,希望逃避批评。你显然学到了很多东西,我建议你继续学习,这样你可以更好地尊重自己的工作。您应该将 Stack Overflow 视为 Wikipedia:它是问答事实的存储库,您至少应该胜任您的工作。

标签: perl math probability


【解决方案1】:

假设你从抽屉里挑出一只 R 袜子。

现在还剩 10 L 袜子(可以正确配对)

还有 9 只 R 袜子(配对不正确)

所以 10 正确:9 错误大约是 1.11:1。

你没有说你期望的数字,但如果你的脚本说 1.12:1,那接近正确的结果。

【讨论】:

  • 最好不要鼓励跑题?
  • 我的推理是,如果我拉出一个 R 和一个 L,它会留下相同数量的 R 和 L,所以下次配对的几率仍然相同。但是,如果我退出,比如说,2x Rs,它会留下一个不平衡的余数,这会稍微有利于不正确的配对。我的脚本一次配对 2 个,然后重新洗牌。
  • 我现在可以看到 mob 的逻辑,并同意这就是它的工作原理。对我来说已经足够好了。我的逻辑错误。干杯。
  • 另外,也许最好不要对离题问题的答案投反对票?
  • @Pete:“我的脚本一次配对 2 个,然后重新洗牌”。无需重新洗牌。
【解决方案2】:

我猜问题是,如果您一次取出所有 20 只袜子 2 只,您多久会得到所有正确的一双?但这肯定不是很清楚,这并不是代码的作用。您似乎在汇总内部循环中发现的好对和坏对,而不是在内循环之后汇总好结果和坏结果。

每次脱掉袜子时都没有必要重新洗牌。

尽量在最小的范围内声明变量。

FWIW 我会这样做:

use strict;
use warnings;
use List::Util 'shuffle';

my $attempts = 1000000;
my $pairs = 10;
my @socks = (('R') x $pairs, ('L') x $pairs);

my $correct_pairings = 0;
for my $attempt (1..$attempts) {
    my $picked_socks = join '', shuffle @socks;
    ++$correct_pairings if $picked_socks =~ /^(?:(.)\1){$pairs}/;
}
print "$correct_pairings correct pairings in $attempts attempts\n";

这表明在不到 0.14% 的时间内获得 10 个匹配对。

【讨论】:

  • 我并不是这个意思。我的意思是,如果蒙上眼睛,我将抽屉里的 20 只袜子全部配对,那么正确配对与错误配对的比例是多少?
  • @Pete:这听起来与 ysth 所假设的完全一样。这不是你的问题所说的。 (我在您的问题中添加了一个更新,反映了您在此处的说明。)
  • @Borodin 不,在我看来我错了,他确实想要成对与未成对的袜子的总比例,但是当你移除所有成对的袜子时,不仅仅是第一对(尽管来自他的结果,数量相同)
  • @ysth:我以为这是你原来的解释;听起来肯定是一样的,但是您的代码会在挑选另一双之前将所有袜子都扔回抽屉。
猜你喜欢
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 2017-03-13
  • 2017-11-18
  • 2019-06-01
相关资源
最近更新 更多