You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prolog中获取指定节点三级好友列表的技术求助

搞定Prolog三级好友列表的问题

嘿,我来帮你解决这个Prolog里的好友列表问题!首先咱们得明确你要的三级好友是啥:就是和a的关系距离在1到3之间的人——直接好友(距离1)、好友的好友(距离2)、好友的好友的好友(距离3),而且你要的结果刚好排除了更远的e、f,完全符合你的期望。

先看你现有的好友事实:

friend(a,b). friend(a,b2). friend(a,b3). friend(b,c). friend(c,d). friend(d,e). friend(e,f).

方法一:自定义递归的层级好友谓词

咱们可以先写一个friend_at_level/3的谓词,专门用来找某个人的第N级好友:

% 第1级就是直接好友,直接匹配friend事实
friend_at_level(Person, Friend, 1) :-
    friend(Person, Friend).

% 第N级好友:先找到第N-1级的中间好友,再找这个中间好友的直接好友
friend_at_level(Person, Friend, N) :-
    N > 1,
    N1 is N - 1,
    friend_at_level(Person, Intermediate, N1),
    friend(Intermediate, Friend),
    Friend \= Person. % 防止出现自己加自己为好友的情况(如果有环的话)

接下来,咱们要把1到3级的所有好友捞出来,还要去重(虽然你现在的例子没重复,但万一有环呢?)。用findall/3配合between/3遍历1-3级,再用sort/2去重排序:

get_three_level_friends(Person, Friends) :-
    findall(F, (between(1,3, Level), friend_at_level(Person, F, Level)), UnsortedList),
    sort(UnsortedList, Friends).

现在测试一下:

?- get_three_level_friends(a, List).
List = [b, b2, b3, c, d].

完美命中你要的结果!

方法二:用闭包简化(适合SWI-Prolog这类支持closure/3的环境)

如果你用的是SWI-Prolog,它自带的closure/3可以直接处理关系的传递闭包,咱们只要限制传递步数在3以内就行:

get_three_level_friends(Person, Friends) :-
    findall(F, (
        closure(friend, Person, F),
        % 计算Person到F的关系距离,确保不超过3
        distance(Person, F, D),
        D =< 3
    ), UnsortedList),
    sort(UnsortedList, Friends).

% 辅助谓词:计算两个节点之间的关系距离
distance(Person, Person, 0).
distance(Person, Friend, D) :-
    friend(Person, Intermediate),
    distance(Intermediate, Friend, D1),
    D is D1 + 1.

运行这个查询,同样会得到你想要的列表。

小提醒

  • 去重很重要:sort/2不仅能给列表排序,还会自动删掉重复元素,要是你的好友关系有环(比如friend(b,a)),这一步就会避免把a自己加到列表里,也不会重复出现同一个好友。
  • 排除自身:在第一个方法里加了Friend \= Person,也是为了防止出现自己成为自己好友的奇怪情况。

这样就能轻松获取你需要的三级好友列表啦!

内容的提问来源于stack exchange,提问作者Daniel Fialho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:36:58