Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中对共享同一父项和子项的项进行分组_C#_Algorithm_Tree - Fatal编程技术网

C# 在C中对共享同一父项和子项的项进行分组

C# 在C中对共享同一父项和子项的项进行分组,c#,algorithm,tree,C#,Algorithm,Tree,我希望找到一种有效的方法将项目分组到树形图中,树形图具有以下特征: 关于树形图,如果水平绘制,它有如下多个层: (0,0)--(1,0)--(2,0) \ \-(1,1)--(2,1) \--(1,2)--/ 对于由类节点建模的节点x,y,x是其级别,y是其索引。对于任何边,我们只允许该边的两个节点使用顺序索引,因此禁止使用1,2-3,2。 允许多个根:0,0,1…等。 关于将项目分组: 因为在树的数据源中有如下节点: (3,5)--(4,10)--(5,5) \ \-(4

我希望找到一种有效的方法将项目分组到树形图中,树形图具有以下特征:

关于树形图,如果水平绘制,它有如下多个层:

(0,0)--(1,0)--(2,0)
   \ \-(1,1)--(2,1)
    \--(1,2)--/
对于由类节点建模的节点x,y,x是其级别,y是其索引。对于任何边,我们只允许该边的两个节点使用顺序索引,因此禁止使用1,2-3,2。 允许多个根:0,0,1…等。 关于将项目分组: 因为在树的数据源中有如下节点:

(3,5)--(4,10)--(5,5)
  \  \-(4,11)-/  /
   \    ....    /
    \--(4,80)--/
我希望将上述4,10~80节点分组为一个节点,这些节点具有相同的特征

只有一个它们共享的父节点 只有一个子节点共享 还需要解决他们只有一个共同的父母或一个共同的孩子,但根本没有孩子或父母的情况。 使用一个特殊的类CompoundNode,它是Node的一个子类

以下是节点的骨架类:

public class Node
{
    public Node(string id)
    {
        Id = id;
    }

    public string Id { get; set; }

    private readonly List<Node> children = new List<Node>();
    public List<Node> Children { get { return children; } }
    private readonly List<Node> parents = new List<Node>();
    public List<Node> Parents { get { return parents; } }

    protected bool Equals(Node other)
    {
        ....
    }

    public override bool Equals(object obj)
    {
        ....
    }

    public override int GetHashCode()
    {
        return (Id != null ? Id.GetHashCode() : 0);
    }

    public override string ToString()
    {
        ....
    }
}
谢谢

编辑:

以下是我在不修改树的情况下提取关系的解决方案,不处理零父或零子的情况:

        var relationships = new List<Tuple<string, string, string>>();

        foreach (var middle in nodes)
        {
            if (middle.Children.Count == 1 && middle.Parents.Count == 1)
            {
                var child = middle.Children[0];
                var parent = middle.Parents[0];
                relationships.Add(new Tuple<string, string, string>(parent.Id, middle.Id, child.Id));
            }
        }
        var groups = relationships.GroupBy(t => new { t.Item1, t.Item3 }).Where(a => a.Count() > 1);

        var toGroupedRelations = groups.Cast<IEnumerable<Tuple<string, string, string>>>().ToList();

好的,这是第一次尝试。无论如何,我应该给你一些好的建议:

var nodes = new List<Node>();

// !! populate your nodes list with all your real nodes first!

// filter to nodes with at most 1 parent and 1 child
// group by a tuple containing the parent (if it exists) and the child (if it exists)
var grouped = nodes.Where(i => i.Children.Count <= 1 && i.Parents.Count <= 1)
    .GroupBy(i => 
        new Tuple<Node, Node>(i.Parents.Count == 0 ? null : i.Parents[0], 
                                i.Children.Count == 0 ? null : i.Children[0]));

// go through your groups - each one should be a cluster of nodes to be merged
foreach (var group in grouped)
{
    // get the first node in the group (which one is arbitrary if we're merging anyway)
    var node = group.First();

    // if this group has a parent
    if (node.Parents.Count == 1)
    {
        // change the parent to only have one child - this one!
        node.Parents[0].Children.Clear();
        node.Parents[0].Children.Add(node);
    }

    // if this group has a child
    if (node.Children.Count == 1)
    {
        // change the child to only have one parent - this one!
        node.Children[0].Parents.Clear();
        node.Children[0].Parents.Add(node);
    }
}

你的树有多大?这会对算法的选择产生重大影响。@P.Brian.Mackey,不,我在一家基金公司工作@Baldrick它不是很大,将少于10个级别,每个级别的项目少于1000个。@VikramBhat查看我编辑的问题。GroupBy就是我要找的!