Esempio n. 1
0
        /// <summary>
        /// Algo 1: Find subgraph frequency (mappings found are saved to disk to be retrieved later during Algo 3).
        /// The value of the dictionary returned is in the form: $"{mappings.Count}#{qGraph.Label}.ser"
        /// </summary>
        /// <param name="inputGraph"></param>
        /// <param name="qGraph">The query graph to be searched for. If not available, we use expansion trees (MODA). Otherwise, we use Grochow's (Algo 2)</param>
        /// <param name="subgraphSize"></param>
        /// <param name="thresholdValue">Frequency value, above which we can comsider the subgraph a "frequent subgraph"</param>
        /// <returns></returns>
        public static Dictionary <QueryGraph, string> Algorithm1_C(UndirectedGraph <int> inputGraph, QueryGraph qGraph, int subgraphSize, int thresholdValue)
        {
            // The enumeration module (Algo 3) needs the mappings generated from the previous run(s)
            Dictionary <QueryGraph, string> allMappings;
            int numIterations = -1;

            if (inputGraph.VertexCount < 121)
            {
                numIterations = inputGraph.VertexCount;
            }

            if (qGraph == null) // Use MODA's expansion tree
            {
                #region Use MODA's expansion tree
                var treatedNodes = new HashSet <QueryGraph>();
                allMappings = new Dictionary <QueryGraph, string>(_builder.NumberOfQueryGraphs);
                do
                {
                    qGraph = GetNextNode()?.QueryGraph;
                    if (qGraph == null)
                    {
                        break;
                    }
                    ICollection <Mapping> mappings;
                    if (qGraph.EdgeCount == (subgraphSize - 1)) // i.e. if qGraph is a tree
                    {
                        if (UseModifiedGrochow)
                        {
                            // Modified Mapping module - MODA and Grockow & Kellis
                            mappings = Algorithm2_Modified(qGraph, inputGraph, numIterations, false);
                        }
                        else
                        {
                            var inputGraphClone = inputGraph.Clone();
                            mappings = Algorithm2(qGraph, inputGraphClone, numIterations, false);
                            inputGraphClone.Clear();
                            inputGraphClone = null;
                        }

                        // Because we're saving to file, we're better off doing this now
                        qGraph.RemoveNonApplicableMappings(mappings, inputGraph, false);
                        treatedNodes.Add(qGraph);
                    }
                    else
                    {
                        // Enumeration moodule - MODA
                        // This is part of Algo 3; but performance tweaks makes it more useful to get it here
                        var parentQueryGraph = GetParent(qGraph, _builder.ExpansionTree);
                        if (parentQueryGraph.EdgeCount == (subgraphSize - 1))
                        {
                            treatedNodes.Add(parentQueryGraph);
                        }
                        string _filename;
                        if (allMappings.TryGetValue(parentQueryGraph, out _filename))
                        {
                            string newFileName; // for parentQueryGraph
                            mappings = Algorithm3(null, inputGraph, qGraph, _builder.ExpansionTree, parentQueryGraph, out newFileName, _filename);
                            if (!string.IsNullOrWhiteSpace(newFileName))
                            {
                                // We change the _filename value in the dictionary since this means some of the mappings from parent fit the child
                                allMappings[parentQueryGraph] = newFileName;
                            }
                        }
                        else
                        {
                            mappings = new Mapping[0];
                        }
                    }

                    if (mappings.Count > thresholdValue)
                    {
                        qGraph.IsFrequentSubgraph = true;
                    }

                    // Save mappings.
                    var fileName = qGraph.WriteMappingsToFile(mappings);
                    if (mappings.Count > 0)
                    {
                        mappings.Clear();
                    }
                    allMappings.Add(qGraph, fileName);

                    // Check for complete-ness; if complete, break
                    if (qGraph.IsComplete(subgraphSize))
                    {
                        qGraph = null;
                        break;
                    }
                    qGraph = null;
                }while (true);
                #endregion
            }
            else
            {
                ICollection <Mapping> mappings;
                if (UseModifiedGrochow)
                {
                    // Modified Mapping module - MODA and Grockow & Kellis
                    mappings = Algorithm2_Modified(qGraph, inputGraph, numIterations, true);
                }
                else
                {
                    mappings = Algorithm2(qGraph, inputGraph, numIterations, true);
                }
                qGraph.RemoveNonApplicableMappings(mappings, inputGraph);
                var fileName = $"{mappings.Count}#{qGraph.Identifier}.ser";
                System.IO.File.WriteAllText(fileName, Extensions.CompressString(Newtonsoft.Json.JsonConvert.SerializeObject(mappings)));
                if (mappings.Count > 0)
                {
                    mappings.Clear();
                }
                allMappings = new Dictionary <QueryGraph, string>(1)
                {
                    { qGraph, fileName }
                };
            }

            return(allMappings);
        }
