这是解决方案:
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 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;
}
}