java优先级问题

时间:2021-12-29 05:27:21
已知有 1,3,5,7,9,11,13,15,17,19...这些整数
需要随机拿出里面的一个整数 但是有优先级 比如9的优先级高 出现的概率为80%
也就是说 我要随机拿一个整数 优先级高的肯定出现的概率比较高 
请问如何控制优先级 或者说是有什么方法 设置这些优先级 谢谢了

14 个解决方案

#1


原来楼主是这个意思。相当于一个摇奖程序啊。。。

#2


那么楼主用空间换时间吧,
比如 优先级高的多放几个数字,然后打乱,这样算比例好点吧。在用随机函数取出来。你看呢?
只要把比例搞对就好了。

#3


那楼主的意思到底是要控制概率大的出现高还是优先级的出现高??

#4


引用 2 楼  的回复:
那么楼主用空间换时间吧,
比如 优先级高的多放几个数字,然后打乱,这样算比例好点吧。在用随机函数取出来。你看呢?
只要把比例搞对就好了。

确实是个办法。我只学了些基础。也想不到什么好办法。。

#5


该回复于2012-04-09 09:46:24被版主删除

#6


这样的话,9,9,9,9,[1,3,5,7,11,13,15,17,19]

#7


不懂说什么呢,真应该好好了

#8


其实不复杂,假定 A B C D 三个签
权重分别为: A:3  B:4  C:5  D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A  7:B  12:C  13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

#9


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3 B:4 C:5 D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A 7:B 12:C 13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

但是这个区域是否也应该随机分配比较好?

#10


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3  B:4  C:5  D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A  7:B  12:C  13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

那出现的概率是控制数字还是字母?

#11


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3  B:4  C:5  D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A  7:B  12:C  13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

那出现的概率是控制数字还是字母?

#12


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3  B:4  C:5  D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A  7:B  12:C  13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

+1

#13


引用 9 楼  的回复:
但是这个区域是否也应该随机分配比较好?

从概率学来考虑,不需要。


引用 10 楼  的回复:
那出现的概率是控制数字还是字母?

在我举的例子,为了区分权重和选择项,所以把选择项用了字母标识;实际使用的时候,你选择项是数字也没啥关系,自己别搞混就行了。

#14


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3 B:4 C:5 D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A 7:B 12:C 13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

基本就是这个思路了
比如
1出现的概率是1次,3出现的概率是10次,5出现的概率次是15次,7出现的概率是25次,9出现的概率是80次,11出现的概率为100次等等,即区间[1,1]出现1,区间[2,11]出现3,区间[12,26]出现5,区间[27,51]出现7,区间[52,131]出现9,区间[132,231]出现11,等等,按8L的思路可以用1个集合,分别在每个区间填充不同的对应的数字,然后在区间内取随机数,区间落在哪里就取对应的数,不过这样如果区间过大,填充的数就越多,比较占用内存空间,所以可以采用TreeMap

int[] a = {1,3,5,6,9,11}; //出现的数字
int[] pa = {1,3,10,15,25,80,100}; //每个数字出现的次数
Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
int range = 0;
for (int i=0; i<a.length; i++) {
    map.put(range, a[i]); //把区间和对应的数字保存到map
    range += pa[i];
    //相当于[0,1)区间保存1,[1,4)区间保存3,[4,14)区间保存5,等等
    //即map(0)保存1,map(1)保存3,map(4)保存5,等等
}

int r = (int)Math.random()*range + 1; //在区间内随机抽选,即取[1,range]的一个随机数
Map.Entry<Integer, Integer> e = map.lowerEntry(r); //从map中取小于随机数的最大区间
if (e == null) {
    System.out.println("不存在这样概率的数字"); //对于给定的区间随机数,这种情况不会发生
} else {
    System.out.printf("抽选的数字为:%d\n", e.getValue());
}

 

#1


原来楼主是这个意思。相当于一个摇奖程序啊。。。

#2


那么楼主用空间换时间吧,
比如 优先级高的多放几个数字,然后打乱,这样算比例好点吧。在用随机函数取出来。你看呢?
只要把比例搞对就好了。

#3


那楼主的意思到底是要控制概率大的出现高还是优先级的出现高??

#4


引用 2 楼  的回复:
那么楼主用空间换时间吧,
比如 优先级高的多放几个数字,然后打乱,这样算比例好点吧。在用随机函数取出来。你看呢?
只要把比例搞对就好了。

确实是个办法。我只学了些基础。也想不到什么好办法。。

#5


该回复于2012-04-09 09:46:24被版主删除

#6


这样的话,9,9,9,9,[1,3,5,7,11,13,15,17,19]

#7


不懂说什么呢,真应该好好了

#8


其实不复杂,假定 A B C D 三个签
权重分别为: A:3  B:4  C:5  D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A  7:B  12:C  13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

#9


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3 B:4 C:5 D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A 7:B 12:C 13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

但是这个区域是否也应该随机分配比较好?

#10


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3  B:4  C:5  D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A  7:B  12:C  13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

那出现的概率是控制数字还是字母?

#11


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3  B:4  C:5  D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A  7:B  12:C  13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

那出现的概率是控制数字还是字母?

#12


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3  B:4  C:5  D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A  7:B  12:C  13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

+1

#13


引用 9 楼  的回复:
但是这个区域是否也应该随机分配比较好?

从概率学来考虑,不需要。


引用 10 楼  的回复:
那出现的概率是控制数字还是字母?

在我举的例子,为了区分权重和选择项,所以把选择项用了字母标识;实际使用的时候,你选择项是数字也没啥关系,自己别搞混就行了。

#14


引用 8 楼  的回复:
其实不复杂,假定 A B C D 三个签
权重分别为: A:3 B:4 C:5 D:1

那么建立一个列表,将各权重进行累进计算,得到:
3:A 7:B 12:C 13:C

然后在1~13中取随机数:rand。

然后从头到尾看看rand落在哪个区间就知道应该选谁了。

比如:rand=11,就是C;rand=4,就是B;绝对符合概率要求。

基本就是这个思路了
比如
1出现的概率是1次,3出现的概率是10次,5出现的概率次是15次,7出现的概率是25次,9出现的概率是80次,11出现的概率为100次等等,即区间[1,1]出现1,区间[2,11]出现3,区间[12,26]出现5,区间[27,51]出现7,区间[52,131]出现9,区间[132,231]出现11,等等,按8L的思路可以用1个集合,分别在每个区间填充不同的对应的数字,然后在区间内取随机数,区间落在哪里就取对应的数,不过这样如果区间过大,填充的数就越多,比较占用内存空间,所以可以采用TreeMap

int[] a = {1,3,5,6,9,11}; //出现的数字
int[] pa = {1,3,10,15,25,80,100}; //每个数字出现的次数
Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
int range = 0;
for (int i=0; i<a.length; i++) {
    map.put(range, a[i]); //把区间和对应的数字保存到map
    range += pa[i];
    //相当于[0,1)区间保存1,[1,4)区间保存3,[4,14)区间保存5,等等
    //即map(0)保存1,map(1)保存3,map(4)保存5,等等
}

int r = (int)Math.random()*range + 1; //在区间内随机抽选,即取[1,range]的一个随机数
Map.Entry<Integer, Integer> e = map.lowerEntry(r); //从map中取小于随机数的最大区间
if (e == null) {
    System.out.println("不存在这样概率的数字"); //对于给定的区间随机数,这种情况不会发生
} else {
    System.out.printf("抽选的数字为:%d\n", e.getValue());
}