/// <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); }
/// <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); }