首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从一组常量中选取2个随机值

从一组常量中选取2个随机值
EN

Stack Overflow用户
提问于 2014-02-16 03:49:09
回答 3查看 163关注 0票数 0

在Prolog中,如何从一组52张卡片中随机选取2个值?即Player1(X,Y),X是52中的任何一张牌,Y是另一张牌,它们必须是不同的。Player2将得到同样的待遇,他的牌必须与已经选择的牌不同。谢谢。

EN

回答 3

Stack Overflow用户

发布于 2014-02-16 04:19:51

在SWI-Prolog中,我会做一个pick_card/3

代码语言:javascript
代码运行次数:0
运行
复制
pick_card(Cards, Card, Rest) :-
  length(Cards, N), random_between(1, N, R), nth1(R, Cards, Card, Rest).

并应用它2次

代码语言:javascript
代码运行次数:0
运行
复制
pick_two_cards(Cards, C1,C2, Rest) :-
  pick_card(Cards, C1, R1),
  pick_card(R1, C2, Rest).
票数 1
EN

Stack Overflow用户

发布于 2014-02-16 05:28:39

基本上,任务是从集合1..52中抽取4个不同的元素。

例如,在Python中,有一个用于此操作的标准函数,代码为

代码语言:javascript
代码运行次数:0
运行
复制
random.sample(range(1, 52 + 1), 4)

我已经看过了Python是如何实现random.sample(range(1..N + 1), K)的--它基本上就是K个生成随机数1..N的步骤,并且在每一步中,只要在当前生成的数已经在上一步中被选中的情况下继续尝试生成随机数即可。它看起来效率很低,但可能需要它来归档分布的一致性。

让我们为Prolog创建一个类似的(但简化的) sample谓词。

代码语言:javascript
代码运行次数:0
运行
复制
sample(N, K, Sample) :-
    sample(N, K, [], Sample).

sample(_, 0, _, []).
sample(N, K, Selected, [X | Rest]) :-
    K > 0,
    new_random_index(N, Selected, X),
    NewSelected = [X | Selected],
    NewK is K - 1,
    sample(N, NewK, NewSelected, Rest).

new_random_index(N, Selected, X) :-
    ( 
        % Can be implementation-specific. Works in B-Prolog and ECLiPSe CLP.
        X is (random mod N) + 1, 
        \+ membchk(X, Selected) 
    ; 
        new_random_index(N, Selected, X)
    ).

几个测试运行:

代码语言:javascript
代码运行次数:0
运行
复制
| ?- sample(52, 4, Sample).
sample(52, 4, Sample).
Sample = [40,23,38,44] ?
yes
| ?- sample(52, 4, Sample).
sample(52, 4, Sample).
Sample = [2,28,39,17] ?
yes

如果将membchk测试改为使用集合而不是列表来测试成员资格的谓词,则可以大大提高程序的效率。但这是非常特定于实现的。

票数 1
EN

Stack Overflow用户

发布于 2014-02-16 09:42:28

如果你想重复地抽出随机的牌,最好是一次洗完整个列表,然后简单地从前面挑选牌。一些Prologs (例如ECLiPSe)有一个库谓词,所以你可以直接调用

代码语言:javascript
代码运行次数:0
运行
复制
lists:shuffle(Cards, [Card1,Card2|Rest]).

如果你想自己写一个shuffling,这里有一个巧妙的技巧:

代码语言:javascript
代码运行次数:0
运行
复制
shuffle(Xs, Rs) :-
    add_random_keys(Xs, KXs),  % add random key to each list element
    keysort(KXs, KRs),         % sort by keys, perturbing original order
    strip_keys(KRs, Rs).       % remove the keys again

add_random_keys([], []).
add_random_keys([X|Xs], [K-X|KXs]) :-
    random(K),
    add_random_keys(Xs, KXs).

strip_keys([], []).
strip_keys([_K-X|KXs], [X|Xs]) :-
    strip_keys(KXs, Xs).
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21802746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档