简体   繁体   English

如何建立一个链表,使每个节点都有一个随机的int值,但是总值之和和节点数将预先确定?

[英]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?

I've started building something like this: 我已经开始构建这样的东西:

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]);
}

It is totally not the right algorithm, but this is the general idea i'm heading for 这绝对不是正确的算法,但这是我要追求的基本思想

For a uniform random answer (assuming the implicit non-negativity constraint): generate nodeCount - 1 pairwise distinct integers between 0 inclusive and sum + nodeCount - 1 exclusive. 对于统一的随机答案(假设隐式非负约束):生成nodeCount - 1成对的,在00之间的和且sum + nodeCount - 1互斥的整数。 Sort these, prepend -1 , and append sum + nodeCount - 1 . 对它们进行排序,在-1添加,然后追加sum + nodeCount - 1 Return the difference sequence minus one. 返回差异序列减一。

Example: nodeCount = 4 and sum = 10 . 示例: nodeCount = 4并且sum = 10 Generate integers. 生成整数。

5 2 12

Sort, prepend, append. 排序,添加,追加。

-1 2 5 12 13

Difference sequence. 差异序列。

3 3 7 1

Minus one. 减一

2 2 6 0

Implementation notes: you need to special case nodeCount == 0 if that's a possibility. 实施注意事项:如果可能,您需要特殊情况下的nodeCount == 0 To generate integers with no duplicates: if sum is small compared to nodeCount , then use a partial Fisher--Yates shuffle. 要生成没有重复的整数:如果sumnodeCount相比nodeCount ,则使用部分Fisher-Yates随机播放。 Otherwise, sample nodeCount - 1 integers with replacement and repeat until there are no duplicates. 否则,请采样nodeCount - 1带替换的整数,然后重复进行直到没有重复。

If you want the sum to be a particular total, you can have a remaining total and make the last element that value. 如果您希望总和是特定的总计,则可以有一个剩余的总计,并使最后一个元素成为该值。 e..g 例如

Make the nodes have random values X1, X2, ... Xn-1, total - SumOf(X1, ... Xn-1) This will ensure the total is always total 使节点具有随机值X1,X2,... Xn-1,总数-SumOf(X1,... Xn-1)这将确保总数始终为total

如果您要生成n个值,它们的总和为S,则可以生成0到1之间的n个随机双精度数,然后将它们相除,使其总数为1。然后将值乘以S。如果数字必须为整数,可能需要一些其他工作才能正确处理舍入。

You can do something like this: 您可以执行以下操作:

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;
}

You can replace temp = rand.nextDouble() with temp = rand.nextDouble / scalingFactor (where eg scalingFactor = 10) to increase the uniformity and reduce the probability that any nodes will end up equaling 0. 您可以将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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM