Проверка всех возможных порядков является классической задачей перестановки, даже если для этой конкретной задачи может быть более эффективный алгоритм.
Одна оптимизация может быть выполнена путем уменьшения перестановки до длины-1 массива, поскольку в круговых порядкахнапример, 0,1,2,3,4 и 4,0,1,2,3 (и все последующие вращения) одинаковы.Вы можете просматривать заказ со своего места, всегда начиная с позиции 0.
(function ()
{
'use strict';
let popularity =
[
[ 0, 1, 1, 1, 1], // ← yes you like all your friends
[-1, 0, 1,-1, 0],
[-1, 1, 0, 1, 0],
[ 1, 1, 1, 0,-1],
[ 1, 0, 0,-1, 0],
];
function permutation(arr)
{
let
l = arr.length,
perms = []
;
if(l<2)
return [arr];
for(let i=0; i<l; i++)
{
let
cpy = Array.from(arr),
[perm] = cpy.splice(i, 1)
;
perms.push(...permutation(cpy).map(v => [perm, ...v]));
}
return perms;
}
let
keys = Array.from(popularity.keys()).slice(1),
permutations = permutation(keys),
rating = permutations.map(v =>
{
let
last = v.length -1,
// start with our own relationships to the left and right neighbour
// (each: we like him, he likes us)
rate =
popularity [0] [v[0]]
+ popularity [v[0]] [0]
+ popularity [0] [v[last]]
+ popularity [v[last]] [0]
;
for(let i = 0; i<last; i++)
rate += popularity[v[i]][v[i+1]] + popularity[v[i+1]][v[i]];
return [rate, [0, ...v]];
}
).sort( (v1, v2) => ( v1[0] === v2[0] ? 0 : (v1[0] > v2[0] ? -1 : 1)) );
console.log(rating);
})();
выход:
[ [ 8, [ 0, 4, 1, 2, 3 ] ],
[ 8, [ 0, 3, 2, 1, 4 ] ],
[ 6, [ 0, 3, 1, 2, 4 ] ],
[ 6, [ 0, 4, 2, 1, 3 ] ],
[ 4, [ 0, 1, 4, 2, 3 ] ],
[ 4, [ 0, 1, 2, 3, 4 ] ],
[ 4, [ 0, 4, 1, 3, 2 ] ],
[ 4, [ 0, 1, 3, 2, 4 ] ],
[ 4, [ 0, 2, 3, 1, 4 ] ],
[ 4, [ 0, 3, 2, 4, 1 ] ],
[ 4, [ 0, 4, 2, 3, 1 ] ],
[ 4, [ 0, 4, 3, 2, 1 ] ],
[ 2, [ 0, 3, 4, 2, 1 ] ],
[ 2, [ 0, 3, 1, 4, 2 ] ],
[ 2, [ 0, 2, 4, 1, 3 ] ],
[ 2, [ 0, 4, 3, 1, 2 ] ],
[ 2, [ 0, 3, 4, 1, 2 ] ],
[ 2, [ 0, 1, 2, 4, 3 ] ],
[ 2, [ 0, 2, 1, 4, 3 ] ],
[ 2, [ 0, 2, 1, 3, 4 ] ],
[ 0, [ 0, 1, 4, 3, 2 ] ],
[ 0, [ 0, 2, 3, 4, 1 ] ],
[ -2, [ 0, 1, 3, 4, 2 ] ],
[ -2, [ 0, 2, 4, 3, 1 ] ] ]
Как мы видим, все еще в обратном порядкеПерестановки в сочетании с вами (0) с одинаковым рейтингом конечноИсключение зеркальных порядков, т. Е. Обращенных перестановок, было бы еще одной оптимизацией.
Я сделал это для демонстрации за один шаг, чтобы шаг за шагом сделать код более читабельным и решать отдельные проблемы.Вы можете изменить рефакторинг вычисления рейтинга непосредственно в алгоритм перестановки.
Правильный расчет сложности времени не кажется таким простым.Пожалуйста, прочитайте обсуждение в комментариях ниже.