【发布时间】:2021-08-26 04:41:13
【问题描述】:
我有一个不连续的数字 N 列表(例如{ 1, 2, 3, 6, 8, 10}),我需要在 N 中逐步创建随机数字对并将它们存储在一个列表中,其中不能有两次相同的对。
例如,对于 3 个不同数字的列表,有 6 个可能的对(不包括相同的数字对):
以{ 4, 8, 9 } 列表为例,可能的对是:
(4,8) (4,9) (8,4) (8,9) (9,4) (9,8)
例如,当我们到达 30 的数字列表大小时,我们会得到 870 个可能的配对,而使用我当前的方法,我的效率会越来越低,可能配对越多。
例如,现在我使用 30 大小的数字列表的策略是:
N = { 3, 8, 10, 15, 16, ... } // size = 30
// Lets say I have already a list with 200 different pairs
my_pairs = { (8,16), (23, 32), (16,10), ... }
// Get two random numbers in the list
rn1 = random(N)
rn2 = random(N)
Loop through my_pairs to see if the pair (rn1,rn2) has already been generated
If there is one, we pick two new numbers rn1 & rn2 at random and retry adding them to my_pairs
If not then we add it to the list
问题是我们在 my_pairs 中的配对越多,配对不在该列表中的可能性就越小。所以我们必须多次检查多个随机对,每次都遍历列表。
我可以尝试在开始时生成所有可能的对,每次我需要将随机对添加到列表中时,将列表打乱并弹出一个元素。 但是当我的数字列表大小增加时(例如 100 个不同数字的 9900 个可能对),存储所有可能的对将占用大量空间。 而且我在处理过程中在 N 中添加了数字,所以我不能每次都重新计算所有可能的对。
是否有生成随机唯一对的算法?
也许使用矩阵或将我的配对存储在某种树形图中会更快?
【问题讨论】:
-
将生成的对存储在哈希表中,而不是线性列表中。
-
@AloisChristen 实际上我纠正了自己,我没有从 N 中删除数字,只是添加。没有最小值和最大值,它们必须> 0。我使用了所有可能配对的 ~10% 到 ~70% 之间,它变化很大。通常我从一个小的 N 开始,然后逐渐添加数字。 N 的大小有时可以达到 10k 以上。我提到了数学和图形标签,因为我可能正在考虑使用矩阵或树图数据结构。
-
@subski:哈希表的重点是“检查整个哈希表”的时间实际上并没有随着哈希表变大而增加。 (无论如何,平均而言)此外,如果您用尽了 2/3 的可能性,则平均需要 3 次尝试才能找到未使用的元素。根据您的评论,这大概是最坏的情况。在整个问题中,预计拒绝策略的速度比不检查 fir 重复的速度要慢两倍。
-
全代对和哈希表似乎都很好。根据您需要优化的程度,您甚至可以选择混合解决方案(从哈希表开始,切换到固定 % 以外的所有对)如果您生成所有对,this structure 可能会有所帮助
-
准确地说,如果你使用所有可能的对,当添加一个新元素时,你只需要使用添加的元素生成可能的对。由于您永远不会删除元素,因此现有的对在被选中之前一直有效。
标签: algorithm math graph combinations