创建集群需要C#算法

创建集群需要C#算法,c#,linq,graph-algorithm,C#,Linq,Graph Algorithm,我有一个通用列表,比如list TransactionInfo类有三个属性:- public long TransactionId { get; set; } public string BuyerName { get; set; } public string SellerName { get; set; } 如果以下是我的列表中的数据:- 1 A B 2 A C 3 A D 4 G H 5 C M 6 D E 7 A F 8 H L 9 L R 10 Y Z 然后,我想基于成员

我有一个通用列表,比如
list

TransactionInfo
类有三个属性:-

public long TransactionId { get; set; }
public string BuyerName { get; set; }  
public string SellerName { get; set; }
如果以下是我的列表中的数据:-

1 A B   
2 A C
3 A D
4 G H
5 C M
6 D E
7 A F
8 H L
9 L R
10 Y Z
然后,我想基于成员之间的事务创建组集群。我想写一个LINQ查询,它应该返回新的列表

ClusterInfo类包含一个属性:-

public List<TransactionInfo> Transactions { get; set; }
集群[1]

4 G H
8 H L
9 L R
集群[2]

10 Y Z
如何选择这些新列表:- 所有直接或间接买家/卖家都应属于一个集群

谁能帮我写LINQ查询来实现这一点。如果不是LINQ,那么简单for循环解决方案也就足够了

PS:-从移动发布此信息。。因此,请原谅错误的格式设置

以下是解决方案:

static public void Main()
{
    // Example of dataset
    List<TransactionInfo> transactionInfos = new List<TransactionInfo>()
    {
        new TransactionInfo(1, "A", "B"),
        new TransactionInfo(2, "A", "C"),
        new TransactionInfo(3, "A", "D"),
        new TransactionInfo(4, "G", "H"),
        new TransactionInfo(5, "C", "M"),
        new TransactionInfo(6, "D", "E"),
        new TransactionInfo(7, "A", "F"),
        new TransactionInfo(8, "H", "L"),
        new TransactionInfo(9, "L", "R"),
        new TransactionInfo(10, "Y", "Z"),
    };

    // Creates the graph and add the arcs
    UndirectedGraph<string> graph = new UndirectedGraph<string>();
    foreach (TransactionInfo transactionInfo in transactionInfos)
        graph.AddArc(transactionInfo.SellerName, transactionInfo.BuyerName);

    var result = (from clusterByNode in graph.GetConnectedComponents()  // Gets the connected components
                  select (from transactionInfo in transactionInfos  // Gets the transaction infos
                          join node in clusterByNode on transactionInfo.BuyerName equals node  // Joins the transactionInfo with the node in the connected component
                          select transactionInfo).ToList()).ToList();
}
以及查找连接组件的类:

public class UndirectedGraph<T>
{
    private Dictionary<T, HashSet<T>> linkedNodes = new Dictionary<T, HashSet<T>>();

    public void AddNode(T node)
    {
        if (!linkedNodes.ContainsKey(node))
            linkedNodes.Add(node, new HashSet<T>());
    }

    public void AddArc(T node1, T node2)
    {
        if (!linkedNodes.ContainsKey(node1))
            linkedNodes.Add(node1, new HashSet<T>());
        linkedNodes[node1].Add(node2);

        if (!linkedNodes.ContainsKey(node2))
            linkedNodes.Add(node2, new HashSet<T>());
        linkedNodes[node2].Add(node1);
    }

