/// <summary>
        /// 与えた有限集合の冪集合を返す
        /// 冪集合は、すべての部分集合を要素にもつ
        /// </summary>
        /// <param name="originalSet">元の集合(台集合)</param>
        /// <returns>冪集合 P(originalSet)</returns>
        public static FamilyOfSubsets <TEnum> PowerSet <TEnum>(this FiniteSet <TEnum> originalSet)
            where TEnum : Enum
        {
            //まず密着位相をつくる
            var retFamily = originalSet.IndiscreteFamily();

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

            // 1 << n は 2^n (2のn乗)
            for (int index = 0; index < (1 << originalSet.Count); index++)
            {
                var subset = new FiniteSet <TEnum>();
                int bit    = 0;
                foreach (var element in originalSet)
                {
                    if ((index & (1 << bit)) != 0)
                    {                        // if the j-th bit of i is set...
                        subset.Add(element); // add the item to the current sublist
                    }
                    bit++;
                }
                retFamily.Add(subset); // add the current sublist to the final result
            }



            return(retFamily);
        }
        /// <summary>
        /// 台集合からなあらゆる開集合系を網羅したリストを生成するメソッド。の改良版。
        /// https://twitter.com/noshi91/status/1342137767615066113?s=20
        /// というアドバイスをもらったのでそれを転写。
        /// ビット演算を用いてなんとかしたが、それでもやはり実行がとてつもなく重く、時間もかかる。
        /// そのため、このメソッドで生成したリストを別途jsonやxmlに保存したほうがよい。
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="originalSet">元の集合(台集合)</param>
        /// <returns>開集合系リスト</returns>
        public static SortedSet <FamilyOfSubsets <TEnum> > OpenSetsListVer2 <TEnum>(this FiniteSet <TEnum> originalSet)
            where TEnum : Enum
        {
            //Ver1では openSetsを作る→openSetsが開集合系の可能性を満たすかどうか判定していたが…

            //まず冪集合をつくる すでに重いと思う
            FamilyOfSubsets <TEnum> PowerSet = originalSet.PowerSet();
            //返すリスト
            var retList = new SortedSet <FamilyOfSubsets <TEnum> >();


            BigInteger ans = 0;

            void dfs(BigInteger s, int i)
            {
                if (i == 32)
                {
                    string printFamilySets = "";

                    for (int t = 0; t != 32; ++t)
                    {
                        if (((s >> t) & 1) == 0)
                        {
                            continue;
                        }
                        printFamilySets += "{";
                        for (int k = 0; k != 5; ++k)
                        {
                            if (((t >> k) & 1) == 1)
                            {
                                printFamilySets += ",";
                            }
                        }
                        printFamilySets += "},";
                    }
                    Console.WriteLine(printFamilySets);

                    ans += 1;
                    return;
                }
                dfs(s, i + 1);
                for (int t = 0; t != i; ++t)
                {
                    if (((s >> t) & 1) == 1 && ((s >> (t & i)) & 1) == 0)
                    {
                        return;
                    }
                }
                dfs(s | (1 << i), i + 1);
            };

            dfs(0, 0);


            Console.WriteLine(retList.Count + "個");
            return(retList);
        }
        /// <summary>
        /// 2つの集合の対称差(排他的論理和)を取る
        /// </summary>
        /// <param name="set1">集合1</param>
        /// <param name="set2">集合2</param>
        /// <returns>集合1△集合2</returns>
        public static FiniteSet <TEnum> SymmetricExcept <TEnum>(this FiniteSet <TEnum> set1, FiniteSet <TEnum> set2)
            where TEnum : Enum
        {
            var retSet = new FiniteSet <TEnum>(set1);

            retSet.SymmetricExceptWith(set2);
            retSet.Update();
            return(retSet);
        }
        /// <summary>
        /// 2つの集合の和集合を取る
        /// </summary>
        /// <param name="set1">集合1</param>
        /// <param name="set2">集合2</param>
        /// <returns>集合1∪集合2</returns>
        public static FiniteSet <TEnum> Union <TEnum>(this FiniteSet <TEnum> set1, FiniteSet <TEnum> set2)
            where TEnum : Enum
        {
            var retSet = new FiniteSet <TEnum>(set1);

            retSet.UnionWith(set2);
            retSet.Update();
            return(retSet);
        }
 public bool Equals([AllowNull] FiniteSet <TEnum> x, [AllowNull] FiniteSet <TEnum> y)
 {
     //値参照して同じならtrue
     if (x.SequenceEqual(y))
     {
         return(true);
     }
     return(false);
 }
