我真的希望你能帮助我,我有一个对象数组,我需要一种算法或一个指向某些东西的指针来读取它们,以使其与邻居相似。
例如
[
{a:12,b: 7,c: 5},
{a: 5,b: 5,c: 5},
{a: 3,b: 3,c: 3},
{a: 5,b: 7,c: 5},
{a:12,b: 7,c: 5}
]
成为
[
{a: 5,b: 5,c: 5},
{a: 5,b: 7,c: 5},
{a:12,b: 7,c: 5},
{a:12,b: 7,c: 5},
{a: 3,b: 3,c: 3},
]
我在这里有一个REPL ...
https://repl.it/@idrise/ThoseWellmadeMonitors
我已经强行将其强行使用,但它并没有获得最佳成绩,并且需要大阵列才能实现。
这是分数的计算方式,分数越高越好!
function scoreArray(array) {
let score = 0;
for (let f = 1; f < array.length; f++) {
score += howSimilarAreObjects(array[f - 1], array[f]);
}
return score;
}
function howSimilarAreObjects(object1, object2) {
let score = 0;
Object.keys(object1).forEach(curValue => {
if (object1[curValue] === object2[curValue]) {
score++;
}
});
return score;
}
任何帮助表示赞赏,
Idris
答案 0 :(得分:0)
您可以使每个元素相互竞争,并获得两个对象之间的相似性。然后进行分组,首先获得相似性最高的对象,然后获得较低相似性的对象。通过将它们推送到结果集,按已经看到的对象过滤数组。
const similar = (a, b) => Object.keys(a).filter(k => a[k] === b[k]).length;
var array = [{ a: 12, b: 7, c: 5}, { a: 5, b: 5, c: 5}, { a: 3, b: 3, c: 3}, { a: 5, b: 7, c: 5}, { a: 12, b: 7, c: 5}],
groups = {},
used = new Set,
result = [];
array.forEach((a, i) =>
array
.slice(i + 1)
.forEach(b => (s => (groups[s] = groups[s] || []).push(a, b))(similar(a, b))));
Object
.keys(groups)
.reverse()
.forEach(k => result.push(...groups[k].filter(o => !used.has(o) && used.add(o))));
console.log(result);
console.log(groups);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:0)
让我们定义一个您希望最小化的功能:
每对邻居之间的平方距离的最小和
如果要遍历所有n!
排列并选择最低的排列,则您将实现目标。当然,n!
太贵了,因此我们必须使用更简单的方法。
您可以采用一个贪婪的近似值,即:
这不是最佳选择,但也不会相差太远。计算起来非常便宜(O(n ^ 2),O(n!)的整数)。
使用此函数,您实质上是在尝试解决traveling salesman problem(TSP),该问题已经写了很多东西,并且存在很多近似值。一般问题是np-hard,因此通常的方法是选择一个不太昂贵的近似值,其中最简单的方法可能是上面概述的贪婪方法。