【程序员眼中的统计学(5)】排列组合:排序、排位、排

排列组合:排序、排位、排

0 问题



回到顶部

1 基本计数法则


1  分类加法计数原则

定义若具有性质A的事件有m个,具有性质B的事件有n个,则具有性质A或性质B的事件有m+n个。

例子:事件A:a点到b点乘火车有3条线路。
        事件B:a点到b点乘汽车有2条线路。
        则a点到b点共有(2+3)=5条不同线路

解释说明:完成一件事,有n类方法。在第1类办法中有m1种不同的方法,在第2类方法中有m2种不同的方法,……,在第n类方法中有mn 种不同的方法,则完成这件事的不同方法共有:N=m1+m2+...+mn

注意点:各类方法相互独立的。

2 分步乘法计数原则

定义:若具有性质A的事件有m个,具有性质B的事件有n个,则具有性质A与性质B的事件有m*n个。

例子:事件A:a点到b点有3条不同的路径。
      事件B:b点到c点有2条不同的路径。
      则a点到b点共有3*2=6条不同的路径。

解释说明:完成一件事,需要分成n个步骤。做第1步有m1种不同的方法,做第2步有m2种不同的方法,……,做第n步与mn种不同的方法,则完成这件事的不同方法共有:N=m1*m2*mn

注意点:各个步骤相互依存。

3 分类计数原理与分布计数原理相同点与不同点

  • 相同点: 分类计数原理与分布计数原理都是涉及完成一件事的不同方法的种数问题。
  • 不同点: 分类计数原理与“分类”有关,各种方法相互独立,用其中任何一种方法都可以完成这件事。 分布计数原理与“分布”有关,各个步骤相互依存,只有各个步骤都完成了,这件事才算完成。

回到顶部

2 排列


1 排列描述

排列的定义

设 A={a1,a2,...,an}是n个不同元素的集合,m满足0≤m≤n。任取A中m个元素按顺序排成一列,称为从A中取m个的一个无重排列。

例子:

排列符号定义

从n个不同元素中,任取m个元素的所有排列的个数叫做从n个元素的排列数,用符号表示。

排列计算公式

选排列:当m<n时的排列称为选排列。选排列数公式:

 

全排列:当m=n时的排列称为全排列。全排列公式:

 

2  排列的优缺点

优点

可以辅助计算排列的概率问题。

缺点

此公式只适用m个元素是不同的情况,如果当m个元素有重复的时候就不能用此方法,使用受到条件限制。

排列应用

可以计算彩票的中奖概率,分析彩票的购买的排列情况,如七位数等。

回到顶部

3  圆周排列


1  圆周排列描述

圆周排列定义

从n个不同的数中不重复的取出m个沿一圆圈排列,称为一个圆周排列,表示为 。

圆周排列符号定义

从n个不同的数中不重复的取出m个沿一圆圈排列,得到的排列数,符号表示为 

例子

圆周排列计算公式

2  圆周排列优缺点

优点

可以快速计算圆周排列的排列数。

缺点

不区分圆周排列是逆时针还是顺时针排列。

圆周排列应用

在圆形的马场比赛跑道,可以计算赛马的中奖概率。

回到顶部

4 组合


1  组合描述

组合的定义

从n个不同元素中不重复的选取m个元素,组成一组(不管其顺序),称为从n个不同元素中选取m个元素的无重组合。

组合符号定义

从n个不同元素中不重复的选取m个元素,组成一组(不管其顺序),得到的排列数用符号 表示。

例子:

组合计算公式 

 

组合数的两个性质: 

2  组合的优缺点

优点

生活中经常计算概率的时候经常需要用到组合辅助计算。

缺点

输入的n个元素必须互不相同。

组合应用

可以计算彩票的中奖概率,分析彩票的购买的组合情况,如组合3。

回到顶部

5  排列组合算法



 

1 排列算法

递归法、字典序法、递增进位数制法、递减近位数制法、邻位交换法、n进制法……

递归算法

输入:{1,2,3}。输出:123,132,213,231,312,321

算法思想:第一位取1,对2,3全排列。第一位取2,对1,3全排列。第一位取3,对1,2全排列。

字典序法

算法思想:设p是集合{1、2、3、4……n}的一个全排列:p=p1p2.....pn

1、从排列的右端往左,找出第一个比右边数字小的数字序号j,也就是第一个顺序两位数。

2、从右端开始到j.找出第一个比pj大的数字pk。

3、交换pj,pk

4、对交换后的集合中p(j+1)......pn顺序逆转,也就是顺序排列。

2  排列算法描述

排列算法输入数据、输出结果

* @param object       输入可选元素

* @param m              选取m个数排列

* @param out           输出排列后的元素集

* @return                  输出排列总数

类和方法描述

类名:Permutation.java

