如何通过标记匹配和组匹配对此数组进行最佳排序?

时间:2016-12-02 12:32:02

标签: arrays ruby algorithm sorting

我有一个数组arr条目,我有一个entryA。我的目标是找到与arr最相关的entryA条目。

我决定使用标记出现次数和组成员资格来排序arr。我希望尽可能减少时间和空间:

# For some entry entryX in array arr:
   entryX.tag_list      #returns the array of tags for entryX
   entryX.groups        #returns the array of groups for entryX
   entryA.user          #returns the user who created entryA

# Similarly, for entryA
   entryA.tag_list      #returns the array of tags for entryA
   entryA.groups        #returns the array of groups for entryA
   entryA.user          #returns the user who created entryA

我想对数组arr进行排序,使得arr中与entryA共享最多相同组的条目,entryA.tag_list中相同标签的数量最多并且由同一个用户创建将具有优先权,并将定位在arr[0]。所以我想为每个共享组分别设置1,每个标记共享1个,如果由同一个用户创建,则为2个。

实现这一目标的最佳算法是什么?

3 个答案:

答案 0 :(得分:1)

  1. 设计一个结构以保留{original_entry_index, closeness_to_A_score}
  2. 使用与输入数组一样多的元素数量创建上述数组并分别填入closeness_to_A_score
  3. closeness_to_A_score降序创建的数组。
  4. O(N)空间复杂度和O(N * log(N))时间复杂度。

    在为“共享标签”和“共享组”的得分做出贡献时,可能会出现一些惊喜 - 如果您可以将它们存储在哈希集(最佳)或排序集(足够好)而不是列表中(呻吟) !),计算交叉点中的元素将尽可能快地计算。

答案 1 :(得分:1)

发布Adrian的回答。您已经为数组中的项描述了一种分类器。现在你需要用你的规则来实现它。

为了应用它,您可以使用Enumerable#sort_by,除了分类之外,它正是Adrian所说的。此方法将根据分类等级对元素进行排序。考虑到,您需要在列表顶部使用最相似的元素,您需要将.inverse添加到结果数组中。

解决方案的可能模板之一可能如下所示

def classifier_generator(sample)
  lambda do |entry|
    # calculation of similarity based on sample and entry values
  end
end 

grader = classifier_generator(entryA)

arr.sort_by &grader .inverse

答案 2 :(得分:1)

TAG_LIST_UNIT_VALUE = 1
GROUPS_UNIT_VALUE = 1
SAME_USER_VALUE = 2

def score(entryA, entryX)
   TAG_LIST_UNIT_VALUE * (entryA.tag_list & entryX.tag_list).size +
   GROUPS_UNIT_VALUE * (entryA.groups & entryX.groups).size +
   (entryA.user == entryX.user) ? SAME_USER_VALUE : 0
end

arr.sort_by { |entryX| -score(entryA, entryX) }

entryA.tag_list & entryX.tag_listentryAentryX共有的群组数组。类似于groupsscore返回的值被否定以使排序减少。