Пример #1
0
 private static void Visit(UndirectedGraph graph, IReporter reporter,
                           ISet <Vertex> candidates, ISet <Vertex> excluded, ImmutableArray <Vertex> cliqueInProgress)
 {
     Debug.Assert(candidates.All(v => graph.Degree(v) > 0));
     Debug.Assert(excluded.All(v => graph.Degree(v) > 0));
     Debug.Assert(!candidates.Overlaps(excluded));
     Debug.Assert(candidates.Any());
     while (candidates.Any())
     {
         var v                      = CollectionsUtil.PopArbitrary(candidates);
         var neighbours             = graph.Neighbours(v);
         var neighbouringCandidates = CollectionsUtil.Intersection(candidates, neighbours);
         if (neighbouringCandidates.Any())
         {
             var neighbouringExcluded = CollectionsUtil.Intersection(excluded, neighbours);
             Visit(graph, reporter,
                   neighbouringCandidates, neighbouringExcluded,
                   CollectionsUtil.Append(cliqueInProgress, v));
         }
         else if (CollectionsUtil.AreDisjoint(excluded, neighbours))
         {
             reporter.Record(CollectionsUtil.Append(cliqueInProgress, v));
         }
         var added = excluded.Add(v);
         Debug.Assert(added);
     }
 }
Пример #2
0
        public void AreDisjoint()
        {
            var empty = new HashSet <int> {
            };
            var one   = new HashSet <int> {
                1
            };
            var two = new HashSet <int> {
                1, 2
            };
            var six = new HashSet <int> {
                0, 1, 2, 3, 4, 5
            };

            Assert.That(CollectionsUtil.AreDisjoint(empty, one));
            Assert.That(CollectionsUtil.AreDisjoint(one, empty));
            Assert.That(CollectionsUtil.AreDisjoint(empty, two));
            Assert.That(CollectionsUtil.AreDisjoint(two, empty));
            Assert.That(CollectionsUtil.AreDisjoint(empty, six));
            Assert.That(CollectionsUtil.AreDisjoint(six, empty));
            Assert.That(!CollectionsUtil.AreDisjoint(one, two));
            Assert.That(!CollectionsUtil.AreDisjoint(two, one));
            Assert.That(!CollectionsUtil.AreDisjoint(one, six));
            Assert.That(!CollectionsUtil.AreDisjoint(six, one));
            Assert.That(!CollectionsUtil.AreDisjoint(two, six));
            Assert.That(!CollectionsUtil.AreDisjoint(six, two));
            Assert.That(!CollectionsUtil.AreDisjoint(one, one));
            Assert.That(!CollectionsUtil.AreDisjoint(two, two));
            Assert.That(!CollectionsUtil.AreDisjoint(six, six));
        }
Пример #3
0
    public static void Explore(UndirectedGraph graph, IReporter finalReporter)
    {
        var scheduler = TaskScheduler.Default;
        int sent      = 0;
        int received  = 0;

        // Step 3: collect results.
        var collect = new ActionBlock <ImmutableArray <Vertex> >(clique => finalReporter.Record(clique));

        // Step 2: visit vertices.
        var reporter  = new NestedReporter(collect);
        int waitgroup = 1;

        void completion(Task _)
        {
            if (Interlocked.Decrement(ref waitgroup) == 0)
            {
                reporter.Close();
                collect.Complete();
            }
        }

        var excluded = new HashSet <Vertex>();
        var visit    = new ActionBlock <Vertex>(v =>
        {
            var neighbours = graph.Neighbours(v);
            Debug.Assert(neighbours.Any());
            var neighbouringCandidates = CollectionsUtil.Difference(neighbours, excluded);
            if (neighbouringCandidates.Any())
            {
                var neighbouringExcluded = CollectionsUtil.Intersection(excluded, neighbours);
                _ = Interlocked.Increment(ref waitgroup);
                _ = Task.Run(delegate
                {
                    Pivot.Visit(graph, reporter, Pivot.Choice.MaxDegreeLocal,
                                neighbouringCandidates, neighbouringExcluded,
                                ImmutableArray.Create(v));
                }).ContinueWith(completion, scheduler);
            }
            else
            {
                Debug.Assert(!CollectionsUtil.AreDisjoint(neighbours, excluded));
            }
            var added = excluded.Add(v);
            Debug.Assert(added);
            ++received;
        });

        _ = visit.Completion.ContinueWith(completion, scheduler);

        // Step 1: feed vertices in order.
        _ = Task.Run(delegate
        {
            foreach (var v in Degeneracy.Ordering(graph, drop: 1))
            {
                while (!visit.Post(v))
                {
                    throw new InvalidOperationException("Post failed");
                }
                ++sent;
            }
            visit.Complete();
        });

        collect.Completion.Wait();
        if (sent != received)
        {
            throw new InvalidOperationException($"{sent} sent <> {received} received");
        }
    }