    public IEnumerable<HashSet<T>> GetConnectedComponents()
    {
        HashSet<T> visitedNodes = new HashSet<T>();

        foreach (T nodeToVisit in linkedNodes.Keys)
        {
            if (!visitedNodes.Contains(nodeToVisit))
            {
                HashSet<T> connectedComponent = GetConnectedComponent(nodeToVisit);
                visitedNodes.UnionWith(connectedComponent);
                yield return connectedComponent;
            }
        }
    }
    private HashSet<T> GetConnectedComponent(T from)
    {
        HashSet<T> result = new HashSet<T>();

        Stack<T> nodesToVisit = new Stack<T>();
        nodesToVisit.Push(from);
        result.Add(from);

        while (nodesToVisit.Count != 0)
        {
            T nodeToVisit = nodesToVisit.Pop();

            foreach (T linkedNode in linkedNodes[nodeToVisit])
            {
                if (!result.Contains(linkedNode))
                {
                    nodesToVisit.Push(linkedNode);
                    result.Add(linkedNode);
                }
            }
        }

        return result;
    }
}
公共类无向图
{
private Dictionary linkedNodes=新字典();
公共无效添加节点(T节点)
{
if(!linkedNodes.ContainesKey(节点))
Add(node,newhashset());
}
公共无效添加弧(T节点1、T节点2)
{
如果(!linkedNodes.ContainsKey(节点1))
Add(node1,newhashset());
linkedNodes[node1]。添加(node2);
如果(!linkedNodes.ContainsKey(节点2))
Add(node2,newhashset());
linkedNodes[node2]。添加(node1);
}
公共IEnumerable GetConnectedComponents()
{
HashSet visitedNodes=新HashSet();
foreach(linkedNodes.key中的T nodeToVisit)
{
如果(!visitedNodes.Contains(nodeToVisit))
{
HashSet connectedComponent=GetConnectedComponent(nodeToVisit);
visitedNodes.UnionWith(connectedComponent);
收益率返回连接组件;
}
}
}
私有HashSet GetConnectedComponent(T from)
{
HashSet result=新的HashSet();
Stack nodesToVisit=新堆栈();
nodesToVisit.Push(从);
结果。添加(从);
while(nodesToVisit.Count!=0)
{
T nodeToVisit=nodesToVisit.Pop();
foreach(linkedNodes[nodeToVisit]中的T linkedNode)
{
如果(!result.Contains(linkedNode))
{
nodesToVisit.Push(linkedNode);
结果.添加(linkedNode);
}
}
}
返回结果;
}
}

您想要实现的是“找到一个图形的位置”是的,先生,我需要找到连接的组件,然后将它们分组感谢ton bro:)。。我确实想要这个结果集。衷心感谢你。您通过提供以下代码来拯救我的一天:)
public class TransactionInfo
{
    public long TransactionId { get; set; }
    public string BuyerName { get; set; }
    public string SellerName { get; set; }

    public TransactionInfo(long transactionId, string buyerName, string sellerName)
    {
        TransactionId = transactionId;
        BuyerName = buyerName;
        SellerName = sellerName;
    }
}
public class UndirectedGraph<T>
{
    private Dictionary<T, HashSet<T>> linkedNodes = new Dictionary<T, HashSet<T>>();

    public void AddNode(T node)
    {
        if (!linkedNodes.ContainsKey(node))
            linkedNodes.Add(node, new HashSet<T>());
    }

    public void AddArc(T node1, T node2)
    {
        if (!linkedNodes.ContainsKey(node1))
            linkedNodes.Add(node1, new HashSet<T>());
        linkedNodes[node1].Add(node2);

        if (!linkedNodes.ContainsKey(node2))
            linkedNodes.Add(node2, new HashSet<T>());
        linkedNodes[node2].Add(node1);
    }

    public IEnumerable<HashSet<T>> GetConnectedComponents()
    {
        HashSet<T> visitedNodes = new HashSet<T>();

        foreach (T nodeToVisit in linkedNodes.Keys)
        {
            if (!visitedNodes.Contains(nodeToVisit))
            {
                HashSet<T> connectedComponent = GetConnectedComponent(nodeToVisit);
                visitedNodes.UnionWith(connectedComponent);
                yield return connectedComponent;
            }
        }
    }
    private HashSet<T> GetConnectedComponent(T from)
    {
        HashSet<T> result = new HashSet<T>();

        Stack<T> nodesToVisit = new Stack<T>();
        nodesToVisit.Push(from);
        result.Add(from);

        while (nodesToVisit.Count != 0)
        {
            T nodeToVisit = nodesToVisit.Pop();

            foreach (T linkedNode in linkedNodes[nodeToVisit])
            {
                if (!result.Contains(linkedNode))
                {
                    nodesToVisit.Push(linkedNode);
                    result.Add(linkedNode);
                }
            }
        }

        return result;
    }
}