问题描述
我正在尝试输入电影列表并找到在同一部电影中演出的演员.问题:给定一个电影列表,使用递归显示一组明星的链接.这些是事实的例子:
i am trying to have an input of a list of movies and find the actors who play at the same movies.Question : Given a list of movies, display their link by a set of stars using recursion.these are an example of facts :
fact(movie,actor).
starsin(a,bob).
starsin(b,bob).
starsin(c,bob).
starsin(a,maria).
starsin(b,maria).
starsin(c,maria).
starsin(a,george).
starsin(b,george).
starsin(c,george).
输入输出示例:
?- sameActors([a,b,c],Y).
Y = bob,maria,george.
到目前为止写的规则:
sameActors(Actors,Movies) :-
findall(Stars,(member(movie,Actors),starsin(movie,Stars)),Name),
sum_list(Name,Movies).
我很新,在网上找不到任何类似的解决方案来解决我的问题,我不明白我做错了什么,或者我需要添加什么.
I am quite new and can't find any similar solution online for my problem, i don't understand what i am doing wrong , or what i need to add.
推荐答案
这里还有一个(终于找到方法了)
Here is another one (I finally found a way)
没有递归,只是findall的一个亲戚,setof/3
:
No recursion, just a relative of findall, setof/3
:
给定一个主演电影演员"的数据库:
Given a database of "actors starring in movies":
starsin(a,bob).
starsin(c,bob).
starsin(a,maria).
starsin(b,maria).
starsin(c,maria).
starsin(a,george).
starsin(b,george).
starsin(c,george).
starsin(d,george).
我们做了一些反思(在 setof/3 insidesetof/3 不起作用,但为什么?),然后:
We do some reflection (described in setof/3 inside setof/3 not working, but why?), and then:
subselect(Ax,MovIn) :-
setof(Mx,starsin(Mx,Ax),MovAx), subset(MovIn, MovAx).
actors_appearing_in_movies(MovIn,ActOut) :-
setof(Ax, subselect(Ax,MovIn) , ActOut).
这具有作为 RDBMS 操作的正确感觉!
This has the right feel of being an RDBMS operation!
测试中!
请注意,对于空电影集,我们得到所有演员.这有点正确:所有的演员出演空集的所有电影.
Note that for the empty set of movies, we get all the actors. This is marginally right: all the actorsstar in all the movies of the empty set.
测试包括运行这些目标并观察它们是否成功:
Testing consists in running these goals and observing that they succeed:
actors_appearing_in_movies([],ActOut),
permutation([bob, george, maria],ActOut),!.
actors_appearing_in_movies([a],ActOut),
permutation([bob, george, maria],ActOut),!.
actors_appearing_in_movies([a,b],ActOut),
permutation([george, maria],ActOut),!.
actors_appearing_in_movies([a,b,c],ActOut),
permutation([george, maria],ActOut),!.
actors_appearing_in_movies([a,b,c,d],ActOut),
permutation([george],ActOut),!.
奖金回合:在 R
完全不相关,但我想过如何在 R 中做到这一点.
Bonus Round: In R
Completely unrelated, but I thought about how to do that in R.
经过一番摸索:
# Load tidyverse dplyr
library(dplyr)
# Create a data frame ("tibble") with our raw data using `tribble`
t <- tribble(
~movie, ~actor
,"a" , "bob"
,"c" , "bob"
,"a" , "maria"
,"b" , "maria"
,"c" , "maria"
,"a" , "george"
,"b" , "george"
,"c" , "george"
,"d" , "george")
# The function!
actors_appearing_in_movies <- function(data, movies_must) {
# (movie,actor) pairs of actors active in movies we are interested in
t1 <- data %>% filter(is.element(movie, movies_must))
# (actor, (movies)) pairs of actors and the movies they appear in
# for movies we are interested in
t2 <- t1 %>% group_by(actor) %>% summarize(movies = list(unique(movie)))
# Retain only those which appear in all movies
t3 <- t2 %>% rowwise() %>% filter(setequal(movies_must,movies))
# Select only the actor column
# ("Select" works columnwise, not rowwise as in SQL)
t4 <- t3 %>% select(actor)
return(t4)
}
结果?
上述方法对谁在空电影集中有不同的看法:
The above approach has a different opinion on who is in the empty movie set:
> actors_appearing_in_movies(t, c())
# A tibble: 0 x 1
# … with 1 variable: actor <chr>
但是:
> actors_appearing_in_movies(t, c("a"))
# A tibble: 3 x 1
actor
<chr>
1 bob
2 george
3 maria
> actors_appearing_in_movies(t, c("a","b"))
# A tibble: 2 x 1
actor
<chr>
1 george
2 maria
> actors_appearing_in_movies(t, c("a","b","c"))
# A tibble: 2 x 1
actor
<chr>
1 george
2 maria
> actors_appearing_in_movies(t, c("a","b","c","d"))
# A tibble: 1 x 1
actor
<chr>
1 george
这篇关于在 swi-prolog 中查找不同事实中的相互元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!