方法:

getCountByLine(Object[] object, long m)获取无重排列数目

getCountByCircle(Object[] object, int m)获取无重圆周排列数目

getAllPermutation(Object[] in, List<Object[]> out, int index)得到所有排列

java代码实现

类名:Permutation.java

方法:

getCountByLine(Object[] object, long m)获取无重排列数目

getCountByCircle(Object[] object, int m)获取无重圆周排列数目

getAllPermutation(Object[] in, List<Object[]> out, int index)得到所有排列

java代码实现

/**
     * 获取无重线排列总数目
     * 描述:从n个元数中选取m个元数进行全排列,得出一共有多少种排法
     * 公式:A(m,n)=m!/(n-m)!
     * 优缺点:输入数据必须互不相同。求阶乘时,使用了for循环,避免了递归方法导致内存溢出的风险。
     * (object数组中元素总数为n,从object数组中选出的m个数排列)
     * @param object    输入可选元素
     * @param m            选取m个数排列
     * @return            输出排列总数
     */
    public static BigInteger getCountByLine(Object[] object, long m) {
        long n = object.length;
        BigInteger result = MathUtils.factorial(n-m+1, n);//计算n-m+1到n的阶乘
        return result;
    }
    /**
     * 获取无重圆周排列数目
     * 描述:从n个数中选取m个数进行圆周排列,获取一共有多少种排法
     * 公式:Q(m,n)=A(m,n)/m=m!/(m*(n-m)!)
     * 优缺点:输入数据必须互不相同。m定义了int类型,限制了计算范围。
     * (object数组中元素总数为n,从object数组中选出的m个数圆周排列)
     * @param object    输入可选元素
     * @param m            选取m个数排列
     * @return            输出排列总数
     */
    public static BigInteger getCountByCircle(Object[] object, int m) {
        int n = object.length;
        BigInteger result = MathUtils.factorial(n-m+1, n).divide(BigInteger.valueOf(m));//计算n-m+1到n的阶乘除以m
        return result;
    }
    /**
     * 全排列(递归)
     * 例:输入{1,2,3}输出{1,2,3}{1,3,2}{2,1,3}{2,3,1}{3,1,2}{3,2,1}
     * 描述:输入一个数组,对数组中的所有元素进行全排列,把每种排列放入out集合中。
     * 优缺点:输入数据必须互不相同。使用了递归的算法,当输入数据比较大时,会存在内存溢出的危险。
     * @param in    输入数据
     * @param out    输出数据
     * @param index 默认为0
     */
    public static void getAllPermutation(Object[] in, List<Object[]> out, int index) {
        if(index == in.length-1) {
            Object[] outTemp = in.clone();
            out.add(outTemp);
        }
        for(int i=index; i<in.length; i++) {
            swap(in,index,i);
            getAllPermutation(in,out,index+1);//递归
            swap(in,index,i);
        }
    }
    /**
     * 获取所有排列
     * 例:输入{1,2,3}输出{1}{2}{3}{1,2}{2,1}{1,3}{3,1}{2,3}{3,2}{1,2,3}……
     * 描述:输入一个数组,先从数组中选取一个数全排列,再选取两个两个数全排列,再选取三个数全排列,把所有的得到的排列放入out集合中。
     * 优缺点:输入元素必须互不相同。
     * @param in    输入数据
     * @param out    输出数据
     */
    public static void getSelectPermutaion(Object[] in, List<Object[]> out) {
        List<Object[]> outTemp = new ArrayList<Object[]>();
        for(int i=0; i<in.length; i++) {
            Combination.getCombination(in, outTemp, i+1);//获取所有组合
        }
        for(int i=0; i<outTemp.size(); i++) {
            getAllPermutation(outTemp.get(i), out, 0);//对每种组合进行全排列
        }
    }
    /**
     * 交换下标为i,j两个元素
     * 描述:对object数组的i,j位置的元素进行交换
     * @param object
     * @param i
     * @param j
     */
    public static void swap(Object[] object, int i, int j) {
        Object temp = object[i];
        object[i] = object[j];
        object[j] = temp;
    }

排列算法异常和误差

输入数据时检查数据类型,输出的数据被转换成Object类型了。

适用或不适用场景

输入的元素是互不相同的,并且有序排列。可以据此分析彩票的中奖率,比如七位数。

3 组合算法描述

二进制法

算法思想:首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为 “01”组合,同时将其左边的所有“1”全部移动到数组的最左端。当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。

组合算法输入数据、输出结果

* @param in          输入可选元素

* @param m              选取m个数排列

* @param out           输出组合后的元素集

* @return                  返回组合后的数目

 

类和方法描述

类名:Combination.java

方法:

getCount(Object[] in, long m)获取组合数

getCombination(Object[] in, List<Object[]> out, int m)获取组合后的所有情况

