我有一个类似的列表:
L = [[1,2,3],[4,5,6,7,8],[9,10,11]]
我想随机选择元素,例如:
L1=[[1,2,3],[9,10,11]]
L2=[[1,2,3]]
L3=[[4,5,6,7,8],[9,10,11]]
L4=[[1,2,3]]
我怎么能在erlang中做到这一点?
编辑:我还想保证所有元素至少会被选中一次。
听起来您要做的是获取一个列表[A, B, C, D, E]
并选择随机选择的元素,因此有时您会得到,有时会得到,有时[A, C, E]
会得到[B, C]
,[E]
等等。元素本身就是列表的事实并没有在您给出的示例中似乎很重要。
基本上,这个想法是以某个概率 P 单独选择每个元素,这相当于为每个元素分配一个随机数,然后检查它是否小于 P。最有可能的是,对于您的情况,P = 0.5 - 每个元素都有一个50/50 的机会被选中。
所以,我认为这将解决你的问题。
random_subset(List) -> random_subset(List, 0.5).
random_subset(List, P) ->
% Need to seed the random number generator
{S1,S2,S3} = now(),
random:seed(S1, S2, S3),
% Assign a random value for each element in the list.
Selections = [{E, random:uniform()} || E <- List],
% Only keep elements where the random value is in the selected range
[E || {E, RandomValue} <- Selections, RandomValue < P].
有更紧凑的方法来写这个,但我做了很长的路来解释正在发生的每一步。一个更简单的方法是使用lists:filter/2:
random_subset(List, P) ->
% Note: assuming the random number generator has already been seeded
lists:filter(fun(_) -> random:uniform() < P end, List).
您可以使用random模块生成一个新的随机长度列表,其中包含从 L 中随机选择的项目,必要时消除重复项。