Akinator可以找到所有内容。我可以猜出akinator的算法,但我不明白,akinator使用数据库或任何搜索引擎是因为找到了所有东西。如果使用数据库,数据库的逻辑是什么?创始人如何找到所有知识?
现在就足够了:)
我将在这里进行猜测,不确定什么,因为我不属于编写这个出色的机器人的人。
我想它开始时并不像现在这样聪明,但是请记住:每次得到错误答案时,它都会要求您提出另一个问题,该问题将Akinator的建议与您想到的实际人区分开。因此,它建立在自己的知识库上。
我想Akinator使用决策树,甚至C4.5 algorithm来选择每次查询的内容。它根据先前的答案提出问题,该答案更接近于C4.5算法,而不是经典的决策树。 Akinator真正令人惊奇的是,它甚至可以猜出您在一个或两个答案中犯了错误的某些情况。我想,这是机器人作者开发的算法的附加组件。
[仅计算是否包含数十万个问题,并且每个问题都有5个可能的答案,可以猜测多少个不同的性格。
我不知道Akinator的原始算法是如何实现的,但是我们已经使用数据库解决了类似的任务。您可以在https://github.com/nesterovsky-bros/KB中了解其实现。
编辑:
建议的解决方案是一种算法,该算法将带有答案的问题列表作为输入,并提供下一个问题。该问题及其答案将添加到问题和答案集中。如果没有其他问题,则由一组问题确定实体列表,并给出这些问题的答案。
本质上,SQL解决方案是这样的:
表“实体”定义对象:
create table Data.Entity
(
EntityID int not null primary key, -- Object key.
Name nvarchar(256) -- Object name
);
表“ PredicateType”定义问题类型:
create table Data.PredicateType
(
PredicateID int not null primary key, -- question id
Name nvarchar(128) not null unique -- question name.
);
表“谓词”存储谓词为真的实体:
create table Data.Predicate
(
PredicateID int not null,
EntityID int not null,
constraint PK_Predicate primary key clustered(PredicateID, EntityID),
constraint IX_Predicate_Entity unique(EntityID, PredicateID)
);
例如,如果我们有P(i)-问题,A(i)-答案,i = 1..5,并且A(1)= A(3)= 1,A(2)= A(4)= A(5)= 0,那么选择将如下所示:
with P1 as -- P(1), A(1) = 1
(
select EntityID from Data.Predicate where PredicateID = @p1
),
P2 as -- P(2), A(2) = 0
(
select EntityID from Data.Predicate where PredicateID = @p2
),
P3 as -- P(3), A(3) = 1
(
select EntityID from Data.Predicate where PredicateID = @p3
),
P4 as -- P(4), A(4) = 0
(
select EntityID from Data.Predicate where PredicateID = @p4
),
P5 as -- P(5), A(5) = 0
(
select EntityID from Data.Predicate where PredicateID = @p5
),
M as
(
select EntityID from Data.Entity
intersect
select EntityID from P1
intersect
select EntityID from P3
except
select EntityID from P2
except
select EntityID from P4
except
select EntityID from P5
),
P as
(
select
P.PredicateID,
count(*) EntityCount,
(select count(*) from M) TotalCount
from
Data.Predicate P
inner join
M
on
P.EntityID = M.EntityID
where
P.PredicateID not in (@p1, @p2, @p3, @p4, @p5)
group by
P.PredicateID
)
select top(5) PredicateID from P order by abs(TotalCount - EntityCount * 2);
返回的结果集最好,其次是最好的谓词。
Akinator与搜索引擎非常接近。我认为数据库没有足够的可伸缩性来实现类似Akinator的功能(至少:不是像SQL那样的标准关系数据库)。如果我想实现Akinator,我会改用发布列表,反向索引和类似的数据结构。