[英]How to build a linked list, that every node will have a random int value, but the total values sum and the number of nodes will be fixed in advance?
我已经开始构建这样的东西:
class Node{
Node next,prev;
int val;
Node(int val, Node prev, Node next){
this.val = val;
this.prev = prev;
this.next = next;
}
}
....
public void buildRandomPath(int size, int total){
road = new Node[size];
int tmp = (int)(Math.random()*(double)(total/size));
total = total-tmp;
road[0] = new Node(tmp,road[size-1],road[1]);
for (int i = 1; i < size-1; i++){
tmp = (int)(Math.random()*(double)(total/size-i));
total = total-tmp;
road[i] = new Node(tmp1,road[i-1],road[i+1]);
}
tmp = (int)(Math.random()*(double)(total));
total = total-tmp;
road[size-1] = new Node(tmp,road[size-2],road[0]);
}
这绝对不是正确的算法,但这是我要追求的基本思想
对于统一的随机答案(假设隐式非负约束):生成nodeCount - 1
成对的,在0
和0
之间的和且sum + nodeCount - 1
互斥的整数。 对它们进行排序,在-1
添加,然后追加sum + nodeCount - 1
。 返回差异序列减一。
示例: nodeCount = 4
并且sum = 10
。 生成整数。
5 2 12
排序,添加,追加。
-1 2 5 12 13
差异序列。
3 3 7 1
减一
2 2 6 0
实施注意事项:如果可能,您需要特殊情况下的nodeCount == 0
。 要生成没有重复的整数:如果sum
与nodeCount
相比nodeCount
,则使用部分Fisher-Yates随机播放。 否则,请采样nodeCount - 1
带替换的整数,然后重复进行直到没有重复。
如果您希望总和是特定的总计,则可以有一个剩余的总计,并使最后一个元素成为该值。 例如
使节点具有随机值X1,X2,... Xn-1,总数-SumOf(X1,... Xn-1)这将确保总数始终为total
如果您要生成n个值,它们的总和为S,则可以生成0到1之间的n个随机双精度数,然后将它们相除,使其总数为1。然后将值乘以S。如果数字必须为整数,可能需要一些其他工作才能正确处理舍入。
您可以执行以下操作:
double runningTotal = total;
Random rand = new Random();
road = new double[size];
while(runningTotal > 0) {
double temp = rand.nextDouble(); // return [0, 1)
if(temp > runningTotal) {
temp = runningTotal;
runningTotal = 0.0;
} else {
runningTotal -= temp;
}
road[rand.nextInt(size)] += temp;
}
您可以将temp = rand.nextDouble()
替换为temp = rand.nextDouble / scalingFactor
(例如,scaleFactor = 10),以提高均匀性并降低任何节点最终等于0的可能性。
public Node[] buildRandomPath(int size, int total){
Node[] road = new Node[size];
int tmp = (int)(Math.random()*(double)(total/size));
if(tmp==0)
tmp=1;
total = total-tmp;
road[0] = new Node(tmp,road[size-1],road[1]);
int tmp1=0;
for (int i = 1; i < size-1; i++){
tmp1 = (int)(Math.random()*(double)(total/size-i));
if(tmp1==0)
tmp1=1;
total = total-tmp1;
if(total>0)
road[i] = new Node(tmp1,road[i-1],road[i+1]);
else
road[i] = new Node(0,road[i-1],road[i+1]);
}
road[size-1] = new Node(total,road[size-2],road[0]);
return road;
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
class Node{
Node next,prev;
int val;
}
public class temp {
public Node[] buildRandomPath(int size, int total){
Node[] road = new Node[size];
for (int i = 0; i < road.length; i++) {
road[i]=new Node();
}
int tmp = (int)(Math.random()*(double)(total/size));
if(tmp==0)
tmp=1;
total = total-tmp;
road[0].val=tmp;
road[0].next=road[1];
road[0].prev=road[size-1];
int tmp1=0;
for (int i = 1; i < size-1; i++){
tmp1 = (int)(Math.random()*(double)(total/size-i));
if(tmp1==0)
tmp1=1;
total = total-tmp1;
road[i].next=road[i+1];
road[i].prev=road[i-1];
if(total>0)
road[i].val=tmp1;
else
road[i].val=0;
}
road[size-1].val=total;
road[size-1].next=road[0];
road[size-1].prev=road[size-2];
return road;
}
public static void main(String[] args) {
temp t=new temp();
Node[] node=t.buildRandomPath(10, 500);
int i=0;
for (Node node2 : node) {
i=i+node2.val;
}
System.out.println(i);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.