如何在序言中制作特定长度的随机列表而没有重复? [英] How to make a random list of a specific length without duplicates in prolog?

查看:42
本文介绍了如何在序言中制作特定长度的随机列表而没有重复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个谓词 randomnames/1 来生成三个不同名称的随机列表.名称在数据库中,我已经有了一个随机名称的谓词:

姓名(1,玛丽).姓名(2,帕特).姓名(3,詹姆斯).姓名(4,鲍勃).姓名(5,苏珊).random_name(名称):-随机(0, 6, N),名称(N,名称).

为了将其列入列表,有人建议我应该这样做:

random_names([A,B,C]) :-随机名称(A),随机名称(B),随机名称(C).

唯一的问题是在生成的列表中可能会出现重复项.我不知道如何解决这个问题.我可以编写一个新的谓词来删除重复项,但是我如何用另一个变量替换重复项,以便列表仍然包含三个元素?如果 random_names 谓词中没有明确的头部和尾部,我将如何编写 remove 谓词?

解决方案

在 Prolog 中编程时,请考虑您的解决方案必须满足的条件.

目前,您已经知道如何描述一个包含三个元素的列表,其中每个元素都是一个随机名称.

这是一个好的开始,但还不够:此外,您现在想要描述元素成对不同的条件.

因此,考虑如何描述一个包含三个元素的列表,其中所有元素都是成对不同的.

我给你一个开始,使用 dif/2 以合理的方式表达术语的歧视(参见 ):

<预>Three_distinct_elements([A,B,C]) :-差异(A,B),差异(A,C),差异(B,C).

对于包含 3 个以上元素的列表,您可能会找到一种更通用、更优雅的方式来描述这一点.但是,以上足以解决手头的任务.

因此,只需组合您已有的谓词,例如:

<预>Three_distinct_random_names(Ls) :-random_names(Ls),三不同元素(Ls).

这只是您已经实施的条件的连接.总的来说,这个谓词的解决方案会给你你想要的:一个包含三个不同随机名称的列表.

然而,谓词也可能失败(练习:为什么?).

要尝试谓词直到找到解决方案,例如使用repeat/0:

<预>?- 重复,three_distinct_random_names(Ls).

还有更好的方法来解决这个问题.但是,作为第一个近似值,我建议专注于好的构建块,描述您想要满足的条件.

我对你写的东西有一个一般性的评论:

<块引用>

我可以编写一个新谓词来删除重复项,但是我如何用另一个变量替换重复项,以便列表仍然包含三个元素?>

这一切的措辞都非常势在必行:您在这里考虑删除"、替换"等.要充分利用 Prolog,请专注于描述条件必须满足您想要找到的解决方案!

您想找到一个没有重复的列表吗?描述这样一个列表应该是什么样子的.你想要随机名字吗?描述这样的名字是什么样的,等等.

I'm trying to write a predicate randomnames/1 that generates a random list of three different names. The names are in a database and I already have a predicate for one random name:

name(1, Mary).
name(2, Pat).
name(3, James).
name(4, Bob).
name(5, Susan).

random_name(Name):- 
  random(0, 6, N),    
  name(N, Name). 

To get this in a list, someone suggested I should do:

random_names([A,B,C]) :-
    random_name(A),
    random_name(B),
    random_name(C).

The only problem with this is that it's possible to get duplicates in the list generated. I can't figure out how to fix that issue. I could write a new predicate for removing duplicates, but how would I substitute the duplicate with another variable then, so that the list still has three elements? And how would I even write the remove predicate when there isn't a clear head and tail in the random_names predicate?

解决方案

When programming in Prolog, think in terms of conditions that your solutions must satisfy.

Currently, you have already figured out how to describe a list with three elements, where each element is a random name.

That's a good start, but not yet sufficient: In addition, you now want to describe the condition that the elements are pairwise distinct.

So, think about how to describe a list of three elements where all elements are pairwise distinct.

I give you a start, using dif/2 to express disequality of terms in a sound way (see ):

three_distinct_elements([A,B,C]) :-
        dif(A, B),
        dif(A, C),
        dif(B, C).

You may find a more general and more elegant way to describe this for lists with more than 3 elements. However, the above suffices to solve the task at hand.

So, it only remains to combine the predicates you already have, using for example:

three_distinct_random_names(Ls) :-
        random_names(Ls),
        three_distinct_elements(Ls).

This is simply the conjunction of conditions which you have already implemented. In total, solutions of this predicate will give you what you want: A list with three distinct random names.

However, the predicate may also fail (Exercise: Why?).

To try the predicate until it finds a solution, use for example repeat/0:

?- repeat, three_distinct_random_names(Ls).

There are also better ways to solve this. However, as a first approximation, I recommend to focus on good building-blocks, describing the conditions you want to satisfy.

I have a general comment on what you write:

I could write a new predicate for removing duplicates, but how would I substitute the duplicate with another variable then, so that the list still has three elements?

This is all worded very imperatively: You think here about "removing", "substituting" etc. To get the most out of Prolog, focus on describing the conditions that must hold for the solutions you want to find!

You want to find a list without duplicates? Describe what such a a list must look like. You want random names? Describe what such a name looks like, etc.

这篇关于如何在序言中制作特定长度的随机列表而没有重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