求一个随机抽奖的算法

有没有这样一个算法,要求:
用n次随机结果代替排列组合的概率。
具体比如
枚举step1到20
a=(int)(10000/(20-step+1))
b=(int)(10000×random)
如果b小于a则认为该step被选中。同时该step到20为止都不再计算概率。这样就完成从20个数里即时选出一个数,同时我运行了1000w组,统计得到每个step被选中的频率都是0.05;每二十个数会选中一个。
那么有没有这样的算法可以实现: 我要从二十个数中选三个,每个数都有0.15的中选可能,同时每20个数中必中三个。

2

3个回答

“20个数中必中三个”参考:从未知大小的n个数中取m个数,使各数被取出的概率相等
现在m=3,就算已知n=20也用不到。反正以20个为一组按这个算法选3。

1
u010918104
琉璃村正 嗯 这个办法 大大能不能回答下我后面这个问题,为什么在模拟次数多了以后会出现例外?是因为int的精度问题还是别的什么
大约 4 年之前 回复
u010918104
琉璃村正 嗯 这个办法 大大能不能回答下我后面这个问题,为什么在模拟次数多了以后会出现例外?是因为int的精度问题还是别的什么
大约 4 年之前 回复
u010918104
琉璃村正 嗯 这个办法 大大能不能回答下我后面这个问题,为什么在模拟次数多了以后会出现例外?是因为int的精度问题还是别的什么
大约 4 年之前 回复

这个算法我明白了,把经典概率转化为条件概率就可以了,然后我写了这个
[code=java]
package choujiang;

public class hit {
public static int a[] = new int[21];
public static int b[] = new int[21];
public static int c[] = new int[21];
static boolean mark = false;// 记录是否发出一等奖
static int mark2 = 0;

boolean go_hit(int round) {// 伪随机方法
    int fate = 0;
    int rate = 0;
    boolean temp = false;
    if (mark == false) {
        rate = (int) (10000 / (20 - round + 1));
        fate = (int) (10000 * Math.random());
        if (fate < rate) {
            mark = true;
            temp = true;
        }
    } else {
        temp = false;
    }
    return temp;
}

boolean go_hit2(int round) {// 伪随机方法
    boolean temp = false;
    int fate = 0;
    int rate = 0;
    if (mark2 <= 3) {
        rate = (int) ((3 - mark2) * 1000 / (20 - round + 1));
        rate = (int) (rate / 0.95);
        fate = (int) (1000 * Math.random());
        if (fate <= rate) {
            mark2 = mark2 + 1;
            temp = true;
        }
    }
    return temp;
}

public static void main(String[] args) {
    int round = 0;
    for (int i = 0; i < 10000000; i++) {// 模拟1000000次
        hit see = new hit();
        round = 1;
        mark = false;
        mark2 = 0;
        while (round <= 20) {
            if (see.go_hit(round)) {
                a[round] = a[round] + 1;// 累计结果观察概率
                // System.out.println("一等奖" + round);// 模拟抽奖中奖过程
            } else {
                if (see.go_hit2(round)) {
                    b[round] = b[round] + 1;
                    // System.out.println("二等奖" + round);
                } else {
                    c[round] = c[round] + 1;
                    // System.out.println("三等奖" + round);
                }

            }
            round++;
        }
    }
    for (int i = 1; i < a.length; i++) {
        System.out.print("a" + i + "is" + "   " + a[i] + " ");// 查看概率
        System.out.print("b" + i + "is" + "   " + b[i] + " ");// 查看概率
        System.out.print("c" + i + "is" + "   " + c[i] + " ");// 查看概率
        System.out.println("*");
    }
}

}
[/code]
运行结果
a1is 500753 b1is 1501149 c1is 7998098 *
a2is 499482 b2is 1497660 c2is 8002858 *
a3is 500282 b3is 1496837 c3is 8002881 *
a4is 500130 b4is 1502287 c4is 7997583 *
a5is 499141 b5is 1500685 c5is 8000174 *
a6is 499022 b6is 1504222 c6is 7996756 *
a7is 499067 b7is 1501090 c7is 7999843 *
a8is 499833 b8is 1501011 c8is 7999156 *
a9is 500068 b9is 1504420 c9is 7995512 *
a10is 500269 b10is 1499587 c10is 8000144 *
a11is 499821 b11is 1507425 c11is 7992754 *
a12is 497801 b12is 1504257 c12is 7997942 *
a13is 500746 b13is 1508028 c13is 7991226 *
a14is 498638 b14is 1502178 c14is 7999184 *
a15is 500871 b15is 1502920 c15is 7996209 *
a16is 500978 b16is 1508363 c16is 7990659 *
a17is 500327 b17is 1508092 c17is 7991581 *
a18is 500772 b18is 1503604 c18is 7995624 *
a19is 500923 b19is 1495613 c19is 8003464 *
a20is 501076 b20is 1422746 c20is 8076178 *