Esempio n. 2
0
        /// <summary>
        /// Algo 1: Find subgraph frequency (mappings help in memory)
        /// </summary>
        /// <param name="inputGraph"></param>
        /// <param name="qGraph">The query graph to be searched for. If not available, we use expansion trees (MODA). Otherwise, we use Grochow's (Algo 2)</param>
        /// <param name="subgraphSize"></param>
        /// <param name="thresholdValue">Frequency value, above which we can comsider the subgraph a "frequent subgraph"</param>
        /// <returns></returns>
        public static Dictionary <QueryGraph, ICollection <Mapping> > Algorithm1(UndirectedGraph <int> inputGraph, QueryGraph qGraph, int subgraphSize = -1, int thresholdValue = 0)
        {
            // The enumeration module (Algo 3) needs the mappings generated from the previous run(s)
            Dictionary <QueryGraph, ICollection <Mapping> > allMappings;
            int numIterations = -1;

            if (inputGraph.VertexCount < 121)
            {
                numIterations = inputGraph.VertexCount;
            }

            if (qGraph == null) // Use MODA's expansion tree
            {
                #region Use MODA's expansion tree
                var treatedNodes = new HashSet <QueryGraph>();
                allMappings = new Dictionary <QueryGraph, ICollection <Mapping> >(_builder.NumberOfQueryGraphs);
                do
                {
                    qGraph = GetNextNode()?.QueryGraph;
                    if (qGraph == null)
                    {
                        break;
                    }
                    ICollection <Mapping> mappings;
                    if (qGraph.IsTree(subgraphSize))
                    {
                        if (UseModifiedGrochow)
                        {
                            // Modified Mapping module - MODA and Grockow & Kellis
                            mappings = Algorithm2_Modified(qGraph, inputGraph, numIterations, false);
                        }
                        else
                        {
                            // Mapping module - MODA and Grockow & Kellis.
                            var inputGraphClone = inputGraph.Clone();
                            mappings = Algorithm2(qGraph, inputGraphClone, numIterations, false);
                            inputGraphClone.Clear();
                            inputGraphClone = null;
                        }
                    }
                    else
                    {
                        // Enumeration moodule - MODA
                        // This is part of Algo 3; but performance tweaks makes it more useful to get it here
                        var parentQueryGraph = GetParent(qGraph, _builder.ExpansionTree);
                        if (parentQueryGraph.IsTree(subgraphSize))
                        {
                            treatedNodes.Add(parentQueryGraph);
                        }
                        string file;
                        mappings = Algorithm3(allMappings, inputGraph, qGraph, _builder.ExpansionTree, parentQueryGraph, out file);
                    }
                    if (mappings != null && mappings.Count > thresholdValue)
                    {
                        qGraph.IsFrequentSubgraph = true;
                    }
                    // Save mappings. Do we need to save to disk? Maybe not!

                    allMappings.Add(qGraph, mappings);
                    // Do not call mappings.Clear()
                    mappings = null;
                    // Check for complete-ness; if complete, break
                    if (qGraph.IsComplete(subgraphSize))
                    {
                        qGraph = null;
                        break;
                    }
                    qGraph = null;
                }while (true);

                if (treatedNodes.Count > 0)
                {
                    foreach (var mapping in allMappings)
                    {
                        if (mapping.Key.IsTree(subgraphSize) && !treatedNodes.Contains(mapping.Key))
                        {
                            mapping.Key.RemoveNonApplicableMappings(mapping.Value, inputGraph);
                        }
                    }
                    treatedNodes.Clear();
                }
                treatedNodes = null;
                #endregion
            }
            else
            {
                ICollection <Mapping> mappings;
                if (UseModifiedGrochow)
                {
                    // Modified Mapping module - MODA and Grockow & Kellis
                    mappings = Algorithm2_Modified(qGraph, inputGraph, numIterations, true);
                    // mappings = ModaAlgorithm2Parallelized.Algorithm2_Modified(qGraph, inputGraph, numIterations);
                }
                else
                {
                    mappings = Algorithm2(qGraph, inputGraph, numIterations, true);
                }

                qGraph.RemoveNonApplicableMappings(mappings, inputGraph);
                allMappings = new Dictionary <QueryGraph, ICollection <Mapping> >(1)
                {
                    { qGraph, mappings }
                };

                // Do not call mappings.Clear()
                mappings = null;
            }

            return(allMappings);
        }