多样化排序算法

时间:2014-04-03 06:42:48

标签: arrays algorithm sorting pseudocode

我正在寻找实现多元化排序的方法。每个单元格包含权重值和枚举类型。我想以一种方式对它进行排序,它将根据已经选择的元素类型使权重值动态变化,优先考虑那些选择较少的元素。至今。我想控制多样性因子,这样当它设置为高值时,它会产生一个完全不同的结果数组,当给出一个低值时,它将提供一个几乎常规的'排序数组。

这听起来不是一个非常具体的用例,所以如果对已知算法有任何引用,那也很棒。

更新: 根据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;
    }
}

2 个答案:

答案 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)空间复杂度,因为它需要列表的两种和两种副本。