【问题标题】:Array of Objects ordered by similarity to neighbour按与邻居相似度排序的对象数组
【发布时间】:2018-10-15 20:21:19
【问题描述】:

我真的希望你能帮助我我有一个对象数组,我需要一个算法或一个指向某些东西的指针来阅读,以便根据与邻居的相似性对它们进行排序。

举例

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

非常感谢任何帮助,

伊德里斯

【问题讨论】:

  • 为什么c 属性按降序排序,而其他属性按升序排序..?
  • “相似度”是什么意思? {3, 3, 3}{5, 5, 5} 的相似度与 {12, 7, 5} 的相似度有何不同?
  • 您可能想查找“余弦相似度”的 JavaScript 实现
  • similarity measure 不提供排序所需的ordering。或者您是否尝试通过它们与特定其他元素的相似性对它们进行降序排序?
  • repl 中是描述所需输出的评分函数。我手动对结果进行排序。顺序并不重要,与具有匹配字段的对象的接近度很重要。

标签: javascript node.js algorithm computer-science


【解决方案1】:

您可以将每个元素相互运行并获得两个对象之间的相似性。然后取这些组,首先得到相似度最高的对象,然后是较低的对象。通过将它们推送到结果集,通过已经看到的对象过滤数组。

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

【讨论】:

  • 我无法理解这些groups。您似乎将任意对象推入其中。如果您至少要推送 pairs (每对具有相同的相似性),我会理解,但是组中未配对的对象之间有什么关系?
  • 我怀疑这总能找到最佳解决方案。贪婪的“最大优先”算法通常在组合问题上表现不佳。
  • 一段非常优雅的代码,并没有像 Bergi 所说的那样解决问题,但非常接近。可悲的是,它非常消耗内存,并且在数组中仅 1000 个对象上崩溃了节​​点:(
【解决方案2】:

让我们定义一个您希望最小化的函数:

每对邻居之间的最小平方和

如果您要遍历所有 n! 排列,并选择最低的总数,您就已经实现了您的目标。当然,n! 太贵了,所以我们必须使用更简单的东西。

你可以取一个贪心的近似值,很简单:

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

这不是最优的,但也不会太远。而且计算起来非常便宜 (O(n^2),而不是 O(n!))。

使用此函数,您实际上是在尝试求解traveling salesman problem (TSP),在该问题上已经写了很多,并且存在很多近似值。一般的问题是np-hard,所以正常的做法是选择一个不那么昂贵的近似值,其中最简单的可能是上面概述的贪心方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多