我认为很多学生对这个问题应该都有过类似的思考,也都质疑过,我将我的思考记录下来希望能对其他人有所帮助。
前面提出质疑的内容是我初期对这个问题思考仍不足的时候对老师提出来的,这些质疑是有道理的,但是对问题的理解比较片面,被限制在了“球是被一个一个随机扔进盒子”的假设。它对于该问题公式的否定观点是错误的,实际上这个公式是正确的。
在文章末尾,我增加了更深的理解和总结。但前面文章内容的记录时间过于久远,我就不再更改了,保留了这些质疑否定的内容。
早期质疑
将m个不可分辨的小球放置入n个不同的盒子中,样本空间有
C
n
+
m
−
1
m
C_{n+m-1}^m
Cn+m−1m个样本点,也是基本事件,我赞同这一点。
但是我认为在实际中这些情况并非是等可能的。
因此我对在古典概型中使用这个公式求概率的方法提出质疑,我认为这是错误的。
以下所有内容都是建立在我主观的假设之下:球是被一个一个随机扔进盒子的。
下面是我认为非等可能的理由:
举例,3小球放入2盒子,我认为上图两个事件的可能性比例为1:3。由于球是不可分辨的,所以虽然球是一个一个放入盒子中的,所以在第一个事件里并没有顺序之分,出现事件一的情况只有一种,即第一个球放入了黄盒,第二个球放入了黄盒,第三个球放入了黄盒。而第二个事件里,考虑小球放入顺序(虽然球不可分辨,但是当球放入不同盒子,盒子中出现球的顺序也将改变),可能有三种情况:
- 情况一:第一个球放入黄盒,第二个球放入蓝盒,第三个球放入黄盒
- 情况二:第一二个球放入黄盒,第三个球放入蓝盒
- 情况三:第一个球放入蓝盒,第二三个球放入黄盒
所以我认为这两个基本事件的可能性并不相等,不可以用在古典方法中用来求概率。
为了用事实证明我的想法,我编写了一个C程序,用来大量模拟该实验,统计数据。
代码采取生成随机数代表盒子编号,将球放入对应的盒子中,即随机数代表的盒子中球数加一,随机数对应的数组中的某数加一,重复这个过程,到最后统计代表全部盒子的数组的不同最终情况的出现次数,计算每个情况出现的概率,打印在标准输出上。
另外,由于代码的局限性,只能模拟五个小球及以内的随机放置。
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
struct res {
char result[200];
int num;
double prop;
}resu[30000] = {0};
char box[200] = "\0";
int sign[1000000] = { 0 }, list[100] = {0};
int turn(min) {
int a = strtol(box, '\0', 2) - min;
return a;
}
int main() {
int m = 0, N = 0, M = 0, min = 0, max = 0, i = 0, j = 0, n = 1, a = 0,nn=0,k=0,b=0;
scanf("%d%d%d", &m, &N, &M);
for (i = 0; i < N-1; i++) {
box[i] = '1';
}
for (i = N - 1; i < N + m - 1; i++) {
box[i] = '0';
}
max = strtol(box, '\0', 2);
for (i = 0; i < N - 1; i++) {
box[i] = '0';
}
for (i = N - 1; i < N + m - 1; i++) {
box[i] = '1';
}
min = strtol(box, '\0', 2);
srand((unsigned int)time(NULL));
for (i = 0; i < M; i++) {
for (j = 0; j < N+1; j++) {
list[j] = 0;
}
for (j = 0; j < m; j++) {
a = rand() % N + 1;
list[a]++;
}
for (j = 1; j <= N; j++) {
for (k = nn; k < nn + list[j]; k++) {
box[k] = '0';
}
nn = nn + list[j];
box[nn] = '1';
nn++;
}
box[nn - 1] = '\0';
b = turn(min);
nn = 0;
if (sign[b] == 0) {
sign[b] = n;
strcpy(resu[n].result, box);
resu[n].num++;
n++;
}
else {
resu[sign[b]].num++;
}
}
for (i = 1; i < n; i++) {
printf("%s %5d %.6lf\n", resu[i].result, resu[i].num, (double)resu[i].num / (double)M);
}
return 0;
}
代码生成结果如下:
这是对于3个小球放入2个盒子模拟1000次的试验,可以很明显看到四种情况并非等可能。
第一列输出结果是小球的分布结果(0代表小球,1代表盒子的隔板),第二列输出是事件的出现次数,第三列输出是事件的出现频率。
将实验次数提高为1000000次,结果如下:
显见四种情况的概率趋向0.125,0.375,0.375,0.125
证实了我的想法。
再补充一下对于5个小球放入3个盒子模拟100000次的试验结果:
综上所述
我认为该模型的公式中所给出的基本事件不是等可能的,不应该用于古典方法求概率的过程。
引起我的思考的是这一个题目,我的答案和它的不相符,但它的答案在求解时将这个模型的公式用在了古典方法中,题目如下:
这让我很疑惑,我不知道是我的思路出了问题还是这个题目确实有问题。但除了这里,我还见到很多地方使用这个公式结合古典方法求概率,我不能判断究竟是我出了错误还是这样的方法出了错误,如果您能向我提出您的看法,我将不胜感激。
补充:
另外,我知道还有一个解方程模型,如下:
X
1
+
X
2
+
X
3
=
5
X1+X2+X3=5
X1+X2+X3=5
对于(X1,X2,X3)的取值求出现所给事件的概率。
这个我们往往也抽象为分房模型中随机将不可分辨的球放置入不同盒子中的模型
我认为在这道题中原公式是正确的。因为我认为这道题实际是为盒子随机选几个球的问题,球同时随机进入盒子,这和把球放入盒子的问题是不一致的。我个人认为这两个问题有很大的区别,这又和其他人所认同的两者一致的观点有了不同。
经过一些讨论,我对这个问题有了新的看法和总结
分房问题中随机将不可分辨的球放置入不同盒子中的模型本身并不是为在盒子里放球提出的,它的公式在量子力学等多个领域里有很重要的应用。
在我们学习时,只不过是将复杂的问题抽象成了盒子与球的模型。这个公式的正确性不仅取决于球是不是可分辨的,也取决于球进入盒子的方式。当球不可分辨并且同时随机进入盒子的时候,这个公式就是成立的。
诚然,现实中我们几乎不能把多个球同时扔进盒子并保证其随机性,我们基本都采用一个一个在盒子里放球的方式,但是在很多应用该公式的实际问题中,这种同时性随机性是存在的。为了让初学者理解得透彻并且能够在以后的实际问题中提炼模型并应用,教程对分房问题作出简化,简化成了在盒子放球的模型,并人为地规定球同时进入盒子,这也就是导致我们这些疑问的原因。
希望和我曾经提出过相同疑问的人能够看到这篇文章并对分房问题有更深的理解。