Exemplo n.º 6
0
        /// <summary>
        ///  ∩-完備,σ乗法性があるかどうか(共通部分∩について閉じているかどうか)
        /// </summary>
        /// <param name="subsets">集合族</param>
        /// <returns>∩-完備</returns>
        public static bool isProductComplete <TEnum>(this FamilyOfSubsets <TEnum> subsets)
            where TEnum : Enum
        {
            foreach (FiniteSet <TEnum> subset1 in subsets)
            {
                foreach (FiniteSet <TEnum> subset2 in subsets)
                {
                    FiniteSet <TEnum> andSet = subset1.And(subset2);
                    if (!subsets.Contains(andSet))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
0
        /// <summary>
        ///  △-完備かどうか(対称差△について閉じているかどうか)
        /// </summary>
        /// <param name="subsets">集合族</param>
        /// <returns>△-完備</returns>
        public static bool isSymDiffComplete <TEnum>(this FamilyOfSubsets <TEnum> subsets)
            where TEnum : Enum
        {
            foreach (FiniteSet <TEnum> subset1 in subsets)
            {
                foreach (FiniteSet <TEnum> subset2 in subsets)
                {
                    FiniteSet <TEnum> xorSet = subset1.Xor(subset2);
                    if (!subsets.Contains(xorSet))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 9
0
        /// <summary>
        /// 部分集合族の総和を取る
        /// </summary>
        /// <param name="subsets">部分集合族</param>
        /// <returns>総和</returns>
        public static FiniteSet <TEnum> SumOfSeq <TEnum>(this FamilyOfSubsets <TEnum> subsets)
            where TEnum : Enum
        {
            //集合がなければ空集合を返す
            if (subsets == null || subsets.Count == 0)
            {
                return(new FiniteSet <TEnum>());
            }
            //まず空集合を設置
            var retSet = new FiniteSet <TEnum>();

            foreach (FiniteSet <TEnum> subset in subsets)
            {
                retSet = retSet.Or(subset);
            }

            return(retSet);
        }
Exemplo n.º 10
0
        /// <summary>
        ///  補-完備かどうか(補集合cについて閉じているかどうか)
        /// </summary>
        /// <param name="subsets">集合族</param>
        /// <param name="universe">全体集合</param>
        /// <returns>補-完備</returns>
        public static bool isComplementComplete <TEnum>(this FamilyOfSubsets <TEnum> subsets, FiniteSet <TEnum> universe)
            where TEnum : Enum
        {
            if (!subsets.isUniverseOK(universe))
            {
                throw new ArgumentException("全体集合が、部分集合族の要素である、集合の要素を網羅していません");
            }

            foreach (FiniteSet <TEnum> subset in subsets)
            {
                FiniteSet <TEnum> diffSet = universe.Diff(subset);
                if (!subsets.Contains(diffSet))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 11
0
        /// <summary>
        ///  \-完備かどうか(差集合\について閉じているかどうか)
        /// </summary>
        /// <param name="subsets">集合族</param>
        /// <returns>\-完備</returns>
        public static bool isDiffComplete <TEnum>(this FamilyOfSubsets <TEnum> subsets)
            where TEnum : Enum
        {
            foreach (FiniteSet <TEnum> subset1 in subsets)
            {
                foreach (FiniteSet <TEnum> subset2 in subsets)
                {
                    FiniteSet <TEnum> diffSet = subset1.Diff(subset2);
                    IEqualityComparer <FiniteSet <TEnum> > comparer = new FiniteSetComparer <TEnum>();
                    if (!subsets.Contains(diffSet, comparer))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        public int CompareTo([AllowNull] FiniteSet <TEnum> other)
        {
            //値参照して同じなら0
            if (this.SequenceEqual(other))
            {
                return(0);
            }

            //要素数で比較
            if (this.Count > other.Count)
            {
                return(1);
            }
            else if (this.Count < other.Count)
            {
                return(-1);
            }

            //要素数が同じ場合、番号が若いenumを持っているほうが先に表示
            foreach (var ele1 in this)
            {
                foreach (var ele2 in other)
                {
                    //同じ要素を比較した場合、次のele1を比較
                    if (ele1.Equals(ele2))
                    {
                        break;
                    }
                    else if (ele1.CompareTo(ele2) == 1)
                    {
                        return(1);
                    }
                    else if (ele1.CompareTo(ele2) == -1)
                    {
                        return(-1);
                    }
                }
            }

            //ここまで来ると同じの可能性があるが、そもそも同じであることは冒頭で比較したのでここまでくるとおかしい
            throw new NotImplementedException();
        }
        /// <summary>
        /// 与えた有限集合の密着位相となる部分集合族を返す
        /// </summary>
        /// <param name="originalSet">元の集合(台集合)</param>
        /// <returns>密着位相となる部分集合族 {originalSet,Empty}</returns>
        public static FamilyOfSubsets <TEnum> IndiscreteFamily <TEnum>(this FiniteSet <TEnum> originalSet)
            where TEnum : Enum
        {
            //空集合なら空集合の集合だけ返す つまり{{}}
            if (originalSet == null || originalSet.Count == 0)
            {
                return(new FamilyOfSubsets <TEnum>()
                {
                    new FiniteSet <TEnum>()
                });
            }


            var retFamily = new FamilyOfSubsets <TEnum>();

            retFamily.Add(originalSet);
            retFamily.Add(new FiniteSet <TEnum>());

            return(retFamily);
        }
Exemplo n.º 14
0
        /// <summary>
        /// (有限)位相空間かどうか。集合族が開集合族の定義を満たすかどうか。
        ///
        /// </summary>
        /// <param name="subsets">集合族</param>
        /// <param name="universe">全体集合・台集合</param>
        /// <returns>(有限)位相空間</returns>
        public static bool isTopological <TEnum>(this FamilyOfSubsets <TEnum> subsets, FiniteSet <TEnum> universe)
            where TEnum : Enum
        {
            //集合がなければ偽
            if (subsets == null || subsets.Count == 0)
            {
                return(false);
            }
            //空集合がなければ偽
            else if (!subsets.isContainsEmpty())
            {
                return(false);
            }
            //台集合がなければ偽
            else if (!subsets.Contains(universe))
            {
                return(false);
            }
            //和集合について閉じてなければ偽
            else if (!subsets.isSumComplete())
            {
                return(false);
            }
            //交叉について閉じてなければ偽
            else if (!subsets.isProductComplete())
            {
                return(false);
            }

            //条件を満たしているので真
            return(true);
        }
Exemplo n.º 15
0
 /// <summary>
 ///  与えた集合が、集合族の全体集合の必要条件を満たしているかどうか
 /// ∀subset∈Subsets ∀element∈subset (element ∈ universe)
 ///
 /// </summary>
 /// <param name="subsets">集合族</param>
 /// <param name="universe">全体集合かどうか判定する集合</param>
 /// <returns>与えた集合は全体集合の必要条件を満たす</returns>
 public static bool isUniverseOK <TEnum>(this FamilyOfSubsets <TEnum> subsets, FiniteSet <TEnum> universe)
     where TEnum : Enum
 {
     foreach (FiniteSet <TEnum> subset in subsets)
     {
         foreach (TEnum element in subset)
         {
             if (!universe.Contains(element))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
 /// <summary>
 /// 2つの集合の差集合を取る
 /// </summary>
 /// <param name="set1">集合1</param>
 /// <param name="set2">集合2</param>
 /// <returns>集合1\集合2</returns>
 public static FiniteSet <TEnum> Diff <TEnum>(this FiniteSet <TEnum> set1, FiniteSet <TEnum> set2)
     where TEnum : Enum
 {
     return(Except(set1, set2));
 }
 /// <summary>
 /// 2つの集合の和集合を取る
 /// </summary>
 /// <param name="set1">集合1</param>
 /// <param name="set2">集合2</param>
 /// <returns>集合1∪集合2</returns>
 public static FiniteSet <TEnum> Sum <TEnum>(this FiniteSet <TEnum> set1, FiniteSet <TEnum> set2)
     where TEnum : Enum
 {
     return(Union(set1, set2));
 }
 public int GetHashCode([DisallowNull] FiniteSet <TEnum> obj)
 {
     return(obj.ToString().GetHashCode());
 }
Exemplo n.º 19
0
        /// <summary>
        /// 集合族の中に要素である集合が含まれているかどうか
        /// </summary>
        /// <param name="item">有限集合</param>
        /// <returns>含まれている</returns>
        public override bool Contains(FiniteSet <TEnum> item)
        {
            IEqualityComparer <FiniteSet <TEnum> > comparer = new FiniteSetComparer <TEnum>();

            return(Enumerable.Contains(this, item, comparer));
        }
        /// <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);
        }
 /// <summary>
 /// 集合の濃度を返す
 /// </summary>
 /// <typeparam name="TEnum"></typeparam>
 /// <param name="set">集合</param>
 /// <returns>濃度</returns>
 public static int Cardinality <TEnum>(this FiniteSet <TEnum> set)
     where TEnum : Enum
 {
     return(set.Count);
 }
Exemplo n.º 22
0
        /// <summary>
        /// 部分集合族の包含関係 ⊆ から 自己関係 R を生成するメソッド
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="subsets">部分集合族</param>
        /// <param name="universe">全体集合</param>
        /// <returns></returns>
        public static EndoRelation <FiniteSet <TEnum> > CreateSubsetRelation <TEnum>(this FamilyOfSubsets <TEnum> subsets, FiniteSet <TEnum> universe)
            where TEnum : Enum
        {
            if (!subsets.isUniverseOK(universe))
            {
                throw new ArgumentException("全体集合が、部分集合族の要素である、集合の要素を網羅していません");
            }

            var retRel = new EndoRelation <FiniteSet <TEnum> >();

            //自己関係の全体集合は冪集合(もとの台集合の部分集合族なので)
            retRel.SetUniverse(universe.PowerSet());

            //要素となる集合を格納
            foreach (FiniteSet <TEnum> subsetX in subsets)
            {
                foreach (FiniteSet <TEnum> subsetY in subsets)
                {
                    //X⊆Y ⇔ X R Y という定義で自己関係Rを定義
                    if (subsetX.IsSubsetOf(subsetY))
                    {
                        retRel.Add((subsetX, subsetY));
                    }
                }
            }

            return(retRel);
        }
 /// <summary>
 /// 2つの集合の交叉を取る
 /// </summary>
 /// <param name="set1">集合1</param>
 /// <param name="set2">集合2</param>
 /// <returns>集合1⋂集合2</returns>
 public static FiniteSet <TEnum> Product <TEnum>(this FiniteSet <TEnum> set1, FiniteSet <TEnum> set2)
     where TEnum : Enum
 {
     return(Intersection(set1, set2));
 }
 /// <summary>
 /// 2つの集合の対称差(排他的論理和)を取る
 /// </summary>
 /// <param name="set1">集合1</param>
 /// <param name="set2">集合2</param>
 /// <returns>集合1△集合2</returns>
 public static FiniteSet <TEnum> Xor <TEnum>(this FiniteSet <TEnum> set1, FiniteSet <TEnum> set2)
     where TEnum : Enum
 {
     return(SymmetricExcept(set1, set2));
 }