Пример #1
0
        private void clear()
        {
            var comparer1 = EqualityComparer <TLabel> .Default;
            var comparer2 = new Utils.HashSetEqualityComparer <Tuple <TLabel, int> >();
            var comparer  = new Utils.PairEqualityComparer <TLabel, HashSet <Tuple <TLabel, int> > >(comparer1, comparer2);

            partition    = new Dictionary <TNode, int>();
            partitionMap = new Dictionary <Tuple <TLabel, HashSet <Tuple <TLabel, int> > >, int>(comparer);
            int counter = 0;

            foreach (var node in graph.Nodes)
            {
                if (owner[node] == this)
                {
                    var signature = Tuple.Create(graph.NodeLabel(node), new HashSet <Tuple <TLabel, int> >());

                    if (!partitionMap.ContainsKey(signature))
                    {
                        partitionMap.Add(signature, counter++);
                    }

                    partition.Add(node, partitionMap[signature]);
                }
            }
        }
        /// <summary>
        /// Partition a directed graph's nodes based on (bounded) k-bisimulation equivalence.
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        public IDictionary <TNode, int> BoundedExactBisimulationReduction(int k)
        {
            var partitions = new Dictionary <TNode, int> [k + 1];

            stopwatch.Reset();
            stopwatch.Start();
            {
                // Partition block counter (for uniqueness)
                int counter  = 0;
                var comparer = new Utils.HashSetEqualityComparer <Tuple <TLabel, int> >();

                // Base (k = 0)
                // Create a partition based solely on the labels of the nodes
                partitions[0] = new Dictionary <TNode, int>();
                var labelIds = new Dictionary <TLabel, int>();
                foreach (var label in graph.NodeLabels)
                {
                    labelIds.Add(label, counter++);
                }

                // Assign block to each node
                foreach (var node in graph.Nodes)
                {
                    partitions[0].Add(node, labelIds[graph.NodeLabel(node)]);
                }

                // Store the signatures and the block identifier associated with them
                var signatures = new Dictionary <TLabel, Dictionary <HashSet <Tuple <TLabel, int> >, int> >();
                foreach (var label in graph.NodeLabels)
                {
                    signatures.Add(label, null);
                }

                // Step (k > 0)
                for (int i = 1; i <= k; i++)
                {
                    // Initialize partition
                    partitions[i] = new Dictionary <TNode, int>();

                    // Initialize each entry in the signature storage
                    foreach (var label in graph.NodeLabels)
                    {
                        // Use custom hash set for faster equivalence determination
                        signatures[label] = new Dictionary <HashSet <Tuple <TLabel, int> >, int>(comparer);
                    }

                    foreach (var u in graph.Nodes)
                    {
                        // Label of node
                        var label = graph.NodeLabel(u);

                        // Compute signature (without label) of node u
                        // This is the set of tuples (label(u, v), partition_i-1(v)) for every edge (u, v)
                        var S = new HashSet <Tuple <TLabel, int> >();
                        foreach (var eo in graph.Out(u))
                        {
                            var v = graph.Target(eo);
                            var t = Tuple.Create(graph.EdgeLabel(eo), partitions[i - 1][v]);
                            if (!S.Contains(t))
                            {
                                S.Add(t);
                            }
                        }

                        // Check if signature exists and create a new block if it does not
                        if (!signatures[label].ContainsKey(S))
                        {
                            signatures[label].Add(S, counter++);
                        }

                        // Set block of node u
                        partitions[i].Add(u, signatures[label][S]);
                    }
                }
            }
            stopwatch.Stop();

            return(partitions[k]);
        }
Пример #3
0
        protected override void OnReceive(AbstractMessage message)
        {
            TypeSwitch.On(message)
            .Case((CoordinatorMessage coordinatorMessage) =>
            {
                k_max        = 0;
                partition    = new Dictionary <TNode, int>();
                oldNumBlocks = 0;
                blocks       = new HashSet <int>();
                workers      = coordinatorMessage.Workers;
                state        = new Dictionary <AbstractMachine, WorkerState>();

                var comparer1 = EqualityComparer <TLabel> .Default;
                var comparer2 = new Utils.HashSetEqualityComparer <Tuple <TLabel, int> >();
                var comparer  = new Utils.PairEqualityComparer <TLabel, HashSet <Tuple <TLabel, int> > >(comparer1, comparer2);
                signatures    = new Dictionary <Tuple <TLabel, HashSet <Tuple <TLabel, int> > >, int>(comparer);
                counter       = 0;

                foreach (var worker in workers)
                {
                    state.Add(worker, WorkerState.Refining);
                    worker.SendMe(new ClearMessage(this));
                }
            })
            .Case((ExactRefinedMessage <TLabel> refinedMessage) =>
            {
                state[refinedMessage.Sender] = WorkerState.Waiting;

                var remap = new Dictionary <int, int>();
                foreach (var kvp in refinedMessage.PartitionMap)
                {
                    if (!signatures.ContainsKey(kvp.Key))
                    {
                        signatures.Add(kvp.Key, counter++);
                    }

                    remap.Add(kvp.Value, signatures[kvp.Key]);
                }

                refinedMessage.Sender.SendMe(new RemapPartitionMessage(this, remap));

                if (workers.All(worker => state[worker] == WorkerState.Waiting))
                {
                    signatures.Clear();

                    // All workers have refined, now perform a share step
                    foreach (var worker in workers)
                    {
                        state[worker] = WorkerState.Sharing;
                        worker.SendMe(new ShareMessage(this));
                    }
                }
            })
            .Case((SharedMessage sharedMessage) =>
            {
                state[sharedMessage.Sender] = WorkerState.Waiting;

                if (workers.All(worker => state[worker] == WorkerState.Waiting))
                {
                    // All workers have shared, now count the number of unqiue blocks
                    oldNumBlocks = blocks.Count;
                    blocks.Clear();
                    foreach (var worker in workers)
                    {
                        state[worker] = WorkerState.Counting;
                        worker.SendMe(new CountMessage(this));
                    }
                }
            })
            .Case((CountedMessage countedMessage) =>
            {
                state[countedMessage.Sender] = WorkerState.Waiting;
                blocks.UnionWith(countedMessage.Blocks);

                if (workers.All(worker => state[worker] == WorkerState.Waiting))
                {
                    if (blocks.Count > oldNumBlocks)
                    {
                        // There was a change, continue refining
                        k_max += 1;
                        foreach (var worker in workers)
                        {
                            state[worker] = WorkerState.Refining;
                            worker.SendMe(new RefineMessage(this));
                        }
                    }
                    else
                    {
                        // We're done, collect global partition
                        k_max -= 1;
                        foreach (var worker in workers)
                        {
                            state[worker] = WorkerState.Collecting;
                            worker.SendMe(new SegmentRequestMessage(this));
                        }
                    }
                }
            })
            .Case((SegmentResponseMessage <TNode> segmentResponseMessage) =>
            {
                state[segmentResponseMessage.Sender] = WorkerState.Waiting;

                foreach (var pair in segmentResponseMessage.Pairs)
                {
                    partition.Add(pair.Key, pair.Value);
                }

                if (workers.All(worker => state[worker] == WorkerState.Waiting))
                {
                    onComplete(k_max, partition);
                }
            });
        }