コード例 #1
0
        private static void SolveWithHeuristic(WeightedGraph graph)
        {
            int        currentAnswerWeight = 0;
            int        candidateWeight     = 0;
            List <int> answer = new List <int> ();

            _stopwatch.Start();
            foreach (int v in graph.Vertices.Keys)
            {
                candidateWeight = 0;

                // Select all neighbors
                List <int> neighbors       = Neighbors(v, graph);
                List <int> cliqueCandidate = new List <int> ();

                // Start the candidate clique with the current vertex
                cliqueCandidate.Add(v);

                // Sort neighbors by combined Weight and degree
                List <KeyValuePair <int, int> > neighborsByWeightPlus = SortNeighbors(v, neighbors, graph, "weight+");

                // For each neighbor check if it makes a clique with the candidate
                foreach (var neighbor in neighborsByWeightPlus)
                {
                    bool makeClique = true;
                    foreach (int vCand in cliqueCandidate)
                    {
                        // Check for maxTime
                        if (_stopwatch.Elapsed >= _maxRunTime)
                        {
                            Log("Abort! Max Run Time exceeded!");
                            break;
                        }

                        if (!graph.Edges[vCand].Contains(neighbor.Key))
                        {
                            makeClique = false;
                            break;
                        }
                    }

                    if (makeClique)
                    {
                        cliqueCandidate.Add(neighbor.Key);
                    }

                    // Check for maxTime
                    if (_stopwatch.Elapsed >= _maxRunTime)
                    {
                        Log("Abort! Max Run Time exceeded!");
                        break;
                    }
                }

                // Check if the new candidate is better than the current best answer
                candidateWeight = 0;
                cliqueCandidate.ForEach(c => candidateWeight += graph.Vertices[c]);
                Log(String.Format("current weight: {0}", currentAnswerWeight));
                Log(String.Format("candidate weight: {0}", candidateWeight));
                Log("================================================");
                if (candidateWeight < currentAnswerWeight)
                {
                    continue;
                }
                else
                {
                    currentAnswerWeight = candidateWeight;
                    answer.Clear();
                    answer.AddRange(cliqueCandidate);
                }

                // Check for maxTime
                if (_stopwatch.Elapsed >= _maxRunTime)
                {
                    Log("Abort! Max Run Time exceeded!");
                    break;
                }
            }
            TimeSpan      timeElapsed  = _stopwatch.Elapsed;
            List <string> answerLabels = new List <string> ();

            answer.ForEach(v => answerLabels.Add(graph.VertexIndexMap[v]));
            Log(String.Format("Max Clique: [{0}]", String.Join(", ", answerLabels)));
            Log(String.Format("Max Clique Weight: {0}", currentAnswerWeight));
            using (StreamWriter sw = new StreamWriter(_graphInstancePath.Replace(".txt", "out.csv"), append: true))
            {
                sw.WriteLine(String.Format("{0}\t{1}\t{2}", timeElapsed.ToString(), _graphInstancePath, currentAnswerWeight));
            }
        }
コード例 #2
0
        private static bool BronKerbosch(List <int> R, List <int> P, List <int> X, WeightedGraph graph, ref List <int> answer)
        {
            _backtrackCallCount++;
            //Log ("======================================================");
            //Log (String.Format ("R: [{0}]", String.Join(", ", R)));
            //Log (String.Format ("P: [{0}]", String.Join(", ", P)));
            //Log (String.Format ("X: [{0}]", String.Join(", ", X)));

            int currentCliqueWeight     = 0;
            int possibleMaxCliqueWeight = 0;
            int candidateCliqueWeight   = 0;

            if (_optimizeBacktrack)
            {
                // Check if we can increase the max clique with the current set
                possibleMaxCliqueWeight = 0;
                foreach (int vPos in R.Union(P))
                {
                    possibleMaxCliqueWeight += graph.Vertices[vPos];
                }
                // calculate weight of maximal clique
                currentCliqueWeight = 0;
                foreach (int vAns in answer)
                {
                    currentCliqueWeight += graph.Vertices[vAns];
                }
                //Log (String.Format ("Possible Max Weight: {0}", possibleMaxCliqueWeight));
                //Log (String.Format ("Current Weight: {0}", currentCliqueWeight));
                if (possibleMaxCliqueWeight < currentCliqueWeight)
                {
                    return(false);
                }
            }

            //if P and X are both empty:
            if (P.Count == 0 && X.Count == 0)
            {
                //report R as a maximal clique
                return(true);
            }

            int[] auxP = new int[P.Count];
            P.CopyTo(auxP);
            List <int> auxPList = auxP.ToList();

            //for each vertex v in P:
            foreach (int v in P)
            {
                // Check for maxTime
                if (_stopwatch.Elapsed >= _maxRunTime)
                {
                    Log("Abort! Max Run Time exceeded!");
                    return(false);
                }

                List <int> Nv = Neighbors(v, graph);

                //BronKerbosch1(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
                if (BronKerbosch(R.Union(new List <int> {
                    v
                }).ToList(), auxPList.Intersect(Nv).ToList(), X.Intersect(Nv).ToList(), graph, ref answer))
                {
                    // calculate weight of maximal clique
                    currentCliqueWeight = 0;
                    foreach (int vAns in answer)
                    {
                        currentCliqueWeight += graph.Vertices[vAns];
                    }

                    Log(String.Format("current weight: {0}", currentCliqueWeight));

                    candidateCliqueWeight = 0;
                    foreach (int vCand in R.Union(new List <int> {
                        v
                    }).ToList())
                    {
                        candidateCliqueWeight += graph.Vertices[vCand];
                    }
                    Log(String.Format("candidate weight: {0}", candidateCliqueWeight));

                    // Save heaviest clique as answer
                    if (candidateCliqueWeight > currentCliqueWeight)
                    {
                        answer = R.Union(new List <int> {
                            v
                        }).ToList();
                        Log(String.Format("Candidate is the new max clique! Weight: {0}. Clique: [{1}]", candidateCliqueWeight, String.Join(", ", answer)));
                    }

                    Log("================================================");
                }

                //P := P \ {v}
                auxPList.Remove(v);
                //X := X ⋃ {v}
                X = X.Union(new List <int> {
                    v
                }).ToList();
            }

            return(false);
        }
コード例 #3
0
 private static List <int> Neighbors(int v, WeightedGraph graph)
 {
     return(graph.Edges[v].ToList());
 }
コード例 #4
0
        private static List <KeyValuePair <int, int> > SortNeighbors(int v, List <int> neighbors, WeightedGraph graph, string mode)
        {
            List <KeyValuePair <int, int> > sortedList = new List <KeyValuePair <int, int> >();

            switch (mode)
            {
            case "weight":
                foreach (int neighbor in neighbors)
                {
                    sortedList.Add(new KeyValuePair <int, int> (neighbor, graph.Vertices[neighbor]));
                }
                break;

            case "degree":
                foreach (int neighbor in neighbors)
                {
                    sortedList.Add(new KeyValuePair <int, int> (neighbor, graph.Edges[neighbor].Count));
                }
                break;

            case "weight+":
                foreach (int neighbor in neighbors)
                {
                    sortedList.Add(new KeyValuePair <int, int> (neighbor, CalculateVertexCumulateWeight(neighbor, graph) - graph.Vertices[v] + graph.Vertices[neighbor]));
                }
                break;
            }

            sortedList.Sort((pair1, pair2) => pair2.Value.CompareTo(pair1.Value));

            return(sortedList);
        }