[从头学数学] 第176节 概率
剧情提要:
[机器小伟]在[project师阿伟]的陪同下进入了结丹中期的修炼,
这次要修炼的目标是[概率]。
每次结果都不一样的。
[机器小伟]在[project师阿伟]的陪同下进入了结丹中期的修炼,
这次要修炼的目标是[概率]。
正剧開始:
星历2016年04月14日 09:46:28, 银河系厄尔斯星球中华帝国江南行省。
[project师阿伟]正在和[机器小伟]一起研究[概率]。
小伟决定自己来掷硬币玩一玩:
<span style="font-size:18px;">def tmp(): result = []; print('试验次数--正面朝上次数---正面朝上频率'); for i in range(5, 105, 5): count = 0; for j in range(i): number = random.randint(1, 10000); if number%2 == 0: count+=1; #result.append([i, count, count/i]); print('[',i,',',count,',',count/i, ']'); if __name__ == '__main__': tmp(); >>> 试验次数--正面朝上次数---正面朝上频率 [ 5 , 1 , 0.2 ] [ 10 , 3 , 0.3 ] [ 15 , 9 , 0.6 ] [ 20 , 9 , 0.45 ] [ 25 , 15 , 0.6 ] [ 30 , 11 , 0.36666666666666664 ] [ 35 , 20 , 0.5714285714285714 ] [ 40 , 14 , 0.35 ] [ 45 , 20 , 0.4444444444444444 ] [ 50 , 24 , 0.48 ] [ 55 , 27 , 0.4909090909090909 ] [ 60 , 28 , 0.4666666666666667 ] [ 65 , 40 , 0.6153846153846154 ] [ 70 , 35 , 0.5 ] [ 75 , 38 , 0.5066666666666667 ] [ 80 , 40 , 0.5 ] [ 85 , 38 , 0.4470588235294118 ] [ 90 , 47 , 0.5222222222222223 ] [ 95 , 49 , 0.5157894736842106 ] [ 100 , 55 , 0.55 ] >>> ================================ RESTART ================================ >>> 试验次数--正面朝上次数---正面朝上频率 [ 5 , 2 , 0.4 ] [ 10 , 4 , 0.4 ] [ 15 , 10 , 0.6666666666666666 ] [ 20 , 12 , 0.6 ] [ 25 , 11 , 0.44 ] [ 30 , 9 , 0.3 ] [ 35 , 19 , 0.5428571428571428 ] [ 40 , 20 , 0.5 ] [ 45 , 24 , 0.5333333333333333 ] [ 50 , 24 , 0.48 ] [ 55 , 32 , 0.5818181818181818 ] [ 60 , 29 , 0.48333333333333334 ] [ 65 , 35 , 0.5384615384615384 ] [ 70 , 33 , 0.4714285714285714 ] [ 75 , 32 , 0.4266666666666667 ] [ 80 , 39 , 0.4875 ] [ 85 , 45 , 0.5294117647058824 ] [ 90 , 47 , 0.5222222222222223 ] [ 95 , 42 , 0.4421052631578947 ] [ 100 , 51 , 0.51 ] >>> 试验次数--正面朝上次数---正面朝上频率 [ 5 , 4 , 0.8 ] , [ 10 , 4 , 0.4 ] , [ 15 , 10 , 0.6666666666666666 ] , [ 20 , 14 , 0.7 ] , [ 25 , 10 , 0.4 ] , [ 30 , 13 , 0.43333333333333335 ] , [ 35 , 17 , 0.4857142857142857 ] , [ 40 , 26 , 0.65 ] , [ 45 , 22 , 0.4888888888888889 ] , [ 50 , 24 , 0.48 ] , [ 55 , 29 , 0.5272727272727272 ] , [ 60 , 30 , 0.5 ] , [ 65 , 32 , 0.49230769230769234 ] , [ 70 , 33 , 0.4714285714285714 ] , [ 75 , 34 , 0.4533333333333333 ] , [ 80 , 46 , 0.575 ] , [ 85 , 38 , 0.4470588235294118 ] , [ 90 , 47 , 0.5222222222222223 ] , [ 95 , 46 , 0.4842105263157895 ] , [ 100 , 58 , 0.58 ] ,</span>
每次结果都不一样的。
看一看这些数究竟是如何的:
<span style="font-size:18px;"> if (1) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 20; //config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var array = [ [ 5 , 4 , 0.8 ] , [ 10 , 4 , 0.4 ] , [ 15 , 10 , 0.6666666666666666 ] , [ 20 , 14 , 0.7 ] , [ 25 , 10 , 0.4 ] , [ 30 , 13 , 0.43333333333333335 ] , [ 35 , 17 , 0.4857142857142857 ] , [ 40 , 26 , 0.65 ] , [ 45 , 22 , 0.4888888888888889 ] , [ 50 , 24 , 0.48 ] , [ 55 , 29 , 0.5272727272727272 ] , [ 60 , 30 , 0.5 ] , [ 65 , 32 , 0.49230769230769234 ] , [ 70 , 33 , 0.4714285714285714 ] , [ 75 , 34 , 0.4533333333333333 ] , [ 80 , 46 , 0.575 ] , [ 85 , 38 , 0.4470588235294118 ] , [ 90 , 47 , 0.5222222222222223 ] , [ 95 , 46 , 0.4842105263157895 ] , [ 100 , 58 , 0.58 ] ]; var len = array.length; var stat = new Statistic(); var data = [], text = []; //横坐标 for (var i = 0; i <len; i++) { data.push(array[i][2].toFixed(2)); text.push(array[i][0].toFixed(0)); } stat.init(data, '试验次数', '正面朝上频率', 1); stat.rateHistogram(text, 0, 0); }</span>
画个折线图瞅瞅:
<span style="font-size:18px;"> if (1) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 20; //config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var array = [ [ 5 , 4 , 0.8 ] , [ 10 , 4 , 0.4 ] , [ 15 , 10 , 0.6666666666666666 ] , [ 20 , 14 , 0.7 ] , [ 25 , 10 , 0.4 ] , [ 30 , 13 , 0.43333333333333335 ] , [ 35 , 17 , 0.4857142857142857 ] , [ 40 , 26 , 0.65 ] , [ 45 , 22 , 0.4888888888888889 ] , [ 50 , 24 , 0.48 ] , [ 55 , 29 , 0.5272727272727272 ] , [ 60 , 30 , 0.5 ] , [ 65 , 32 , 0.49230769230769234 ] , [ 70 , 33 , 0.4714285714285714 ] , [ 75 , 34 , 0.4533333333333333 ] , [ 80 , 46 , 0.575 ] , [ 85 , 38 , 0.4470588235294118 ] , [ 90 , 47 , 0.5222222222222223 ] , [ 95 , 46 , 0.4842105263157895 ] , [ 100 , 58 , 0.58 ] ]; var len = array.length; var stat = new Statistic(); var data = [], text = []; //横坐标 for (var i = 0; i <len; i++) { data.push(array[i][2]); text.push(array[i][0].toFixed(0)); } stat.init(data, '试验次数', '正面朝上频率', 1); stat.lineGraph(text, 0, 0, 0, 1.0); } //折线图 this.lineGraph = function(lableArray, xOffset, yOffset, yMin, yMax) { lableArray = lableArray ? lableArray : []; var lables = lableArray.length; xOffset = xOffset ? xOffset : 0; yOffset = yOffset ? yOffset : 0; var colorArray = ['red', 'orange', '#0088FF', 'green', 'cyan', 'blue', '#FF00FF', '#FF8844', 'purple']; var colors = colorArray.length; var height = 380, width = 580; plot.save() .translate(xOffset+60, yOffset+50); plot.setLineWidth(2) .setTextAlign('right'); var max = yMax ? yMax : this.max(); var min = yMin ? yMin : 0; //最大值的末位为0的近似数,比方最大值25。最合适的近似数为30 var dy = Math.round((max-min)/10*100)/100; var size = this.size(); var perH = Math.round((height-100) / 10); var part = 2 * size; var perW = Math.round((width-100) / part); //宽和高度边界 var wBound = part*perW, hBound = 10*perH; plot.setLineWidth(5) .strokeRect(0, 0, wBound, hBound); this.axis2D(0, hBound, wBound+20, hBound+20, this.xLabel, this.yLabel); plot.setLineWidth(2); var count = 0; for (var i = hBound; i >-1; i -= perH) { plot.fillText((min+dy*count).toFixed(2), -10, i+10, 30); count++; if (i > 0) { plot.beginPath() .moveTo(0, i) .lineTo(wBound, i) .closePath() .stroke(); } } for (var i = 0; i < part; i++) { plot.beginPath() .moveTo(i*perW, 0) .lineTo(i*perW, hBound) .closePath() .stroke(); } var xpos, xpos2, ypos; plot.setStrokeStyle('red') .setLineWidth(4); for (var i = 0; i < size; i++) { ypos = hBound-(this.statisticalSample[i]-min)/dy*perH; xpos = perW*(1+2*i); if (i==0) { plot.beginPath() .moveTo(xpos, ypos); } else if (i < size-1) { plot.lineTo(xpos, ypos); } else { plot.lineTo(xpos, ypos) .moveTo(xpos, ypos) .closePath() .stroke(); } } for (var i = 0; i < size; i++) { ypos = hBound-(this.statisticalSample[i]-min)/dy*perH; xpos = perW*(1+2*i); xpos2 = xpos + 0.5*perW; plot.setFillStyle('orange'); shape.fillCircle(xpos, ypos, 5); plot.setFillStyle('blue'); plot.fillText(this.statisticalSample[i].toFixed(2), xpos, ypos-5, 100); plot.setFillStyle('blue'); plot.setTextAlign('center'); if (i < lables) { plot.fillText(lableArray[i], xpos2-0.5*perW, hBound+30, 100); } } plot.restore(); } </span>
来个数据点少一点的:
<span style="font-size:18px;">>>> 试验次数--正面朝上次数---正面朝上频率 [ 5 , 3 , 0.6 ] , [ 15 , 9 , 0.6 ] , [ 25 , 16 , 0.64 ] , [ 35 , 15 , 0.42857142857142855 ] , [ 45 , 20 , 0.4444444444444444 ] , [ 55 , 31 , 0.5636363636363636 ] , [ 65 , 38 , 0.5846153846153846 ] , [ 75 , 44 , 0.5866666666666667 ] , [ 85 , 42 , 0.49411764705882355 ] , [ 95 , 50 , 0.5263157894736842 ] , if (1) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 20; //config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var array = [ [ 5 , 3 , 0.6 ] , [ 15 , 9 , 0.6 ] , [ 25 , 16 , 0.64 ] , [ 35 , 15 , 0.42857142857142855 ] , [ 45 , 20 , 0.4444444444444444 ] , [ 55 , 31 , 0.5636363636363636 ] , [ 65 , 38 , 0.5846153846153846 ] , [ 75 , 44 , 0.5866666666666667 ] , [ 85 , 42 , 0.49411764705882355 ] , [ 95 , 50 , 0.5263157894736842 ] ]; var len = array.length; var stat = new Statistic(); var data = [], text = []; //横坐标 for (var i = 0; i <len; i++) { data.push(array[i][2]); text.push(array[i][0].toFixed(0)); } stat.init(data, '试验次数', '正面朝上频率', 1); stat.lineGraph(text, 0, 0, 0, 1.0); }</span>
假设尝试次数够多呢?
<span style="font-size:18px;">试验次数--正面朝上次数---正面朝上频率 [ 100 , 50 , 0.5 ] , [ 1100 , 548 , 0.49818181818181817 ] , [ 2100 , 1026 , 0.48857142857142855 ] , [ 3100 , 1522 , 0.49096774193548387 ] , [ 4100 , 2083 , 0.5080487804878049 ] , [ 5100 , 2613 , 0.5123529411764706 ] , [ 6100 , 3047 , 0.49950819672131147 ] , [ 7100 , 3522 , 0.496056338028169 ] , [ 8100 , 4083 , 0.5040740740740741 ] , [ 9100 , 4595 , 0.5049450549450549 ] , [ 10100 , 4960 , 0.4910891089108911 ] , if (1) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 20; //config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var array = [ [ 100 , 50 , 0.5 ] , [ 1100 , 548 , 0.49818181818181817 ] , [ 2100 , 1026 , 0.48857142857142855 ] , [ 3100 , 1522 , 0.49096774193548387 ] , [ 4100 , 2083 , 0.5080487804878049 ] , [ 5100 , 2613 , 0.5123529411764706 ] , [ 6100 , 3047 , 0.49950819672131147 ] , [ 7100 , 3522 , 0.496056338028169 ] , [ 8100 , 4083 , 0.5040740740740741 ] , [ 9100 , 4595 , 0.5049450549450549 ] , [ 10100 , 4960 , 0.4910891089108911 ] ]; var len = array.length; var stat = new Statistic(); var data = [], text = []; //横坐标 for (var i = 0; i <len; i++) { data.push(array[i][2]); text.push(array[i][0].toFixed(0)); } stat.init(data, '试验次数', '正面朝上频率', 1); stat.lineGraph(text, 0, 0, 0, 1.0); }</span>
嗯,原来如此。
<span style="font-size:18px;">>>> [0.14, 0.14, 1.0, 0.0, 0.6, 0.4] >>> ================================ RESTART ================================ >>> [0.23, 0.16, 1.0, 0.0, 0.5, 0.5] >>> ================================ RESTART ================================ >>> [0.14, 0.16, 1.0, 0.0, 0.51, 0.49] #掷骰子 def dice(): N = 100; count = [0]*6; for i in range(N): number = random.randint(1,6); if number == 1: count[0]+=1; if number == 5: count[1]+=1; if number < 7: count[2]+=1; if number > 7: count[3]+=1; if number%2 == 0: count[4]+=1; if number%2 == 1: count[5]+=1; for i in range(len(count)): count[i]/=N; print(count); </span>
<span style="font-size:18px;">>>> 两个骰子点数和为1的概率是0.0 两个骰子点数和为2的概率是0.02 两个骰子点数和为3的概率是0.07 两个骰子点数和为4的概率是0.13 两个骰子点数和为5的概率是0.08 两个骰子点数和为6的概率是0.11 两个骰子点数和为7的概率是0.14 两个骰子点数和为8的概率是0.13 两个骰子点数和为9的概率是0.13 两个骰子点数和为10的概率是0.1 两个骰子点数和为11的概率是0.04 两个骰子点数和为12的概率是0.05 #掷骰子, 两骰子点数和 def dice(): N = 100; count = [0]*12; for i in range(N): number1 = random.randint(1,6); number2 = random.randint(1,6); count[number1+number2-1]+=1; for i in range(len(count)): count[i]/=N; for i in range(len(count)): print('两个骰子点数和为{0}的概率是{1}'.format(i+1, count[i]));</span>
假设实验次数够多,终于会是这种情况:
if (1) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 20; //config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var array = [0.0, 0.02, 0.05, 0.105, 0.105, 0.155, 0.175, 0.105, 0.12, 0.11, 0.045, 0.01]; var len = array.length; var stat = new Statistic(); var data = [], text = []; //横坐标 for (var i = 0; i <len; i++) { data.push(array[i]); text.push((i+1).toFixed(0)); } stat.init(data, '点数和', '概率', 1); stat.lineGraph(text, 0, 0, 0, 0.3); }
这种方法是不公平的,数据说明了一切。
>>> pow(1/6, 10);
1.6538171687920194e-08
[人叫板老师]点明了这‘出老千’的现象是真实存在的。
<span style="font-size:18px;">>>> 三天内有两天下雨的概率是0.4 未来三天的天气情况是 [[1, 9, 0], [6, 6, 3], [8, 5, 1], [4, 5, 3], [6, 6, 3], [1, 1, 0], [1, 4, 5], [6, 3, 6], [5, 0, 1], [1, 8, 6], [0, 2, 1], [3, 5, 4], [2, 6, 8], [1, 2, 8], [5, 3, 6], [4, 9, 1], [7, 4, 9], [0, 1, 8], [8, 9, 1], [3, 2, 7]] >>> 三天内有两天下雨的概率是0.3 未来三天的天气情况是 [[3, 7, 9], [7, 5, 6], [5, 2, 0], [8, 8, 3], [6, 0, 3], [6, 1, 6], [5, 2, 8], [2, 2, 2], [1, 5, 5], [6, 6, 3], [0, 3, 2], [2, 2, 5], [6, 4, 7], [5, 7, 5], [1, 0, 2], [2, 6, 1], [3, 3, 4], [8, 8, 5], [2, 9, 1], [2, 0, 2]] def weather(): N = 20; array = [([0]*3) for i in range(N)]; for i in range(N): for j in range(3): array[i][j] = random.randint(0, 9); count2 = 0; for i in range(N): count = 0; for j in range(3): if array[i][j]>=1 and array[i][j]<=4: count+=1; if count == 2: count2+=1; print('三天内有两天下雨的概率是{0}'.format(count2/N)); print('未来三天的天气情况是\n{0}'.format(array)); if __name__ == '__main__': weather();</span>
<span style="font-size:18px;">>>> 试验次数--两个正面朝上次数---两个反面朝上次数 [ 100 , 38 , 35 ] >>> 试验次数--两个正面朝上次数---两个反面朝上次数 [ 100 , 34 , 38 ] >>> 试验次数--两个正面朝上次数---两个反面朝上次数 [ 100 , 32 , 40 ] def coin(): result = [0]*2; print('试验次数--两个正面朝上次数---两个反面朝上次数'); for i in range(100): count = [0]*2; for j in range(3): number = random.randint(1, 10000); if number%2 == 0: count[0]+=1; else: count[1]+=1; if (count[0] == 2): result[0]+=1; if (count[1] == 2): result[1]+=1; #result.append([i, count, count/i]); print('[ 100',',',result[0],',',result[1], ']'); </span>
<span style="font-size:18px;">>>> 第1小题的概率是0.079 第2小题的概率是0.921 第3小题的概率是0.263 第4小题的概率是0.137 第5小题的概率是0.0 第6小题的概率是0.166 第7小题的概率是0.514 第8小题的概率是1.0 >>> ================================ RESTART ================================ >>> 第1小题的概率是0.093 第2小题的概率是0.907 第3小题的概率是0.242 第4小题的概率是0.153 第5小题的概率是0.0 第6小题的概率是0.153 第7小题的概率是0.515 第8小题的概率是1.0 def card(): #抽牌1000次 N = 1000; #8个小题 result = [0]*8; for i in range(N): #52张牌 number = random.randint(1, 52); #约定1-13 第一组红心,依次黑桃、方块、草花 #(1) if number%13 == 7: result[0]+=1; #(2) if number%13 != 7: result[1]+=1; #(3) 方片 if number//13==2: result[2]+=1; #(4) JQK if number%13 > 10: result[3]+=1; #(5) if number//13==0 and number//13 == 3: result[4]+=1; #(6) if number%13 > 6 and number%13<9: result[5]+=1; #(7) if (number//13)%2==0: result[6]+=1; #(8) if (number//13)%2==0 or (number//13)%2==1: result[7]+=1; for i in range(len(result)): print('第{0}小题的概率是{1}'.format(i+1, result[i]/N)); if __name__ == '__main__': card(); </span>
<span style="font-size:18px;">>>> [0.0, 0.35, 1.0] >>> ================================ RESTART ================================ >>> [0.0, 0.44, 1.0] >>> ================================ RESTART ================================ >>> [0.0, 0.4, 1.0] def ball(): N = 100; result = [0]*3; for i in range(N): #9个球编号1-9 number = random.randint(1, 9); if number < 1: result[0]+=1; if number < 5: result[1]+=1; if number < 10: result[2]+=1; for i in range(len(result)): result[i]/=N; print(result); if __name__ == '__main__': ball();</span>
<span style="font-size:18px;">>>> 两个骰子点数和为1的概率是0.0 两个骰子点数和为2的概率是0.02 两个骰子点数和为3的概率是0.06 两个骰子点数和为4的概率是0.08 两个骰子点数和为5的概率是0.09 两个骰子点数和为6的概率是0.11 两个骰子点数和为7的概率是0.225 两个骰子点数和为8的概率是0.145 两个骰子点数和为9的概率是0.12 两个骰子点数和为10的概率是0.085 两个骰子点数和为11的概率是0.055 两个骰子点数和为12的概率是0.01 #掷骰子, 两骰子点数和 def dice(): N = 200; count = [0]*12; for i in range(N): number1 = random.randint(1,6); number2 = random.randint(1,6); count[number1+number2-1]+=1; for i in range(len(count)): count[i]/=N; for i in range(len(count)): print('两个骰子点数和为{0}的概率是{1}'.format(i+1, count[i])); if __name__ == '__main__': dice();</span>
本节到此结束。欲知后事怎样,请看下回分解。