使用LINQ拓扑排序拓扑、LINQ

由网友(齐肩马尾拽天下)分享简介:我有有一个部分顺序关系,我的项目清单。即,该列表可以考虑偏序集。我想这个名单以同样的方式进行排序在本问题。作为正确回答有,这被称为拓扑排序。I have a list of items that have a partial order relation, i. e, the list can be consider...

我有有一个部分顺序关系,我的项目清单。即,该列表可以考虑偏序集。我想这个名单以同样的方式进行排序在本问题。作为正确回答有,这被称为拓扑排序。

I have a list of items that have a partial order relation, i. e, the list can be considered a partially ordered set. I want to sort this list in the same way as in this question. As correctly answered there, this is known as topological sorting.

有一个相当简单的公知的算法来解决这个问题。我想一个LINQ般的实现了。

There's a reasonably simple known algorithm to solve the problem. I want a LINQ-like implementation of it.

我已经尝试过使用排序依据扩展方法,但我敢肯定它是不是能够使拓扑排序。问题是,的IComparer< TKEY的> 接口是不能够再present部分订单。这是因为比较方法可以返回值的主要三种:零 负和正,这意味着是相等 是-小于和是-更大,那么,分别。一个可行的解决方案只会是可能的,如果有一种方法返回的是无关的

I already tried to use OrderBy extension method, but I'm quite sure it's not able to make topological sorting. The problem is that the IComparer<TKey> interface is not able to represent a partial order. This happens because the Compare method can return basically 3 kinds of values: zero, negative, and positive, meaning are-equal, is-less-than, and is-greater-then, respectively. A working solution would only be possible if there were a way to return are-unrelated.

这是我的偏见的观点,我在寻找通过 IPartialOrderComparer&LT可能会组成的回答; T&GT; 接口和一个像这样的扩展方法:

From my biased point of view, the answer I'm looking for might be composed by an IPartialOrderComparer<T> interface and an extension method like this:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IPartialOrderComparer<TKey> comparer
);

这将如何实施?如何在 IPartialOrderComparer&LT; T&GT; 界面会是什么样子?你会推荐一种不同的方法?我渴望看到它。也许有一个更好的方式来重新present偏序,我不知道。

How would this be implemented? How does the IPartialOrderComparer<T> interface would look like? Would you recommend a different approach? I'm eager to see it. Maybe there's a nicer way to represent the partial order, I don't know.

推荐答案

我会建议使用相同的IComparer接口,但写扩展方法,以便跨preT 0为不相关。在偏序,若元素a和b是相等它们的顺序并不重要,像明智的,如果他们是无关的 - 你只需要订购他们就与他们所定义的关系元素

I would suggest using the same IComparer interface, but writing the extension method so as to interpret 0 as not related. In a partial ordering, if elements a and b are equal their order doesn't matter, like-wise if they are unrelated - you only have to order them with respect to elements with which they have defined relationships.

下面是一条什么偶数和奇数的偏序的一个例子:

Here's an example that does a partial ordering of even and odd integers:

namespace PartialOrdering
{
    public static class Enumerable
    {
        public static IEnumerable<TSource> PartialOrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
        {
            List<TSource> list = new List<TSource>(source);
            while (list.Count > 0)
            {
                TSource minimum = default(TSource);
                TKey minimumKey = default(TKey);
                foreach (TSource s in list)
                {
                    TKey k = keySelector(s);
                    minimum = s;
                    minimumKey = k;
                    break;
                }
                foreach (TSource s in list)
                {
                    TKey k = keySelector(s);
                    if (comparer.Compare(k, minimumKey) < 0)
                    {
                        minimum = s;
                        minimumKey = k;
                    }
                }
                yield return minimum;
                list.Remove(minimum);
            }
            yield break;
        }

    }
    public class EvenOddPartialOrdering : IComparer<int>
    {
        public int Compare(int a, int b)
        {
            if (a % 2 != b % 2)
                return 0;
            else if (a < b)
                return -1;
            else if (a > b)
                return 1;
            else return 0; //equal
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<Int32> integers = new List<int> { 8, 4, 5, 7, 10, 3 };
            integers = integers.PartialOrderBy<Int32, Int32>(new Func<Int32, Int32>(delegate(int i) { return i; }), new EvenOddPartialOrdering());
        }
    }
}

结果:4,8,3,5,7,10

Result: 4, 8, 3, 5, 7, 10

阅读全文

相关推荐

最新文章