【问题标题】:Set Covering: Find a set of arrays that overlap the elements of a target array集合覆盖:找到与目标数组元素重叠的一组数组
【发布时间】:2017-10-18 14:12:05
【问题描述】:

假设我有一个数组,A(可排序,如果有帮助的话)

我有一组数组,BCD 等...(全部可排序),所有这些数组都可能部分或完全重叠数组 A

我想找到与数组A 完全重叠的数组BCD 等的最小集合。返回第一个匹配项。

例如,

const A = [1, 2, 3, 4, 'a', 'b', 'c'];

const B = [1, 3, 4, 5, 10];
const C = [1, 3, 5, 'a', 'b']
const D = [2, 4, 'a', 'b', 'c'];
const E = [1, 2, 'b', 'c'] 

findSmallestSet(A, [B, C, D, E]);
// => [B, D]

除此之外:我最初的问题是找到与目标节点树完全重叠的节点树,但我认为上面提出的问题可能是一个更简单的解决方案。

【问题讨论】:

  • B C D E 中数组的最小数量或 B C D E 中元素的最小组合数?
  • 最少数量的数组。感谢您澄清问题:)

标签: javascript arrays algorithm


【解决方案1】:

这被称为“设置封面”问题。它是 NP 完全的,并且经过充分研究。 “正确答案”取决于输入的大小以及您是否可以接受近似值。

【讨论】:

  • 感谢您向我介绍 Set Cover 问题。是否有任何限制可以大大简化问题?假设套数在10-100左右
【解决方案2】:

您可以这样做,首先创建排序函数,该函数将根据匹配元素的数量对第二个参数进行排序,以便您可以从那里开始,然后循环每个内部数组并从第一个参数中删除元素,如果它在当前找到它数组,如果第一个数组中有左元素,则再次对键进行排序并使用递归重复该过程。

const A = [1, 2, 3, 4, 'a', 'b', 'c'];

const B = [1, 3, 4, 5, 10];
const C = [1, 3, 5, 'a', 'b']
const D = [2, 4, 'a', 'b', 'c'];
const E = [1, 2, 'b', 'c']

function findSmallestSet(one, [B, C, D, E]) {
  let obj = {B, C, D, E}
  let keys = Object.keys(obj);
  let getL = (e) => obj[e].filter(e => one.includes(e)).length
  let sortK = (keys) => keys.sort((a, b) => getL(b) - getL(a))
  sortK(keys)
  var r = []

  let find = (one, k) => {
    obj[k[0]].forEach(function(a) {
      var index = one.indexOf(a);
      if (index != -1) one.splice(index, 1)
    })
    
    r.push(k[0])

    if (one.length) {
      k.shift()
      sortK(k)
      find(one, k)
    }
  }

  find(one, keys)
  return r;
}

console.log(findSmallestSet(A, [B, C, D, E]));

【讨论】:

  • 我喜欢这个解决方案的优雅,但我认为它失败了,例如const B = [1, 4, 5, 10, 'c']; const C = [3, 2, 'a', 'b']; const D = [2, 4, 'a', 'b', 'c']; const E = [5, 6, 'd', 'e'];
猜你喜欢
  • 1970-01-01
  • 2020-11-27
  • 2018-12-29
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 2012-04-09
相关资源
最近更新 更多