概率命中算法

kakai 发布于 2014/07/16 11:33
阅读 861
收藏 6
比如有杀怪有20%、0.5%的概率掉落某物品,则可以
public static boolean isHitProbability(float rate, int total) {
        if(rate == total) {
            return true;
        }
        float m = rate % 1;
        if (m != 0) {
            String str = String.valueOf(rate);
            String v = str.split("\\.")[1];
            int len = v.length();
            double cen = Math.pow(10, len);
            rate *= cen;
            total *= cen;
        }
        int hitValue = new Random().nextInt(total) + 1;
        return hitValue <= (int) rate;
    }
isHitProbability(20,100),返回true表示概率命中成功 
isHitProbability(0.5f,100),返回true表示概率命中成功 


加载中
1
kakai
kakai
考虑不严谨,好像有问题,我先看看
0
kakai
kakai

String v = str.split(".")[1];

这句应该改成

String v = str.split("\\.")[1];

0
kakai
kakai
public static boolean isHitProbability(float rate, int total) {
        if(rate == total) {
            return true;
        }
        float m = rate % 1;
        if (m != 0) {
            String str = String.valueOf(rate);
            String v = str.split("\\.")[1];
            int len = v.length();
            double cen = Math.pow(10, len);
            rate *= cen;
            total *= cen;
        }
        int hitValue = new Random().nextInt(total) + 1;
        return hitValue <= (int) rate;
    }
0
k
kidding

效率实在是太低了,new Random()这里要创建多少对象,spilt还要生成正则表达式

纯数字运算就够了啊

kakai
kakai
再请教下,纯数字概率命中是怎么实现的?可以贴代码上来不?
kakai
kakai
用到splite是为了分割小数位,从而将浮点数据转换为整数,一般很少出现0.5%类似这样的概率吧,要是这样,可以用5%1000了,调用就可以这样isHitProbability(5,1000),这样根本不会跑到使用splite里面去。 每次new一个Random是考虑到并发了,虽然没测试过一个Random对象在高并发的情况下使用nextInt会不会有问题,但先这么处理的
0
itian277
itian277
random(1,  total) <= rate
kakai
kakai
random(1, total)这个是哪个里面的?Random类里没有吧,Math.random更加没有了
0
kakai
kakai

还有一种算法就是转换为几分之几,比如20%,即1/5,但这种方式处理能被100整除的算是最公平的概率命中算法,但像30%就只能做1/3处理,这还是有些不公平的。

public static boolean isHitProbability(int rate, int total) {
        if (total == rate) {
            return true;
        }
        if (rate < 0) {
            return false;
        }
        if (total < rate) {
            return false;
        }
        return new Random().nextInt((int) (total / rate)) == 0;
    }

0
k
kidding
//random不用考虑并发
static Random r = new Random();
	
	/**
	 * 
	 * probs 为一系列的概率值 且合为1
	 * @param probs
	 * @return 命中的内容的index
	 */
	static int cal(double[] probs){
		double s = r.nextDouble();
		double carry = 0.0;
		for(int i=0;i<probs.length;i++){
			carry+=probs[i];
			if(carry>=s) return i;
		}
		return probs.length-1;
	}




kakai
kakai
谢谢!
返回顶部
顶部