java代码实现

/**
     * 获取无重组合数目
     * 描述:从n个数中选取m个元素组成一组,得到一共有多少种不同的组合
     * 公式:C(m,n)=n!/(m!*(n-m)!)
     * @param in    输入可选元素
     * @param m        每次选m个
     * @return        返回组合后的总数目
     */
    public static BigInteger getCount(Object[] in, long m) {
        long n = in.length;
        BigInteger result = BigInteger.valueOf(1);
        if(m<2/n) {//增加计算效率
            result = MathUtils.factorial(n-m+1, n).divide(MathUtils.factorial(1, m));//计算公式
        } else {
            result = MathUtils.factorial(m+1, n).divide(MathUtils.factorial(1, n-m));//计算公式
        }
        return result;
    }
    /**
     * 组合(二进制法)
     * 例:输入{1,2,3}从中选2个的数组合。输出:{1,2}{1,3}{2,3}
     * 描述:从输入的元素中,选m个元素组合,把所有的组合存在out中
     * @param in    输入数组
     * @param out    输出组合后的数组集
     * @param m        取出m个数
     */
    public static void getCombination(Object[] in, List<Object[]> out, int m) {
        int n = in.length;
        int[] array = new int[n];
        for(int i=0; i<n; i++) {//初始化
            if(i<m)
                array[i] = 1;
            else
                array[i] = 0;
        }
        List<int[]> list = new ArrayList<int[]>();
        boolean flag = true;
        while(flag) {
            int[] intTemp = array.clone();
            list.add(intTemp);
            for(int i=0; i<n-1; i++) {
                if(array[i]==1 && array[i+1]==0) {
                    array[i]=0;//交换i,i+1的值
                    array[i+1]=1;
                    if(array[0]==0) {//把i位置左边的1都移到最左边
                        for(int k=0,j=0;k<i;k++) {
                            if(array[k]==1) {
                                array[j]=1;
                                array[k]=0;
                                j++;
                            }
                        }
                    }
                    break;
                }
                if(i==n-2) flag = false;
            }
        }
        for(int i=0; i<list.size(); i++) {//把二进制中的1转换成对应的数组
            Object[] objTemp = new Object[m];
            for(int j=0,k=0;j<n;j++) {
                if(list.get(i)[j]==1) {
                    objTemp[k] = in[j];
                    k++;
                }
            }
            out.add(objTemp);
        }
    }

组合算法异常和误差

输入数据时检查数据类型,输入数据的可选范围是受限的。输出的数据为Object类型了,可以通过类型转换变为与输入数据一致的类型。

适用或不适用场景

输入的元素必须是互不相同的,并且属于抽取不放回的情况,抽出是无序的。可以据此分析彩票的中奖率,比如组合3。

回到顶部

6 本章总结


 排列与组合的区别

 

7 开源共享 


 PPT:http://yunpan.cn/cFwhKFiKraHWr 访问密码 5662

开源代码:http://yunpan.cn/cFwhjdaqB9iFs 访问密码 624d

http://www.cnblogs.com/baiboy

时间: 2024-11-01 22:02:30

【程序员眼中的统计学(5)】排列组合:排序、排位、排的相关文章

【程序员眼中的统计学(12)】相关与回归:我的线条如何? (转)

阅读目录 目录 1 算法的基本描述 2 算法的应用场景. 3算法的优点和缺点 4 算法的输入数据.中间结果以及输出结果 5 算法的代码参考 6 共享 相关与回归:我的线条如何? 作者 白宁超 2015年10月25日22:16:07 摘要:程序员眼中的统计学系列是作者和团队共同学习笔记的整理.首先提到统计学,很多人认为是经济学或者数学的专利,与计算机并没有交集.诚然在传统学科中,其在以上学科发挥作用很大.然而随着科学技术的发展和机器智能的普及,统计学在机器智能中的作用越来越重要.本系列统计学的学习

【程序员眼中的统计学(7)】正态分布的运用:正态之美

正态分布的运用:正态之美 1正态分布描述 正态分布是最重要的一种概率分布.正态分布概念是由德国的数学家和天文学家Moivre(棣莫弗)于1733年受次提出的,但由于德国数学家Gauss(高斯)率先将其应用于天文学家研究,故正态分布又叫高斯分布.正态分布起源于误差分析,早期的天文学家通过长期对一些天体的观测收集到了大量数据,并利用这些数据天体运动的物理模型,其中第谷与开 普勒在建模中提出了一条原则-"模型选择的最终标准是其与观测数据的符合程度",这个"符合程度"实质上

【程序员眼中的统计学(6)】几何分布、二项分布及泊松分布:坚持离散

