Beispiel #1
0
        /// <summary>
        /// 離散位相かどうか。
        /// </summary>
        /// <param name="subsets">集合族</param>
        /// <param name="universe">全体集合・台集合</param>
        /// <returns>離散位相である</returns>
        public static bool isDiscrete <TEnum>(this FamilyOfSubsets <TEnum> subsets, FiniteSet <TEnum> universe)
            where TEnum : Enum
        {
            //まず位相空間でなければ偽
            if (!subsets.isTopological(universe))
            {
                return(false);
            }
            //濃度が2^universe.Countでなければ偽
            else if (subsets.Count != ((BigInteger)1 << universe.Count))
            {
                return(false);
            }

            //条件を満たしているので真
            return(true);
        }
        /// <summary>
        /// 台集合からなあらゆる開集合系を網羅したリストを生成するメソッド。
        /// 2^(2^n - 2)という計算をしているため実行がとてつもなく重く、時間もかかる。
        /// そのため、このメソッドで生成したリストを別途jsonやxmlに保存したほうがよい。
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="originalSet">元の集合(台集合)</param>
        /// <returns>開集合系リスト</returns>
        public static SortedSet <FamilyOfSubsets <TEnum> > OpenSetsList <TEnum>(this FiniteSet <TEnum> originalSet)
            where TEnum : Enum
        {
            //まず冪集合をつくる すでに重いと思う
            FamilyOfSubsets <TEnum> PowerSet = originalSet.PowerSet();

            //返すリスト
            var retList = new SortedSet <FamilyOfSubsets <TEnum> >();
            //まず密着位相をつくる
            //var family = originalSet.IndiscreteFamily();

            //クソでかくなるのでビット演算を使わざるを得なかった

            BigInteger indiscreteIndex = 4;

            //扱ってる対象が密着空間かどうか
            bool isDiscrete = false;

            // 1 << n は 2^n (2のn乗)
            for (BigInteger index = 0; index < ((BigInteger)1 << (1 << originalSet.Count) - 2); index++)
            {
                //離散空間の次の位相空間のナンバーを記録する
                //この位相空間は密着位相である
                if (isDiscrete)
                {
                    indiscreteIndex = index;
                    isDiscrete      = false;
                }

                //開集合系を初期化
                var openSets = new FamilyOfSubsets <TEnum>();

                //空集合を入れる。これは必ず入れる
                openSets.Add(new FiniteSet <TEnum>());
                //台集合を入れる。これも必ず入れる
                openSets.Add(originalSet);


                //要素の有無を判定し、追加。
                for (int j = 0; j < (1 << originalSet.Count); j++)
                {
                    if ((index & ((BigInteger)1 << j - 1)) != 0)
                    {
                        //ElementAtがクソ重いのでどうにかすべき
                        openSets.Add(PowerSet.ElementAt(j));
                    }
                }

                //位相空間かどうか判定を行う。位相空間でなければ何もしない
                if (openSets.isTopological(originalSet))
                {
                    //開集合系の条件を満たす
                    retList.Add(openSets);

                    bool Dis = openSets.isDiscrete(originalSet);


                    System.IO.StreamWriter sw = new System.IO.StreamWriter(
                        "test.txt", // 出力先ファイル名
                        true,       // 追加書き込み
                        Encoding.UTF8);

                    //Console.SetOut(sw); // 出力先(Outプロパティ)を設定

                    Console.WriteLine(index.ToString("x4") + ":" + index.ToString() + ":" +
                                      retList.Count + ":" + Dis + ":" +
                                      openSets.ToString());

                    //離散空間の場合、しばらくの間は位相空間となる数字が出てこないので、
                    //bit31の値を倍にする
                    //if (Dis && bit31 >= 4)
                    //{
                    //    isDiscrete = true;
                    //    bit31 = indiscreteIndex * 2 - 1;
                    //}


                    sw.Dispose(); // ファイルを閉じてオブジェクトを破棄
                }
                openSets = null;
            }


            Console.WriteLine(retList.Count + "個");
            return(retList);
        }