按与邻居相似性排序的对象数组

时间:2018-10-15 20:21:19

标签: javascript node.js algorithm computer-science

我真的希望你能帮助我,我有一个对象数组,我需要一种算法或一个指向某些东西的指针来读取它们,以使其与邻居相似。

例如

[ 
  {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

2 个答案:

答案 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!太贵了,因此我们必须使用更简单的方法。

您可以采用一个贪婪的近似值,即:

  1. 由任何邻居开始
  2. 从最近的邻居继续到最后添加的邻居
  3. 重复2直到完成

这不是最佳选择,但也不会相差太远。计算起来非常便宜(O(n ^ 2),O(n!)的整数)。

使用此函数,您实质上是在尝试解决traveling salesman problem(TSP),该问题已经写了很多东西,并且存在很多近似值。一般问题是np-hard,因此通常的方法是选择一个不太昂贵的近似值,其中最简单的方法可能是上面概述的贪婪方法。