几何分布.二项分布及泊松分布:坚持离散 1 回顾题引 1 问题? 小明滑雪: 每次(独立事件)试滑成功的概率0.2,不成功的概率0.8.则 成功 失败 0.2 0.8 1.试滑两次成功的概率?2.试滑一次或两次猜中的概率?3.试滑10000次,首次成功的概率?4.试滑第10000次以上成功的概率? 2 概率树: 3 解答: 1.概率树求概率 设X最终试滑成功次数,则:P(X=1)=P(第1次试滑成功)=0.2 [注:试滑一次成功的概率]P(X=2)=P(第1次试滑失败AND第2试滑成功)=0.2

【程序员眼中的统计学(6.2)】原创实现二项分布算法以及应用

 二项分布算法 1 算法的基本描述,包括:定义.符号解释.具体的计算方法. 1.1 算法描述 在进行一系列相互独立实验,每次既有成功,又有失败的可能,且单次实验成功概率相等.在一系列试验中求成功的次数.这种情况下适用于本算法. 本算法中在n次伯努利试验中:试验n次得到r次成功的概率.二项分布的期望.二项分布方差的具体实现. 1.2 定义 在相互独立事件中,每道题答对概率为p,答错概率为q.在n个问题中答对r个问题的概率为:  这类问题称之为二项分布.表达式为:X~B(n,p) 1.3 符号解释

【程序员眼中的统计学(4)】离散概率分布的运用:善用期望

离散概率分布的运用:善用期望  1 离散概率分布 1  定义 设离散型随机变量X所有可能得取值 Xi (i=1,2,3--.n),且事件{X=xi }的概率为P{X=xi }= pi ,此称为离散型随机变量的概率分布或分布列,即离散概率分布.用表格可表示: 作为一个离散概率分布,应满足以下两个性质: 在日常生活中此类例子不胜枚举,比如,扔一枚或多枚硬币,出现正面朝上的次数. 2    基本概念 离散随机变量 若一个随机变量X的所有可能的取值为有限个或无限可数个, 则称它为离散型随机变量.例如,玩

【程序员眼中的统计学(8)】统计抽样的运用:抽取样本

统计抽样的运用:抽取样本 1总体和样本 1.1总体和样本及相关概念 总体(population):统计学上指的是准备进行测量.研究或分析的整个群体.可以是人.得分,也可以是糖果 - 关键在于总体指的是所有对象.总体可分为有限总体和无限总体. 个体:组成总体的每一个考查对象. 样本(Sample):从总体中选取的一部分对象,是总体的一个子集.样本具有代表性,能在一定程度上反映总体特性. 抽样(Sampling):从总体中抽取部分个体的过程成为抽样,强调的是过程. 样本容量(Sample Size)

【程序员眼中的统计学(6.1)】原创实现几何分布算法以及应用

 几何分布算法 1 算法的基本描述,包括:定义.符号解释.具体的计算方法. 1.1 算法描述 在进行一系列相互独立实验,每次既有成功,又有失败的可能,且单次实验成功概率相等.为了取得第一次成功需要进行多少次实验.这种情况下适用于本算法. 本算法中在n次伯努利试验中:试验r次得到第一次成功的概率.试验r次以上才第一次成功的概率.试验r次或者不到r次才第一次成功.几何分布的期望.几何分布方差的具体实现. 1.2 定义 如果p代表成功概率,则1-p即q代表失败概率使用以下 公式叫做概率的几何分布. 1

【程序员眼中的统计学(2)】集中趋势度量:分散性、变异性、强大的距

 集中趋势度量:分散性.变异性.强大的距 1 平均值 1.1 均值算法的描述 均值的定义 均值有两种计算方法:第一种计算方式是:将所有的数字加起来,然后除以数字的个数 .可用记为:µ=∑x/n 另一种计算方法是把每个数的频数考虑进去了的,它表示如下:µ=∑fx/f 均值符号定义 n:表示的是输入的数据的个数 µ:为数据的均值 ∑:表示所有数据之和 均值算法中的计算方法 统计出输入数据的个数n 计算出所有的数据之和 sum 计算出数据的均值avg=sum/n 1.2 均值算法的应用场景 案例描述:

【程序员眼中的统计学(1)】信息图形化:第一印象

1 饼图算法描述 1.1 饼图算法基本描述 在介绍饼图之前我们先来看一张表格: 上图是表示某公司在下半年中每月的利润情况. 就这张表格而言,我们只能知道各个月份的利润,却无法知道每个月份占总利润的比例,根据这张表格我们画出了两张图,如下: 我们从图中很容易可以得到两个信息:第一幅图看起来数据相差不大,第二幅图看起来数据相差非常大,对于同一张表所画出的两张图为什么会有两种截然不同的见解呢? 其实会发生上述不同的观点主要是因为这两张图的纵轴和标度不一样,第一张图纵轴的起点是0,标度是0.5,而第二张