有一个问题就是为什么我这里在20上的取值会少那么多,我加标记数组尝试了下,发现出现了不少二等奖只取两个数的特例,但是根据概率
P=(3-已取个数)/(20-位置+1)来看 就算前面一个不取,那最后三个的概率都是100%,为什么能出现只选择2个的情况???
@Tiger_Zhao

0
u010918104
琉璃村正 恩恩 搞清楚了我把两个概率分开看了才导致最后会出现要选两个数但总共只有一个数的情况。我直接把四个数看成等价的然后从四个数中再求一次独立事件的概率就好了,谢谢大大!
大约 4 年之前 回复
Tiger_Zhao
Tiger_Zhao 完全不对。那个算法是先把前m个放入备选数组,然后对剩下的n-m个按照各自个概率去替换备选数组中的(随机)某个成员。最后剩下的备选数组成员才是结果。
大约 4 年之前 回复

贴下整理后的代码:

public class fullhit{
public static int geted = 0;
public static boolean task = false;
public static int[] a = new int[21];
public static int[] b = new int[21];
public static int[] c = new int[21];

boolean first_hit(int round) {
    boolean tempmark;
    tempmark = false;
    int rate = 0;
    int fate = 0;
    rate = (int) ((4 - geted) * 10000 / (20 - round + 1));
    fate = (int) (10000 * Math.random() + 1);
    if (fate <= rate) {
        tempmark = true;
        geted++;
    }
    return tempmark;
}

int socend_hit() {
    int r;
    int f;
    int tempint = 0;
    r = (int) 10000 / (4 - geted + 1);
    f = (int) (10000 * Math.random());
    if ((task == false) & (f <= r)) {
        tempint = 1;
        task = true;
    } else {
        tempint = 0;
    }
    return tempint;
}

public static void main(String[] args) {
    int round = 0;
    int s = 0;// 模拟楼层计数器
    int ta = 0;// 一等奖检测
    int tb = 0;// 二等奖检测
    boolean mark;// 检测:不符合每20个出现1个一等奖和3个二等奖就终止程序
    fullhit fh = new fullhit();
    for (int i = 1; i <= 10000000; i++) {//模拟10mX20个楼层
        round = 0;
        geted = 0;
        task = false;
        ta = 0;
        tb = 0;
        mark = true;
        while (round < 20) {
            round++;
            if (fh.first_hit(round)) {
                if (fh.socend_hit() == 1) {
                    // 模拟一等奖;
                    a[round]++;
                    ta++;
                } else {
                    // 模拟二等奖;
                    b[round]++;
                    tb++;
                }
            } else {
                // 模拟三等奖;
                c[round]++;
            }
        }
        if (ta != 1) {
            mark = false;
        }
        if (tb != 3) {
            mark = false;
        }
        if (mark == false) {
            System.out.println("error");
            break;
        }

    }
    for (int i = 1; i <= 20; i++) {
        // 查看选中概率
        System.out.print("a" + i + "的个数=" + a[i] + "("+a[i]/10000+"%。)|");
        System.out.print("b" + i + "的个数=" + b[i] + "("+b[i]/10000+"%。)|");
        System.out.print("c" + i + "的个数=" + c[i]+"("+c[i]/10000+"%。)");
        System.out.println("|");
        s = a[i] + b[i] + c[i];
    }
    System.out.println(s);
}
}
运行结果:

