4

The Akinator can find everything. I can guess akinator's algorithms but I can't understand, akinator uses database or any search engine because find everything. If it use database, what is the logic of database? How can founder find all knowledges?

That's enough for now :)

Birlikisgu
  • 227
  • 1
  • 3
  • 9
  • related: [How do 20 questions AI algorithms work?](http://stackoverflow.com/questions/887533/how-do-20-questions-ai-algorithms-work) – amit Jun 14 '12 at 10:41
  • I first thought it is a dupe, but then changed my mind... However, it is definetly *related*.. – amit Jun 14 '12 at 10:43

3 Answers3

1

I am going to make speculations here, not anything certain, because I am not among the ones that wrote this amazing robot.

I suppose it started off not being so clever as it is now, but remember: every time it gets an answer wrong it asks you to put in another question that will differentiate Akinator's suggestions, from the actual person you got in mind. Thus it builds on its own knowledge base.

I suppose Akinator uses decision trees, or even C4.5 algorithm to choose what to query every time. It asks questions based on the previous answer, which gets closer to C4.5 algorithm, not the classic decision tree. What is really amazing about Akinator is that it can guess even some of the cases in which you made a mistake in one or even two of the answers. This, I suppose, is an add-on to the algorithm developed by the authors of the robot.

Just calculate if it contains hundreds of thousand of questions and every single one of them has 5 possible answers, how many different personalities it can guess.

Boris Strandjev
  • 46,145
  • 15
  • 108
  • 135
1

I don't know how exactly is implemented the original algorithm of Akinator, but we've solved a similar task using database. You may read about its implementation at https://github.com/nesterovsky-bros/KB.

Edited:

The suggested solution is an algorithm that takes as input a list of questions with answers, and offers the next question(s). That question and an answer to it are added to the set of questions and answers. When there is no more question, then a list of entities is determined by set of questions with answers on these questions.

In essence, SQL solution works like this:

  1. Define tables:

Table "Entity" defines objects:

create table Data.Entity
(
  EntityID int not null primary key, -- Object key.
  Name nvarchar(256) -- Object name
);

Table "PredicateType" defines question types:

create table Data.PredicateType
(
  PredicateID int not null primary key, -- question id
  Name nvarchar(128) not null unique -- question name.
);

Table "Predicate" stores entities for which predicate is true:

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)
);
  1. The solution is build a select that for a set of question and answers on input, offers a new question on output.

For example, if we have P(i) - questions, A(i) - answers, i = 1..5, and
A(1) = A(3) = 1, A(2) = A(4) = A(5) = 0 then the select will look like this:

  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);

Where returned result-set is best the next best predicates.

0

Akinator is something very close to a search engine. I don't think that a database can be scalable enough to implement something like Akinator (at least: not a standard relational SQL-like database). If I would have tried to implement Akinator, I would have used instead posting lists, inverted indexes and similar data structures.