Я пытаюсь написать реализацию на C #алгоритма Брона -Кербоша в теории графов, который используется для поиска клик максимального размера в графах.
В идеале этот алгоритм должен создать список графов, где каждый из этих графов будет представлять максимальную клику из исходного входного графа. Мой код не дает ожидаемого результата, и я был бы признателен за некоторые рекомендации по написанию лучшего кода, который достигает этой реализации.
Класс графа, используемый в этом случае, является пользовательским классом, основанным на представлении графа списком смежности -.
public class BronKerbosch
{
public List> Run(Graph R, Graph P, Graph X, List> maximalCliques)
{
// if P and X are both empty, and the size of R is greater than 1 (implies clique):
if (!P.Nodes.Any() && !X.Nodes.Any() && R.Nodes.Count() > 1)
// report R as a maximal clique
maximalCliques.Add(R);
else
{
// Copy P's nodes for traversal
List> nodesCopy = P.Nodes.ToList();
// For each node v in P:
foreach (GraphNode v in nodesCopy)
{
// Make graph with just v
Graph vGraph = new Graph(new NodeList());
vGraph.AddNode(v);
// Make graph with just v's neighbors
Graph neighborGraph = new Graph(v.Neighbors);
// Move v to X
P.Remove(v.Value);
// BronKerbosch(R U {v}, P INTERSECT N(v), X INTERSECT N(v)))
maximalCliques = Run(R.Union(vGraph), P.Intersect(neighborGraph), X.Intersect(neighborGraph), maximalCliques);
X = X.Union(vGraph);
}
}
return maximalCliques;
}
}
Мы будем очень признательны за любую предоставленную помощь -дайте мне знать, если я могу предоставить какую-либо дополнительную информацию.
--
ОБНОВЛЕНИЕ 1 Одним из контекстов входных и выходных данных является график трех человек -человек A, человек B и человек C. Код приведен ниже для предоставления более точных деталей:
graphR = new Graph(new NodeList());
graphP = new Graph(new NodeList());
graphX = new Graph(new NodeList());
Person personA = new Person() {FirstName = "Person A"};
Person personB = new Person() {FirstName = "Person B"};
Person personC = new Person() {FirstName = "Person C"};
Anode = new GraphNode(personA);
Bnode = new GraphNode(personB);
Cnode = new GraphNode(personC);
graphP.AddNode(Anode);
graphP.AddNode(Bnode);
graphP.AddNode(Cnode);
graphP.AddUndirectedEdge(Anode, Bnode);
graphP.AddUndirectedEdge(Cnode, Anode);
expectedClique1 = new Graph(new NodeList());
expectedClique1.AddNode(Anode);
expectedClique1.AddNode(Bnode);
expectedClique1.AddUndirectedEdge(Anode, Bnode);
expectedClique2 = new Graph(new NodeList());
expectedClique2.AddNode(Cnode);
expectedClique2.AddNode(Anode);
expectedClique2.AddUndirectedEdge(Cnode, Anode);
maximalCliques = new List>();
bronKerbosch = new BronKerbosch();
bronKerbosch.Run(graphR, graphP, graphX, maximalCliques);
В этой ситуации я бы хотел, чтобы на выходе были два графа ожидаемаяClique1 и ожидаемаяClique2 -, однако на самом деле на выходе четыре графа только с personA. Надеюсь это поможет!
--
ОБНОВЛЕНИЕ 2 Похоже, я нашел решение проблемы,хотя я не решаюсь закрыть дело, пока не проведу еще несколько тестов, чтобы подтвердить правильность моего решения. Будет обновлено, когда я смогу подтвердить, что мое решение адекватно.