解決策は次のとおりです。
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;
}
}