我正在制作一个音乐生成程序,并且需要一组从0.125,0.25和0.5中选择的x个随机数,它们加起来为1.我想不出这样做的一种巧妙的方法,它也保留了随机元素
谢谢!
答案 0 :(得分:5)
只列举所有可能的总和为1的组合(它不是那么多),并将它们存储在一个数组中。然后只计算该数组的随机索引号以获得随机组合。
答案 1 :(得分:3)
有9个组合加起来1.如果你根本不关心订单,那么你可以选择1和1之间的随机数。 9。
如果您关心订单,那么您需要排列。集合{.5,.25,。25}有3个!排列:
但是,您可能只希望计算唯一的排列。
对于每个集合,您可以使用这样的算法来生成唯一的排列。 http://www.kerrywong.com/2006/04/14/generating-unique-permutations-programmatically/
一旦你知道所有的排列(或唯一的排列),你就可以使用随机数来选择其中一个排列。
答案 2 :(得分:1)
如果您关心稍后扩展这些值,您可能需要考虑采用更加动态的方法。避免硬编码值和逻辑。以下解决方案可能会有所帮助。在下面的示例中,最大值1是可配置的,可以用来累加最大值的值集也是可配置的。加载列表(从文件或输入),然后程序可以运行。这假设您的列表在运行之前从最低值到最高值排序。
public class MusicGeneration{
private List<Double> values = new ArrayList<Double>();
Random rand = new Random();
private double max_value = 0;
public MusicGeneration() {
max_value = 10;
values.add(0.125);
values.add(0.25);
values.add(0.5);
values.add(0.75);
}
private void createMusic() {
double total = 0;
while (total < max_value) {
int i = rand.nextInt(maxChoice(total));
System.out.println("Picked :: " + values.get(i));
total += values.get(i);
System.out.println("Total :: " + total);
}
}
private int maxChoice(double total) {
int size = values.size() - 1;
while (size > 0) {
if ((max_value - total) >= values.get(size)) {
System.out.println("Returning " + (size + 1));
return (size + 1);
}
size--;
}
return 1;
}
public static void main(String args[]) {
MusicGeneration play = new MusicGeneration();
play.createMusic();
}
}
答案 3 :(得分:0)
创建一个存储这三个双打的数组:.125,.25,.5。然后生成一个数字1-3,用它索引数组,并将结果+你的总数到目前为止进行比较1.如果更少,添加它们并继续。如果相等,请停止程序。如果更大,则生成另一个随机索引。
答案 4 :(得分:0)
迭代解决方案,如果可能性的数量太大,可以很容易地推广。
只需检查每个步骤中哪些数字合法,然后根据它生成下一个数字。
java代码:
static Random random = new Random();
public static double getRandom(double[] l) {
int i = random.nextInt(l.length);
return l[i];
}
public static List<Double> getRandNums() {
List<Double> l = new LinkedList<Double>();
double x = 1;
double[] arr1 = { 0.125, 0.25, 0.5 };
double[] arr2 = { 0.125, 0.25 };
double[] arr3 = { 0.125 };
double r;
while (x > 0) {
if (x >= 0.5) {
r = getRandom(arr1);
} else if (x >= 0.25) {
r = getRandom(arr2);
} else {
r = getRandom(arr3);
}
l.add(r);
x -= r;
}
return l;
}