Reputation: 87
I'm kind of at a loss on how to tackle this homework project based on what I know about prolog (which, admittedly isn't a whole lot)
Basically, we have a group of diners that rank their preferences on a certain dish. to make things easy, we name the dishes A, B, C, D, and E
The goal is to assign seats at a table based on what the diners selected as their preference, so if diner1 had their rankings as [A, E, D, C, B], he would be seated somewhere near Diner2 who has [E, C, A, B, D] because of the similar rankings.
each dish will have a point value, and will be multiplied by a modifier based on the dishes position in the list.
I know I'm going to need a list of Diners (which are going to be lists themselves), and I'm going to need to sort that list based on a score that will be calculated based on the dish rankings. The sorted list will be output in decreasing order (highest score at the top)
My questions are, how would I calculate the score based on prologs math functions, and how would I associate a Diner with a score, and then sort the list of Diners based on the score? Furthermore, is it possible to do this all in one query?
thank you in advance
Upvotes: 0
Views: 114
Reputation: 22803
Well, I would first create a small database with the scores for each dish:
dishScore(a, 5).
dishScore(b, 7.3).
% ...
Then I'd set up the location coefficients:
coefficients([1, 0.8, 0.7, 0.4, 0.1]).
Now you're prepared to write a predicate to score a ranking:
scoreRanking(Ranking, Score) :-
coefficients(Coeff),
scoreRankingLoop(Ranking, Coeff, Score).
scoreRankingLoop([], [], 0).
scoreRankingLoop([Dish|Dishes], [C|Coeff], FinalScore) :-
dishScore(Dish, DishScore),
scoreRankingLoop(Dishes, Coeff, RemainingScore),
MyScore is DishScore * C,
FinalScore is RemainingScore + MyScore.
Now you need to sort the list of diners. The ISO predicate for doing this kind of thing is keysort/2
, and the idea is that you build X-Y
terms where X is the key and Y is the value, and it sorts on X. SWI has its own special predicate, predsort/3
which we will use instead because it's less work.
compareOnScore(Delta, Left, Right) :-
scoreRanking(Left, LScore),
scoreRanking(Right, RScore),
compare(Delta, LScore, RScore).
Now you can just call predsort/3
with compareOnScore
as an argument:
predsort(compareOnScore, Diners, Result).
Of course, this is making a lot of bad assumptions. I hope it's helpful anyway!
Upvotes: 1