这是上学期由于课程需要,需要用编程来解决求出关于高等数学概率论与数理统计中的期望问题。所以当时我就选了在生活中实际应用最广泛最常见的离散型随机变量的期望(超市抽奖问题),现在整理一下记录。
数学期望来源:
在17世纪,有一个赌徒向法国著名数学家帕斯卡挑战,给他出了一道题目:甲乙两个人赌博,他们两人获胜的机率相等,比赛规则是先胜三局者为赢家,一共进行五局,赢家可以获得100法郎的奖励。当比赛进行到第四局的时候,甲胜了两局,乙胜了一局,这时由于某些原因中止了比赛,那么如何分配这100法郎才比较公平?
用概率论的知识,不难得知,甲获胜的可能性大,乙获胜的可能性小。
因为甲输掉后两局的可能性只有(1/2)×(1/2)=1/4,也就是说甲赢得后两局的概率为1-(1/4)=3/4,甲有75%的期望获得100法郎;而乙期望赢得100法郎就得在后两局均击败甲,乙连续赢得后两局的概率为(1/2)*(1/2)=1/4,即乙有25%的期望获得100法郎奖金。
可见,虽然不能再进行比赛,但依据上述可能性推断,甲乙双方最终胜利的客观期望分别为75%和25%,因此甲应分得奖金的100*75%=75(法郎),乙应分得奖金的的100×25%=25(法郎)。这个故事里出现了“期望”这个词,数学期望由此而来。
离散型随机变量期望:
如果随机变量只取得有限个值或无穷能按一定次序一一列出,其值域为一个或若干个有限或无限区间,这样的随机变量称为离散型随机变量。
离散型随机变量的一切可能的取值 与对应的概率
乘积之和称为该离散型随机变量的数学期望(若该求和绝对收敛),记为
。
公式
离散型随机变量X的取值为 ,
为X对应取值的概率,可理解为数据
出现的频率
,则:
超市抽奖问题(原问题链接地址:https://wenku.baidu.com/view/50ec11aa0b1c59eef9c7b48e.html):
代码:
一共编写了3个类:
Combine类:用来得到n个数据的全部组合
package mathTest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class Combine {
//为了保证不会出现值相同的重复数据
Set<String> testSet = new TreeSet<String>(new MyComparator());
public <E> Set<String> combinerSelect(List<E> data, List<E> workSpace, int n, int k) {
List<E> copyData;
List<E> copyWorkSpace;
if(workSpace.size() == k) {
String data1="";
for(int o=0;o<workSpace.size();o++){
//System.out.print(workSpace.get(o));
if(o!=workSpace.size()-1)
data1=data1+workSpace.get(o)+",";
else
data1=data1+workSpace.get(o);
}
testSet.add(data1);
}
for(int i = 0; i < data.size(); i++) {
copyData = new ArrayList<E>(data);
copyWorkSpace = new ArrayList<E>(workSpace);
copyWorkSpace.add(copyData.get(i));
for(int j = i; j >= 0; j--)
copyData.remove(j);
combinerSelect(copyData, copyWorkSpace, n, k);
}
return testSet;
}
}
DataEx类:求某个组合的概率分布(分布率)
package mathTest;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class DataEx {
public double GetDataEx(List<String> data, String[] results, int num) {
// 得到数据的总个数
int dataNum = data.size();
int m=0;
int n=0;
double retu=1.0;
//计算在原始数据中所有对象出现的次数 写入到map中
Map map = new HashMap();
for (String temp : data) {
Integer count = (Integer) map.get(temp);
map.put(temp, (count == null) ? 1 : count + 1);
}
//计算在组合后的数据中某个组合所有对象出现的次数 写入到map中
Map map1 = new HashMap();
for (String temp : results) {
Integer count = (Integer) map1.get(temp);
map1.put(temp, (count == null) ? 1 : count + 1);
}
//得到map1中的所有键
Iterator iterator=map1.keySet().iterator();
while(iterator.hasNext()){
Object ob=iterator.next();
int n1= (int)map.get(ob);
int m1= (int)map1.get(ob);
retu=retu*this.Calculation(m1, n1);
}
retu=retu/this.Calculation(num, dataNum);
return retu;
}
//求得组合c(m,n)的结果
public double Calculation(int m, int n) {
//分子值
double numerator=n;
//分母值
double denominator=m;
for (int i = n; i > n-m+1; i--) {
numerator = numerator * (i - 1);
}
//因为在java中double输出会默认使用科学记数法输出,所以数值位数较多是需要将其格式化为指定指定格式
//System.out.println(new DecimalFormat("###############0.000000").format(numerator));
for (int j = m; j >1; j--) {
denominator = denominator *(j - 1);
}
//System.out.println(new DecimalFormat("###############0.000000").format(denominator));
double retu=numerator/denominator;
return retu;
}
}
main类:主程序类,初始化并输出各项数据,计算数学期望
package mathTest;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class main {
public static void main(String[] args) {
DataEx dataex=new DataEx();
//原始数据
List<String> data = new ArrayList<String>();
//用来标识从中取的个数
int flag=10;
//用来设置求期望的X,若不设置则默认X为抽得分数
List<Double> Ex = new ArrayList<Double>();
Ex.add((double) 2500);
Ex.add((double) 178);
Ex.add((double) 2);
Ex.add((double) 3);
Ex.add((double) -22);
Ex.add((double) -22);
Ex.add((double) 5);
Ex.add((double) 8);
Ex.add((double) 44);
Ex.add((double) 88);
Ex.add((double) 1000);
//用来存放求得的期望
Double expectation=0.0;
for(int i=0;i<10;i++){
data.add("10");
}
for(int i=0;i<10;i++){
data.add("5");
}
Combine t = new Combine();
for(int i = 1; i < data.size(); i++)
t.combinerSelect(data, new ArrayList<String>(), data.size(), i);
Iterator it=t.testSet.iterator();
//用来存放数据相加的值,用来判断是否有重复项
List<Integer> sums = new ArrayList<Integer>();
//用来记录是第几个组合
int a=1;
//循环得到每个组合
while(it.hasNext()){
//得到组合
String item=it.next().toString();
//进行字符串分割
String[] results = item.split(",");
int sum=0;
//如果长度是设定的取出的个数
if(results.length==flag){
for(int j=0;j<flag;j++){
sum=sum+Integer.parseInt(results[j]);
}
sums.add(sum);
boolean f=false;
//循环判断sum是否在sums中有重复的值
for(int i=0;i<sums.size()-1;i++){
if(sum==sums.get(i))
f=true;
}
if(!f){
System.out.println("-----------第"+a+"个组合分析开始-----------");
System.out.println("组合:"+item);
System.out.println("组合相加值:"+sum);
Double probability=dataex.GetDataEx(data,results,flag);
System.out.println("组合概率分布(分布率):"+new DecimalFormat("###############0.000000").format(probability));
if(Ex!=null&&Ex.size()!=0){
expectation=expectation+Ex.get(a-1)*probability;
}else{
expectation=expectation+sum*probability;
}
System.out.println();
a++;
}
}
}
System.out.println("数学期望为:"+new DecimalFormat("###############0.000000").format(expectation));
}
}
运行结果图:
完全正确运行。如果你想要计算其他的期望问题,只需修改代码中里面的数值即可。
所以我根据这个题目编写了简单的JAVA控制台版的自动求离散型随机变量期望,此程序经过改进可以方便高效准备快捷的解决生活中的各种求利润、效益等最优化的问题。例如经济决策问题、投资方案问题、体育比赛问题、抽奖问题等。比如商家就可此程序来控制抽奖的利润。
我的博客地址:www.b0c0.com 欢迎访问