a1的个数=499824(49%。)|b1的个数=1497290(149%。)|c1的个数=8002886(800%。)|
a2的个数=500605(50%。)|b2的个数=1498930(149%。)|c2的个数=8000465(800%。)|
a3的个数=500648(50%。)|b3的个数=1498506(149%。)|c3的个数=8000846(800%。)|
a4的个数=498906(49%。)|b4的个数=1499513(149%。)|c4的个数=8001581(800%。)|
a5的个数=499420(49%。)|b5的个数=1501569(150%。)|c5的个数=7999011(799%。)|
a6的个数=499057(49%。)|b6的个数=1499303(149%。)|c6的个数=8001640(800%。)|
a7的个数=499637(49%。)|b7的个数=1500461(150%。)|c7的个数=7999902(799%。)|
a8的个数=499751(49%。)|b8的个数=1497757(149%。)|c8的个数=8002492(800%。)|
a9的个数=499362(49%。)|b9的个数=1500223(150%。)|c9的个数=8000415(800%。)|
a10的个数=500398(50%。)|b10的个数=1501744(150%。)|c10的个数=7997858(799%。)|
a11的个数=500780(50%。)|b11的个数=1499652(149%。)|c11的个数=7999568(799%。)|
a12的个数=501419(50%。)|b12的个数=1500825(150%。)|c12的个数=7997756(799%。)|
a13的个数=499531(49%。)|b13的个数=1498670(149%。)|c13的个数=8001799(800%。)|
a14的个数=500125(50%。)|b14的个数=1499623(149%。)|c14的个数=8000252(800%。)|
a15的个数=499369(49%。)|b15的个数=1500529(150%。)|c15的个数=8000102(800%。)|
a16的个数=500528(50%。)|b16的个数=1499332(149%。)|c16的个数=8000140(800%。)|
a17的个数=500256(50%。)|b17的个数=1501182(150%。)|c17的个数=7998562(799%。)|
a18的个数=500026(50%。)|b18的个数=1500794(150%。)|c18的个数=7999180(799%。)|
a19的个数=500726(50%。)|b19的个数=1501076(150%。)|c19的个数=7998198(799%。)|
a20的个数=499632(49%。)|b20的个数=1503021(150%。)|c20的个数=7997347(799%。)|
s=10000000
0
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
求一个抽奖算法......
50%不中奖rn25%优惠卷(优惠有好几种这个可以直接随机的)rn25%红包rnrn其中红包在25%的的比例,不是整个比例rn1、90到100的红包6万分之一rn2、80到89.99的红包5万分之一rn3、50到79.99的红包4万分之一rn4、30到49.99的红包3万分之一rn5、20到29.99的红包2万分之一rn6、10到19.99的红包1万分之一rn7、5到9.99的红包五千分之一rn8、3到4.99的红包两千分之一rn9、2到2.99到红包五百分之一rn10、1到1.99的红包一百分之一rn11、其余都是0.99以下rn[img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/monkey/26.gif][/img]rnrn求大神.....
求一个福彩抽奖的算法
求一个福彩抽奖的算法
一个随机抽奖
公司要抽百分之X的人,可以去免费旅游rnrn人:关一、谢二、张三、李四、陈五、吴六、何七、周八、梁九、蔡十rnrn概率:70%rnrn随机。。
抽奖程序 随机抽奖
纯js抽奖程序_非常实用 抽奖程序 随机抽奖 抽奖示例 纯js抽奖代码 抽奖代码 抽奖软件
求JS随机抽奖代码
不要太复杂的,抽过的不能再抽了,名字要滚动显示的,按钮2个,一个开始一个结束,点击结束后名字会慢慢停下的那种,谢谢!
求一个随机分配的算法。
学校有10个专业,专业分别是rn01,02.....10rn现在学校的学生需要去实习了,提供了15个实习点,实习点代码分别为rns01,s02,s03........s15rn并且为每个实习点指定了每个专业对应的实习人数,比如rns01 指定实习专业人数rn01 5人rn02 0人rn03 30人rn04 5人rn....................rnrn哪位高人能帮忙解决一下,当我把每个实习点的对应专业的人数设置好之后,把对应专业的学生随机分配到对应的实习点rn这个算法我应该怎么来写,对算发接触太少,很急,求大家帮忙。为谢:)rn
随机抽奖
随机抽奖
求一个算法:随机命中
要求是rn1.必须是随机命中rn2.可以控制在某个时间段内命中多少次(不管你调用多少次)rn 比如说,我设定8点-12点命中20次,那么不管你在这段时间调用1000次还是10000次,都是确保你rn 命中数=20左右rnrn谢谢
求 抽奖算法
6个箱子 rn鼠标点击相应箱子 即可获得随机奖励rnrn规则如下:rn5金币每日中奖人数为200人rn10金币每日中奖人数为100人rn30金币每日中奖人数为50人rn50金币每日中奖人数为10人rn100金币每日中奖人数为5人rnrn大家给点意见 (有相应的代码最好了)~_~rn
求翻牌抽奖算法
求翻牌抽奖算法rn比如有20张牌,点击一张得知是否中奖。。rnrn就好比淘宝上、拍拍上的抽奖。请问有什么好 的方法实现啊
请教一个随机抽奖问题
刚开始接触VF不久,得到上头命令,必须做出一个随机抽奖(抽选老师)的东东..rn人数大概在300人左右,比方说,我想通过COMBO控件来选择一个教师信息表中的所有教语文的老师,然后从中进行抽选.但是,我所用的COMBO控件总是不起作用,请问哪位高手做过类似的吗?教在下两招,急啊..
一个简单的随机抽奖程序
一个简单的随机抽奖程序,实现了随机抽取一等奖,二等奖,三等奖的功能
MFC抽奖小游戏 随机抽奖
用MFC编写的抽奖小游戏 用到MFC对话框控件的控制以及随机函数rand()
一个简单的抽奖算法
通过随机数的区间分布实现一个抽奖算法。接受一个包含奖品中奖概率的list,返回中奖的奖品。 先定义一个抽象奖品类。 public abstract class AbstractPrize { /** * 奖品概率 */ private double probability; public double getProbability() {
随机获取礼物活动总结(抽奖算法)
/** * 奖励金(礼物)模型 * Created by tong.hua on 2017-10-26. */ public class BountyItem extends ToString{ private static final long serialVersionUID = -4046365922597449030L; //礼物编号 private int
一个抽奖系统的算法
1-33中随机抽取6个,让其6个数字不重复,用js输出
求php抽奖概率的算法
我有个抽奖的轮盘rnrn想 根据自己设置的概率 rnrn输出 0 1 2 3 4 5 6 7rnrn这8个奖项 请问 要怎么写这个概率rnrnrn比如 7 就高概率的 抽到
求一个抽奖系统!
我要这几天做一个抽奖系统。功能有:1、设置各个奖项的人数、2、可以设置几个必中的号码、3、设置抽奖的号码范围、4、一次能抽出多个号码!我用的是winfrom..rn新手一个,请求帮助!rn
js随机抽奖程序
js实现随机抽奖程序,可以自动随机抽取想要的结果。 随机抽奖程序,可以控制随机抽奖结果
随机抽奖生成代码
我根据单位具体要求自己编写的抽奖器:指在人数内不能出现带4的号码,分多轮,每轮有多位中奖号码,已中奖的不再显示。 文档中有界面样张,详细全面的代码及相关标注,便于理解学习。
抽奖随机软件
任意设置, 形式多样, 方便快捷,功能强大的抽奖软件!!完全免费
随机抽奖系统
一个简单的抽奖系统(随机数生成软件),可以生成long类型的随机数(默认是10位数的随机数,可以自定义随机数的位数长度)
随机抽奖软件
随机抽奖软件
Excel2007随机抽奖程序
EXCEL2007随机抽奖程序,可自定义编辑,使用方便
随机红包抽奖
一个随机抽红包的小程序,没积分了,看看能不能弄点积分
js随机抽奖
开发工具与关键技术:Visual Studio javascript 作者:华境聪 撰写时间:2019/1/19 这是非常简单做的一个小demo,设置time为Null,利用定时器不断查询数据库数据,停止清除定时器time让它为null,获取控制器传过来data的长度的UserName值,显示到页面上去。这里也调用了键盘事件,设置incident的值为0,按键盘时触发回车键请求开始方法,再让inc...
随机选号抽奖
随机抽奖选号中奖,本程序是为XX公司做了一个市场大检查为了公平公正的抽取市场分组进行的一个PP
计算机随机抽奖程序
在电视中我们常看到计算机随机抽奖活动,主持人在电脑键盘上按下一个键,屏幕中出现一串滚动的随机数字,在按下一个键屏幕中就出现了一组激动人心的幸运数字。接下来就产生一个新的幸运星……。 本程序通过随机产生幸运数字,实现计算机随机抽奖。
随机抽奖代码实现(4)
<span style="color:#333333;">本套课程主要讲解定时器的本身的相关原理及方法,以及使用定时器制作一些交互效果,如随机抽奖、自动书写代码、匀速运动等</span>
随机抽奖系统源码
抽奖系统源码,取不重复随机数,手机号码抽奖!
随机抽奖程序
本程序 为我一朋友定制,简单了点,希望高手别见笑<br><br>功能实现:<br><br> 1、设置抽奖人数、设置对应显示照片<br> 2、不重复出现已抽中号码<br> 3、只设置三等奖 3位、二等奖2位、一等奖1位<br> 4、按enter键切换<br><br>
DELPHI 随机抽奖软件
随机抽奖软件,支持随机抽奖,免数据库 随机抽奖软件,支持随机抽奖,免数据库
随机抽奖和倒计时
随机抽奖和倒计时,PPT制造的档案,供参考玩乐
Authorware随机抽奖作品
运用了判断图标,群组图标以及随机函数制作的随机抽奖作品,此作品易于掌握,很不错哦
简单的抽奖随机策略
public Integer getPrizeResult() { // 10W内的随机数 try { while (true) { int index = new Random().nextInt(100001); log.info("【随机数】"+index);
随机抽奖代码片段--Java
public String turntable(int customerId){ //查询用户积分 CustomerScore userscore = customerScoreDao.findByCustomerId(customerId); //积分不足 if(null==userscore) return ActivityResponse.backFail(Activi
jQuery实现随机抽奖
目录结构index.html 抽奖 随机抽奖 开始 choujiang.less body{ text-align: center; } #title{ text-align: center; font-size: 40px; font-weight: 400; font-family: 微软雅黑; margin-bottom: 20p
jquery图片随机抽奖
jquery图片随机抽奖
JS+JQ随机抽奖代码
JS+JQ随机抽奖代码: 可以实现随机抽奖功能
jquery随机抽奖.zip
jquery随机抽奖是一款基于jquery css3实现的随机抽奖程序特效代码。 jquery随机抽奖演示图:                                                        点击查看演示: