我正在寻找实现多元化排序的方法。每个单元格包含权重值和枚举类型。我想以一种方式对它进行排序,它将根据已经选择的元素类型使权重值动态变化,优先考虑那些选择较少的元素。至今。我想控制多样性因子,这样当它设置为高值时,它会产生一个完全不同的结果数组,当给出一个低值时,它将提供一个几乎常规的'排序数组。
这听起来不是一个非常具体的用例,所以如果对已知算法有任何引用,那也很棒。
更新: 根据Ophir的建议,这可能是一个基本的包装器:
// these will be the three arrays, one per type
$contentTypeA, $contentTypeB, $contentTypeC;
// sort each by value
sort($contentTypeA);
sort($contentTypeB);
sort($contentTypeC);
// while i didn't get the amount I want or there aren't any more options to chose from
while ($amountChosen < 100 && (count($contentTypeA) + count($contentTypeB) + count($contentTypeC) > 0)) {
$diversifiedContent[] = selectBest($bestA, $bestB, $bestC, &$contentTypeA, &$contentTypeB, &$contentTypeC);
$amountChosen++;
}
$diversifiedContent = array_slice($diversifiedContent, 0, 520);
return $diversifiedContent;
}
function selectBest($bestA, $bestB, $bestC, &$contentTypeA, &$contentTypeB, &$contentTypeC) {
static $typeSelected;
$diversifyFactor = 0.5;
if (?) {
$typeSelected['A']++;
array_shift($contentTypeA);
return $bestA;
}
else if (?) {
$typeSelected['B']++;
array_shift($contentTypeB);
return $bestA;
}
else if (?) {
$typeSelected['C']++;
array_shift($contentTypeC);
return $bestA;
}
}
答案 0 :(得分:2)
您的定义是非常笼统的术语,而不是数学术语,所以我怀疑您是否能找到与您想要的完全匹配的紧密解决方案。 我可以建议这个简单的方法:
分别对每种类型进行排序。然后通过迭代地获取最高优先级列表中的最大值来合并列表,其中优先级是值的乘积和该类型的“饥饿”因子。饥饿因子将是忽略该类型的步数和多样性因子的组合。此功能的确切形状取决于您的应用程序。
答案 1 :(得分:1)
这是一个想法:
class item(object):
def __init__(self, enum_type, weight):
self.enum_type = enum_type
self.weight = weight
self.dyn_weight = weight
def __repr__(self):
return unicode((self.enum_type, self.weight, self.dyn_weight))
def sort_diverse(lst, factor):
# first sort
by_type = sorted(lst, key=lambda obj: (obj.enum_type, obj.weight))
cnt = 1
for i in xrange(1, len(lst)):
current = by_type[i]
previous = by_type[i-1]
if current.enum_type == previous.enum_type:
current.dyn_weight += factor * cnt
cnt += 1
else:
cnt = 1
return sorted(by_type, key=lambda obj: (obj.dyn_weight, obj.enum_type))
试试这个例子:
lst = [item('a', 0) for x in xrange(10)] + [item('b', 1) for x in xrange(10)] + [item('c', 2) for x in xrange(10)]
print sort_diverse(lst, 0) # regular sort
print sort_diverse(lst, 1) # partially diversified
print sort_diverse(lst, 100) # completely diversified
根据您的需要,您可能希望使用更复杂的重量更新功能。
该算法基本上是O(nlogn)时间复杂度和O(n)空间复杂度,因为它需要列表的两种和两种副本。