用于随机混洗相等元素的排序比较方法

时间:2009-06-23 06:31:22

标签: algorithm language-agnostic comparison random sorting

这是一个难题。

我想更改以下比较方法,以便当两个项目被认为相等时,它们将随机洗牌。

myList.Sort( (x, y) => x.Score.CompareTo(y.Score) );

我可以想象,如果您不希望在分数相同的情况下优先考虑一个结果,那么在订购搜索结果时这种情况会很有用。

有人想试一试吗?

这是我第一次尝试解决方案,但它不起作用。我会告诉你原因。

class RandomizeWhenEqualComparer<T> : IComparer<T>
{
    private readonly Func<T, T, int> _comparer;

    public int Compare(T x, T y)
    {
            if (x.Equals(y)) return 0;

        int result = _comparer(x, y);

        if (result != 0) return result;

        double random = StaticRandom.NextDouble();
        return (random < .5) ? -1 : 1;
    }

    public RandomizeWhenEqualComparer(Func<T, T, int> comparer)
    {
        _comparer = comparer;
    }
}

4 个答案:

答案 0 :(得分:7)

首先随机播放,然后使用稳定排序。

答案 1 :(得分:4)

正如锐齿所说,你可以存储每次比较的结果并再次查看它们。

但这并不好玩,而且它会增加时间复杂度和空间复杂度,因为您必须存储以前的比较并在每次进行比较时搜索它们。

所以这就是我要做的事情: 在搜索开始时,获取随机种子。 然后编写一个基于T和种子创建哈希的函数。

public int Hash(T a, int s)
{
    // e.g.
    return Random( a.Name().ToInt() + s ).NextDouble();
}

public int Compare(T x, T y, int s)
{
    if (x.Equals(y)) return 0;

    int result = _comparer(x, y);

    if (result != 0) return result;

    return (Hash(x, s) < Hash(y, s) ) ? -1 : 1;
}

这在给定的排序中是稳定的,但不需要查找表。

答案 2 :(得分:2)

问题是比较的结果不能在排序中重现。对于给定的元素对,排序算法可以多次调用比较方法,并且比较方法应该每次都返回相同的值。

您可以存储涉及随机shuffle的每个比较的结果,并在再次为相应的对调用比较方法时查找它们。

答案 3 :(得分:0)

如果您只控制排序方法,那么您将受到严重限制,因为您不知道它将使用哪种排序算法。您必须保持相等键值之间任何比较的随机结果并查看任何新的比较表格中的相等值之间的差异,以确保在任何单一的分拣运行中获得相同,稳定的结果,如Sharptooth所说。

不是严格意义上的比较方法,但是快速排序算法怎么样,你可以随机分配哪个细分任何一个值等于枢轴值的值呢?递归细分会在左边随机放置一些相等的值,在右边放置一些值。