如何对连接对的列表进行分组

时间:2015-10-30 11:16:25

标签: c# nodes graph-theory edges

我有一个从X到Y的连接列表,如下所示: -

public class Connection
{
    private int X { get; set; }
    private int Y { get; set; }

    public Connection(int X, int Y)
    {
        this.X = X;
        this.Y = Y;
    }
}


List<Connection> connectionList = new List<Connection>();

connectionList.Add(new Connection(1, 2));
connectionList.Add(new Connection(1, 3));
connectionList.Add(new Connection(1, 4));
connectionList.Add(new Connection(2, 1));
connectionList.Add(new Connection(2, 3));
connectionList.Add(new Connection(2, 4));
connectionList.Add(new Connection(3, 1));
connectionList.Add(new Connection(3, 2));
connectionList.Add(new Connection(4, 1));
connectionList.Add(new Connection(4, 2));
connectionList.Add(new Connection(5, 6));

我现在想知道我有groups的连接列表。例如,这里有两个连接的图表,代表上面的数据。

connected graph

程序的期望输出是两组,A(1,2,3 4)和B(5,6)。

最佳方法是什么?

3 个答案:

答案 0 :(得分:4)

这个怎么样;

var groups = new List<List<int>>();
foreach (var con in connectionList)
{
    if(!groups.Any(g => g.Contains(con.X) || g.Contains(con.Y)))
    {
        groups.Add(new List<int>() { con.X, con.Y }); //con.X is not part of any group, so we can create a new one with X and Y added, since both a are in the group       
    } 
    else 
    {
        var group = groups.First(g => g.Contains(con.X) || g.Contains(con.Y));
        if(!group.Contains(con.X)) group.Add(con.X);
        if(!group.Contains(con.Y)) group.Add(con.Y);
    }
}

从头顶做了这件事,也没有测试过。目的很简单;

  • 如果任何组中都存在X和Y,请添加新组。
  • 如果组中存在X或Y,则Y或X也应该是该组的一部分,因此将其添加。

鉴于你的情况,这应该给你两个清单;一个用(1,2,3,4),一个用(5,6)。

编辑:点击here查看结果。

答案 1 :(得分:1)

您需要在图表中找到所有已断开连接的子图。您需要做的是从特定节点开始,并通过实现DFSBFS来遍历连接到您开始的节点的所有节点,并标记所有这些节点。当没有更多连接的节点时,检查是否存在任何非市场节点。如果有任何特定的未标记节点的启动并执行相同的操作,直到没有未标记的节点。 您还可以检查Ktuskal算法here。这种算法比较复杂,因为它在断开连接的加权图中描述了所有三个。

答案 2 :(得分:1)

接受的答案适用于数据集,但它不会使用不同的订单,例如:

connectionList.Add(new Connection(1, 2));
connectionList.Add(new Connection(3, 4));
connectionList.Add(new Connection(1, 3));

有很多选择,但其中一个是:

var groups = new List<List<int>>();
foreach (var con in connectionList)
{
    if(!groups.Any(g => g.Contains(con.X) || g.Contains(con.Y)))
    {
        groups.Add(new List<int>() { con.X, con.Y }); //con.X is not part of any group, so we can create a new one with X and Y added, since both a are in the group       
    } 
    else 
    {
        if(groups.Where(g => g.Contains(con.X) || g.Contains(con.Y)).Count()==1)
        {
           var group = groups.First(g => g.Contains(con.X) || g.Contains(con.Y));
           if(!group.Contains(con.X)) group.Add(con.X);
           if(!group.Contains(con.Y)) group.Add(con.Y);
        }
        if(groups.Where(g => g.Contains(con.X) || g.Contains(con.Y)).Count()>1)
        {
          List<int> groupUnion= new List<int>();
          foreach(var grp in groups.Where(g => g.Contains(con.X) || g.Contains(con.Y)).ToList())
          {
            groupUnion= groupUnion.Union(grp).ToList(); 
            groups.Remove(grp);
          }
          if(!groupUnion.Contains(con.X)) groupUnion.Add(con.X);
          if(!groupUnion.Contains(con.Y)) groupUnion.Add(con.Y);              
          groups.Add(groupUnion);
        }


    }
}

here是运行代码的示例