简体   繁体   English

如何定期分发 integer 个数组元素 [参见图片示例]

[英]How can I distribute integer array elements periodically [See image for example]

It's a slot machine game.这是一款老虎机游戏。 We already know the number of different outputs.我们已经知道不同输出的数量。 But it needs to work on any kind of variations of that table, obviously.但显然,它需要处理该表的任何类型的变体。

So far, I have tried several naive approaches:到目前为止,我已经尝试了几种天真的方法:

  • Dumping all results in an array and try to distribute them by moving along the array.将所有结果转储到一个数组中,并尝试通过沿数组移动来分布它们。
  • Tried to insert elements one by one, finding an empty and 'periodic' slot for each element.尝试一个接一个地插入元素,为每个元素找到一个空的“周期性”插槽。

Output Table Image Output 表格图片

Examples Image示例图像

I use indexes of rows data to create and distribute array elements periodically.我使用行数据索引来定期创建和分发数组元素。 (eg: first row corresponds to value 0, second row corresponds to value 1 and so on..) (例如:第一行对应值 0,第二行对应值 1,依此类推。)

So my output array will consist elements from 0 to 10 and the size will be 100 for provided table.所以我的 output 数组将包含从 0 到 10 的元素,对于提供的表,大小为 100。

EDIT: I have deleted the old code because I come up with an actual solution.编辑:我删除了旧代码,因为我想出了一个实际的解决方案。 Unfortunately I'm not sure if it is the correct/optimum way and has no idea how to check it.不幸的是,我不确定这是否是正确/最佳的方式,也不知道如何检查它。

Here is my code:https://goonl.netools.com/snapshot/code/#ng5xi35uewbrgc40avciud这是我的代码:https://goonl.netools.com/snapshot/code/#ng5xi35uewbrgc40avciud

Here are the sample result这是示例结果

Can someone maybe check my code and verify that I have the correct result?有人可以检查我的代码并验证我的结果是否正确吗?

So, you want a pool where each possibility happens a fixed amount of times, before refilling the pool.因此,您需要一个池,其中每种可能性都发生固定次数,然后再重新填充池。 What you can do is make an array of integers, each index corresponding to the result, and each value being the probability.你可以做的是制作一个整数数组,每个索引对应于结果,每个值都是概率。 Then, you create an integer that stores the sum of all probabilities.然后,您创建一个 integer 来存储所有概率的总和。 When you want an item, create a number between 1 and the sum of probabilities (inclusive).当你想要一个项目时,创建一个介于 1 和概率总和(含)之间的数字。 Go down the array, subtracting the probability from the random number. Go数组向下,随机数减去概率。 When it is <= 0, that is your random choice.当它 <= 0 时,这是您的随机选择。 To remove from the pool, subtract 1 from the chance of what you landed on, and 1 from the sum.要从池中移除,请从您着陆的机会中减去 1,然后从总和中减去 1。 When the sum is zero, that means the pool is empty and can be refilled.当总和为零时,这意味着池是空的并且可以重新填充。 Here is an example in c#:这是 c# 中的示例:

class RandomPool {
    private int[] chances;
    public int Total {get; private set;} // total pooled items
    public readonly int Length;
    public int this[int i] {
        get => chances[i]; // get the chance at an index
        set {
            Total += value - chances[i]; // updates the total
            chances[i] = i; // sets the chance at an index
        }
    }
    public RandomPool(int length) {
        chances = new int[length];
        Length = length;
    }
    public int Get() {
        // creates a random number 1-total
        int rand = Random.Range(1, total + 1);
        int i = 0;
        // loops through the chances 
        while (true) {
            // decreases the random value by the change
            rand -= chances[i];
            // if it is <= 0
            if (rand <= 0)
                return i; // return the index of the chosen item
            i++;
        }
    }

Then you can use it like this:然后你可以像这样使用它:

var pool = new RandomPool(3); // create the pool
pool[0] = 5; // assign the chances
pool[1] = 2;
pool[3] = 3;
while (pool.Total > 0) { // while there is something in the pool
    int x = pool.Get(); // get an item
    Console.WriteLine($"Randomly chose index: {p}"); // log the result
    pool[x]--; // remove one from the pool
}

When pool.Total == 0 you can refill the pool.pool.Total == 0时,您可以重新填充池。 Also, I haven't tested this code, so there might be a few errors.另外,我还没有测试过这段代码,所以可能会有一些错误。

Here is a way to get this.这是获得此信息的一种方法。 I will start with the inspiration, and then add how to do it efficiently.我将从灵感开始,然后添加如何高效地完成它。

Imagine you have a series of alarm clocks in front of you.想象一下,您面前有一系列闹钟。 5 of them go off 13x per day.其中 5 个 go 每天优惠 13 次。 The rest go off 9, 8, 7, 6, and 5 times per day. rest go 每天关机9次、8次、7次、6次、5次。 (I chose this example to match your output table image.) Each starts a random point between when it last went off and when it next goes off. (我选择这个例子来匹配你的 output 表图像。)每个开始一个随机点,在它上次关闭和下一次关闭之间。

The answer you want is the order in which they go off.你想要的答案是他们 go 关闭的顺序。 This order is periodic - it repeats every day.这个顺序是周期性的——它每天都重复。 They also go off in exactly the right proportions every day.他们还每天以完全正确的比例关闭 go。 But the random start makes them go off randomly.但是随机启动使它们 go 随机关闭。

Now how do we figure this out efficiently?现在我们如何有效地解决这个问题? The idea is to use a PriorityQueue to track when each alarm clock goes off.这个想法是使用PriorityQueue来跟踪每个闹钟何时响起。 So we'll want something like aRecord (double priority, String result, double weight) to put into our queue.所以我们需要像Record (double priority, String result, double weight)这样的东西放入我们的队列中。 Our result field will be your string description, the weight will be your 13 or whatever, and usingRandom you'll start priority at rand.nextDouble() / weight .我们的result字段将是您的字符串描述, weight将是您的 13 或其他任何内容,并且使用Random您将从rand.nextDouble() / weight开始priority The priority queue will compare based on priority .优先级队列会根据priority进行比较。

And now the heart of the loop where you you populate your array will be:现在,填充数组的循环的核心是:

QueueItem qi = queue.poll();
answer.add(qi.result);
queue.offer(QueueItem(qi.priority + 1/qi.weight, qi.result, qi.weight);

This makes each array item take time O(log(queue.size())) to produce.这使得每个数组项都需要时间O(log(queue.size()))来生成。 And you see that every qi.weight times qi.result comes up, the priority increases by 1. (So it is periodic.)你看到每次qi.weight乘以qi.result出现, priority增加 1。(所以它是周期性的。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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