public ClusteringResult Clone()
        {
            ClusteringResult target = new ClusteringResult();
            target.Parent = this.Parent;
            HashSet<string> layerNames = new HashSet<string>();
            List<Category> categoryList = new List<Category>();
            target.checkDividCategoryDic = this.checkDividCategoryDic;
            target.random = new Random(random.Next());
            foreach (var category in Categories)
            {
                var ca = new Category();
                target.Categories.Add(ca);
                categoryList.Add(ca);
                foreach (var item in category.Layer)
                {
                    var layer = ca.GetLayer(item.Key);
                    layerNames.Add(item.Key);
                    foreach (ComunityEx comuinity in item.Value.Comunities)
                    {
                        layer.Comunities.Add(comuinity);
                        target.ComunityList.Add(comuinity);
                        target.ComunityDic.Add(comuinity.Id, comuinity);
                    }
                }
            }

            foreach (var item in layerNames)
            {
                LayerGroup lg = new LayerGroup()
                {
                    Name = item,
                    Items = new System.Collections.ObjectModel.ObservableCollection<Layer>()
                };
                target.LayerGroup.Add(item, lg);
                foreach (var item2 in Categories)
                {
                    lg.Items.Add(item2.GetLayer(item));
                }
            }
            return target;
        }
 ClusteringResult Run3()
 {
     OnReport("開始");
     ClusteringResult cr = new ClusteringResult() { Parent = this };
     cr.CreateRandom(ClusterTable, random.Next());
     cr.Run();
     OnReport("計算終了\n");
     GC.Collect();
     return cr;
 }
        public void CategorySort(ClusteringResult baseResult)
        {
            List<Category> list = new List<Category>();
            List<Category> list2 = new List<Category>(this.Categories);
            foreach (var item in baseResult.Categories)
            {
                if (list2.Count > 0)
                {
                    var idList = item.GetComuity().Select(n => n.Id);
                    var c = list2.OrderByDescending(n => n.GetComuity().Select(m => m.Id).Intersect(idList).Count()).First();
                    list2.Remove(c);
                    list.Add(c);
                }
                else
                {
                    list.Add(new Category());
                }
            }
            this.Categories.Clear();
            foreach (var item in list)
            {
                this.Categories.Add(item);
            }

            var layerNames = this.LayerGroup.Select(n => n.Key).Distinct().ToArray();
            LayerGroup.Clear();
            foreach (var item in layerNames)
            {
                LayerGroup lg = new LayerGroup() { Name = item, Items = new System.Collections.ObjectModel.ObservableCollection<Layer>() };
                LayerGroup.Add(item, lg);
                foreach (var item2 in Categories)
                {
                    lg.Items.Add(item2.GetLayer(item));
                }
            }
        }
        /// <summary>
        /// 過去のもの。頑張りすぎた。
        /// </summary>
        /// <returns></returns>
        ClusteringResult Run2()
        {
            List<ClusteringResult> tmpResult = new List<ClusteringResult>();
            OnReport("開始");
            for (int i = 0; i < wideCount; i++)
            {
                ClusteringResult cr = new ClusteringResult() { Parent = this };
                cr.CreateRandom(ClusterTable, random.Next());
                tmpResult.Add(cr);
            }

            int loopCount = 0;
            int sameCount = 0;
            double sameRate = 0;
            while (true)
            {

                loopCount++;
                if (tmpResult.First().GetLockRate() == sameRate)
                {
                    sameCount++;
                }
                else
                {
                    sameRate = tmpResult.First().GetLockRate();
                    sameCount = 0;
                }

                OnReport(loopCount + "回目開始");
                foreach (var item in tmpResult)
                {
                    item.Run();
                }
                OnReport("計算終了");

                var baseResult = tmpResult.OrderByDescending(n => n.GetPerformanceIndex()).First();
                foreach (var item in tmpResult)
                {
                    item.CategorySort(baseResult);
                }
                tmpResult = tmpResult.OrderByDescending(n => n.GetPerformanceIndex()).ToList();
                List<ClusteringResult> list = new List<ClusteringResult>();
                foreach (var item in tmpResult.Take(tmpResult.Count / 2))
                {
                    var clone = item.Clone();
                    list.Add(clone);
                }
                if (tmpResult.Count > 3)
                {
                    foreach (var item in tmpResult.Skip(tmpResult.Count / 2).ToArray())
                    {
                        tmpResult.Remove(item);
                    }
                    foreach (var item in list)
                    {
                        tmpResult.Add(item.Clone());
                    }
                }

                if (tmpResult.First().GetLockRate() < 0.9 && loopCount < 100 && sameCount < 10)
                {
                    int c = 0;
                    OnReport("マージ・ランダム振り開始");
                    foreach (var item in tmpResult)
                    {
                        var count = item.CreateMargeData(list, true);
                        //  lock (this)
                        {
                            c += count;
                        }
                    }
                    OnReport("レポート開始");
                    OnReport(tmpResult.First().View());

                    if (c == 0) break;
                }
                else
                {
                    foreach (var item in tmpResult)
                    {
                        var count = item.CreateMargeData(list, false);
                    }
                    tmpResult.First().Run();
                    break;
                }

                if (tmpResult.First().DivideCategory())
                {
                    OnReport("クラスタ分割発生");
                    var r = tmpResult.First();
                    tmpResult.Clear();
                    for (int i = 0; i < TryCount; i++)
                    {
                        tmpResult.Add(r.Clone());
                    }
                }
                GC.Collect();
            }
            GC.Collect();
            OnReport("完了");
            return tmpResult.First();
        }