//Because of the definition of patterns, result is not null.
        public List <List <int> > GetCandidatesForeachVertex(Graph pattern)
        {
            List <List <int> > ret = new List <List <int> >();

            for (int i = 0; i < pattern._vertexes.Length; i++)
            {
                List <int> vCand = null;
                Vertex     v     = pattern._vertexes[i];
                foreach (int vlid in v._vLabel)
                {
                    Step       entry = new Step(vlid, StepType.Nlabel);
                    List <int> cand;
                    _index.TryGetValue(entry, out cand);
                    if (cand != null)
                    {
                        if (vCand == null)
                        {
                            vCand = cand;
                        }
                        else
                        {
                            vCand = Tools.MergeSortedArray(vCand, cand);
                        }
                    }
                }

                foreach (int eid in v._outEdge)
                {
                    Edge       e     = pattern._edges[eid];
                    Step       entry = new Step(e._eLabel, StepType.Forward);
                    List <int> cand;
                    _index.TryGetValue(entry, out cand);
                    if (cand != null)
                    {
                        if (vCand == null)
                        {
                            vCand = cand;
                        }
                        else
                        {
                            vCand = Tools.MergeSortedArray(vCand, cand);
                        }
                    }
                }

                foreach (int eid in v._inEdge)
                {
                    Edge       e     = pattern._edges[eid];
                    Step       entry = new Step(e._eLabel, StepType.Backward);
                    List <int> cand;
                    _index.TryGetValue(entry, out cand);
                    if (cand != null)
                    {
                        if (vCand == null)
                        {
                            vCand = cand;
                        }
                        else
                        {
                            vCand = Tools.MergeSortedArray(vCand, cand);
                        }
                    }
                }

                ret.Add(vCand);
            }
            return(ret);
        }
        bool recursiveSearch()
        {
            if (_depth == _pattern._vertexes.Length)
            {
                if (_enumerateSubgraphs)
                {
                    _DoSomething(_pattern, g2, _vMap, _arg).ForEach(e => _rets.Add(e));
                }
                return(true);
            }

            HashSet <int> cand = null;

            foreach (Edge e in _pattern._edges)
            {
                HashSet <int> ccand = new HashSet <int>();
                if (e._from == _depth && e._to < _depth)
                {
                    int    vconsid = _vMap[e._to];
                    Vertex v       = g2._vertexes[vconsid];
                    foreach (int eid in v._inEdge)
                    {
                        Edge eg = g2._edges[eid];
                        if (eg._eLabel == e._eLabel && !_vMap.Contains(eg._from))
                        {
                            ccand.Add(eg._from);
                        }
                    }
                }
                else if (e._to == _depth && e._from < _depth)
                {
                    int    vconsid = _vMap[e._from];
                    Vertex v       = g2._vertexes[vconsid];
                    foreach (int eid in v._outEdge)
                    {
                        Edge eg = g2._edges[eid];
                        if (eg._eLabel == e._eLabel && !_vMap.Contains(eg._to))
                        {
                            ccand.Add(eg._to);
                        }
                    }
                }
                else
                {
                    continue;
                }
                if (cand == null)
                {
                    cand = ccand;
                }
                else
                {
                    cand.IntersectWith(ccand);
                }
                if (cand.Count == 0)
                {
                    return(false);
                }
            }

            /*
             * if (_cands == null && _pattern._vertexes[_depth]._vLabel.Length != 0)
             * {
             *  cand = new HashSet<int>();
             *  int[] tempCand = null;
             *  _g._vertexLabelIndex.TryGetValue(_pattern._vertexes[_depth]._vLabel[0], out tempCand);
             *  if (tempCand != null)
             *      cand.UnionWith(tempCand);
             *  for (int i = 1; i < _pattern._vertexes[_depth]._vLabel.Length; i++)
             *  {
             *      _g._vertexLabelIndex.TryGetValue(_pattern._vertexes[_depth]._vLabel[i], out tempCand);
             *      if (tempCand != null)
             *          cand.IntersectWith(tempCand);
             *  }
             * }
             *
             * if (cand != null && cand.Count == 0)
             *  return false;
             * //?
             * //inefficient
             * if (_cands != null && _cands[_depth]!=null)
             *  cand.IntersectWith(_cands[_depth]);
             */
            if (cand == null)
            {
                cand = new HashSet <int>();
                if (_cands == null || _cands[_depth] == null)
                {
                    for (int i = 0; i < g2._vertexes.Length; i++)
                    {
                        cand.Add(i);
                    }
                }
                else
                {
                    cand.UnionWith(_cands[_depth]);
                }
                for (int i = 0; i < _depth; i++)
                {
                    cand.Remove(_vMap[i]);
                }
            }

            foreach (int tryvid in cand)
            {
                bool flag = true;
                foreach (int vlid in _pattern._vertexes[_depth]._vLabel)
                {
                    if (!g2._vertexes[tryvid]._vLabel.Contains(vlid))
                    {
                        flag = false;
                        break;
                    }
                }
                if (!flag)
                {
                    continue;
                }

                _vMap[_depth] = tryvid;
                _depth++;
                if (_enumerateSubgraphs)
                {
                    recursiveSearch();
                }
                else
                {
                    if (recursiveSearch())
                    {
                        return(true);
                    }
                }
                _depth--;
                _vMap[_depth] = -1;
            }
            return(false);
        }
        List <IndexedGraph> JoinGraphPair(Graph g1, IndexedGraph g2)
        {
            int i;
            List <IndexedGraph> ret = new List <IndexedGraph>();

            Vertex[] newVertex = new Vertex[g2._vertexes.Length + 1],
            originalVertex = g2._vertexes;
            originalVertex.CopyTo(newVertex, 0);
            newVertex[newVertex.Length - 1] = new Vertex();
            g2._vertexes = newVertex;

            for (int j = 0; j < g1._vertexes.Length; j++)
            {
                Vertex v = g1._vertexes[j];
                if (v._vLabel.Length == 0)
                {
                    continue;
                }
                int[] restLabels = new int[v._vLabel.Length - 1],
                originalLabels = v._vLabel;
                v._vLabel      = restLabels;
                for (i = 0; i < restLabels.Length; i++)
                {
                    restLabels[i] = originalLabels[i + 1];
                }

                for (i = 0; i < originalLabels.Length; i++)
                {
                    if (i >= 1)
                    {
                        restLabels[i - 1] = originalLabels[i - 1];
                    }
                    VLabel vlabel = new VLabel();
                    vlabel._vid = j; vlabel._vlid = originalLabels[i];

                    ret.AddRange(GetAllJoins(g1, g2, vlabel));
                }
                v._vLabel = originalLabels;
            }

            if (g1._edges.Length > 0)
            {
                Edge[] restEdges = new Edge[g1._edges.Length - 1],
                originalEdges = g1._edges;
                g1._edges     = restEdges;
                for (i = 0; i < restEdges.Length; i++)
                {
                    restEdges[i] = originalEdges[i];
                }
                Edge   laste  = originalEdges[originalEdges.Length - 1];
                Vertex lastv1 = g1._vertexes[laste._from],
                       lastv2 = g1._vertexes[laste._to];
                for (int j = 0; j < originalEdges.Length; j++)
                {
                    if (j < originalEdges.Length - 1)
                    {
                        restEdges[j] = originalEdges[originalEdges.Length - 1];
                    }
                    Edge e = originalEdges[j];

                    Vertex v1 = g1._vertexes[e._from],
                           v2 = g1._vertexes[e._to];

                    int[] restOutEdge = new int[v1._outEdge.Length - 1],
                    restInEdge      = new int[v2._inEdge.Length - 1],
                    originalOutEdge = v1._outEdge,
                    originalInEdge  = v2._inEdge;

                    i = 0;
                    foreach (int eid in originalOutEdge)
                    {
                        if (eid != j)
                        {
                            restOutEdge[i++] = eid;
                        }
                    }
                    v1._outEdge = restOutEdge;
                    i           = 0;
                    foreach (int eid in originalInEdge)
                    {
                        if (eid != j)
                        {
                            restInEdge[i++] = eid;
                        }
                    }
                    v2._inEdge = restInEdge;

                    int[] restOutEdgeLast, restInEdgeLast,
                    originalOutEdgeLast = lastv1._outEdge,
                    originalInEdgeLast  = lastv2._inEdge;

                    if (j < originalEdges.Length - 1)
                    {
                        restOutEdgeLast = new int[lastv1._outEdge.Length];
                        restInEdgeLast  = new int[lastv2._inEdge.Length];

                        for (i = 0; i < lastv1._outEdge.Length; i++)
                        {
                            if (lastv1._outEdge[i] == originalEdges.Length - 1)
                            {
                                restOutEdgeLast[i] = j;
                            }
                            else
                            {
                                restOutEdgeLast[i] = lastv1._outEdge[i];
                            }
                        }
                        lastv1._outEdge = restOutEdgeLast;
                        for (i = 0; i < lastv2._inEdge.Length; i++)
                        {
                            if (lastv2._inEdge[i] == originalEdges.Length - 1)
                            {
                                restInEdgeLast[i] = j;
                            }
                            else
                            {
                                restInEdgeLast[i] = lastv2._inEdge[i];
                            }
                        }
                        lastv2._inEdge = restInEdgeLast;
                    }

                    ret.AddRange(GetAllJoins(g1, g2, e));

                    if (j < originalEdges.Length - 1)
                    {
                        restEdges[j]    = originalEdges[j];
                        lastv1._outEdge = originalOutEdgeLast;
                        lastv2._inEdge  = originalInEdgeLast;
                    }
                    v1._outEdge = originalOutEdge;
                    v2._inEdge  = originalInEdge;
                }
                g1._edges = originalEdges;
            }

            g2._vertexes = originalVertex;

            for (i = 0; i < ret.Count; i++)
            {
                Graph g = ret[i];
                if (g._vertexes[g._vertexes.Length - 1].Isolated())
                {
                    Vertex[] newV = new Vertex[g._vertexes.Length - 1];
                    for (int j = 0; j < newV.Length; j++)
                    {
                        newV[j] = g._vertexes[j];
                    }
                    g._vertexes = newV;
                }
            }
            return(ret);
        }
        public List <Tuple <IndexedGraph, List <int> > > MineEgonet(int minSupp, int maxSize, int maxRadius, int[] constraintVSet)
        {
            //bool useVIDList = false;

            List <int> constraintVSetList = constraintVSet.ToList();

            DateTime begin = DateTime.Now;

            //FrequentPathMining fpm = new FrequentPathMiningDepth();
            FrequentPathMining fpm = new FrequentPathMiningBreadth();

            fpm.Init(_g, minSupp, maxSize, constraintVSet, true, maxRadius);
            //fpm.Init(_g, minSupp, maxSize);

            Console.WriteLine("{0} seconds. {1} path results.",
                              (DateTime.Now - begin).TotalSeconds,
                              fpm._resultCache.Count);


            List <Tuple <IndexedGraph, List <int> > > ret = new List <Tuple <IndexedGraph, List <int> > >();

            Console.WriteLine("Adding {0} paths.", fpm.GetPathAndVID(1).Count);
            List <Tuple <IndexedGraph, List <int> > > lastResults = fpm.GetPathAndVID(1);

            ret.AddRange(fpm.GetPathAndVID(1));

            //IndexedGraph z = new IndexedGraph();
            //z.Read(@"E:\RkNPQ\1.txt");
            //SubGraphTest sgt1 = new SubGraphTest();

            for (int size = 2; size <= maxSize; size++)
            {
                begin = DateTime.Now;
                Console.WriteLine("Computing Size-{0} Candidate Patterns.", size);
                List <Tuple <IndexedGraph, List <int> > > tempResults = new List <Tuple <IndexedGraph, List <int> > >();

                for (int i = 0; i < lastResults.Count; i++)
                {
                    for (int j = i; j < lastResults.Count; j++)
                    {
                        List <IndexedGraph> newPatterns = null;
                        List <int>          vids        = null;
                        if (j == i)
                        {
                            Graph tempG = lastResults[i].Item1.ShallowCopy();
                            newPatterns = JoinGraphPair(tempG, lastResults[i].Item1);
                            vids        = lastResults[i].Item2;
                        }
                        else
                        {
                            vids = Tools.MergeSortedArray(lastResults[i].Item2, lastResults[j].Item2);
                            if (vids.Count < minSupp)
                            {
                                continue;
                            }
                            newPatterns = JoinGraphPair(lastResults[i].Item1, lastResults[j].Item1);
                        }
                        foreach (IndexedGraph pattern in newPatterns)
                        {
                            //if (sgt1.MatchNeighborhood(z, pattern, 0))
                            //{
                            //    Console.WriteLine();
                            //}
                            bool hasDup = false;
                            foreach (var pair in tempResults)
                            {
                                if (_subGTester.MatchNeighborhood(pattern, pair.Item1, 0))
                                {
                                    hasDup = true;
                                    break;
                                }
                            }
                            if (!hasDup)
                            {
                                tempResults.Add(new Tuple <IndexedGraph, List <int> >(pattern, vids));
                            }
                        }
                    }
                }
                Console.WriteLine("{0} seconds. {1} candidates.",
                                  (DateTime.Now - begin).TotalSeconds,
                                  tempResults.Count);
                begin = DateTime.Now;
                Console.WriteLine("Validating Size-{0} Candidate Patterns.", size);

                //Compute Zipper Patterns
                List <Tuple <IndexedGraph, List <int> > > zipperPatterns = new List <Tuple <IndexedGraph, List <int> > >();
                if (size > maxRadius + 1 && size <= 2 * maxRadius + 1)
                {
                    SubGraphTest sgt = new SubGraphTest(true, MapOperationInstances.GetZipperHeads);
                    foreach (var tup in lastResults)
                    {
                        //if(sgt1.MatchNeighborhood(z,tup.Item1,0))
                        //    tup.Item1.Print();
                        var headPosList = ZipperHandler.DetectPotentialZipper(tup.Item1, maxRadius);
                        if (headPosList == null)
                        {
                            continue;
                        }
                        List <int> vids = null;
                        Dictionary <Tuple <int, int>, List <int> > mapELabel2Vids = new Dictionary <Tuple <int, int>, List <int> >();
                        vids = tup.Item2;
                        foreach (int i in vids)
                        {
                            sgt.MatchNeighborhood(tup.Item1, _g, i, headPosList);
                            HashSet <Tuple <int, int> > eLabels = new HashSet <Tuple <int, int> >();
                            sgt._rets.ForEach(e => eLabels.Add((Tuple <int, int>)e));
                            foreach (var pair in eLabels)
                            {
                                if (!mapELabel2Vids.ContainsKey(pair))
                                {
                                    mapELabel2Vids[pair] = new List <int>();
                                }
                                mapELabel2Vids[pair].Add(i);
                            }
                        }
                        foreach (var pair in mapELabel2Vids)
                        {
                            if (pair.Value.Count >= minSupp)
                            {
                                Edge newEdge = new Edge();

                                newEdge._from = headPosList[pair.Key.Item2].Item1;
                                newEdge._to   = headPosList[pair.Key.Item2].Item2;

                                newEdge._eLabel = pair.Key.Item1;
                                IndexedGraph g           = tup.Item1.ShallowCopy();
                                Edge[]       newEdgeList = new Edge[g._edges.Length + 1];
                                g._edges.CopyTo(newEdgeList, 0);
                                newEdgeList[newEdgeList.Length - 1] = newEdge;
                                g._edges = newEdgeList;

                                Vertex v1             = g._vertexes[newEdge._from];
                                int[]  newOutEdgeList = new int[v1._outEdge.Length + 1];
                                v1._outEdge.CopyTo(newOutEdgeList, 0);
                                newOutEdgeList[newOutEdgeList.Length - 1] = newEdgeList.Length - 1;
                                v1._outEdge = newOutEdgeList;

                                Vertex v2            = g._vertexes[newEdge._to];
                                int[]  newInEdgeList = new int[v2._inEdge.Length + 1];
                                v2._inEdge.CopyTo(newInEdgeList, 0);
                                newInEdgeList[newInEdgeList.Length - 1] = newEdgeList.Length - 1;
                                v2._inEdge = newInEdgeList;
                                g.GenIndex();

                                zipperPatterns.Add(new Tuple <IndexedGraph, List <int> >(g, pair.Value));
                            }
                        }
                    }
                }
                lastResults.Clear();
                foreach (var pair in tempResults)
                {
                    int supp = 0;

                    List <List <int> > ccands = _niindex.GetCandidatesForeachVertex(pair.Item1);

                    if (ccands.Exists(e => e != null && e.Count == 0))
                    {
                        continue;
                    }

                    //if (ccands[0].Count < minSupp)
                    //continue;

                    _subGTester._cands = ccands;

                    List <int> vids = null, filteredVids = null;
                    filteredVids = new List <int>();
                    vids         = pair.Item2;

                    foreach (int i in vids)
                    {
                        if (_subGTester.MatchNeighborhood(pair.Item1, _g, i))
                        {
                            supp++;
                            filteredVids.Add(i);
                        }
                    }

                    _subGTester._cands = null;

                    if (supp >= minSupp)
                    {
                        ret.Add(new Tuple <IndexedGraph, List <int> >(pair.Item1, filteredVids));

                        //pattern.Print();
                        //Console.WriteLine(supp+"\n");

                        lastResults.Add(new Tuple <IndexedGraph, List <int> >(pair.Item1, filteredVids));
                    }
                }
                Console.WriteLine("{0} seconds. {1} results.",
                                  (DateTime.Now - begin).TotalSeconds,
                                  lastResults.Count);
                begin = DateTime.Now;

                if (size <= maxRadius + 1)
                {
                    var addpath = fpm.GetPathAndVID(size);
                    lastResults.AddRange(addpath);

                    Console.WriteLine("Adding {0} paths.", addpath.Count);
                    //lastResults.Sort((x, y) => x._vertexes.Length - y._vertexes.Length);
                    ret.AddRange(fpm.GetPathAndVID(size));
                }
                else
                {
                    //add Zipper Patterns
                    Console.WriteLine("Adding {0} Zippers.", zipperPatterns.Count);
                    lastResults.AddRange(zipperPatterns);
                    ret.AddRange(zipperPatterns);
                }
                if (lastResults.Count == 0)
                {
                    break;
                }
            }
            return(ret);
        }