Menjana Semua Pembahagian Set
Salah satu masalah asas dalam matematik gabungan ialah mencari semua partition bagi set tertentu. Pembahagian set membahagikan set kepada subset berpisah bukan kosong, dirujuk sebagai blok atau bahagian.
Dalam masalah ini, kami mencari kaedah untuk menghitung semua partition bagi set dengan elemen yang berbeza. Pertimbangkan set {1, 2, 3}. Pembahagiannya ialah:
Algoritma Pembahagian
Tugas boleh dipecahkan kepada dua submasalah: pembahagian kepada dua bahagian dan pembahagian bahagian kepada beberapa bahagian.
Dua Bahagian Pembahagian
Untuk set elemen n, semua partition dua bahagian boleh dijana dengan mewakili setiap elemen sebagai sedikit dalam corak n-bit. Bit 0 menunjukkan penempatan di bahagian pertama, dan 1 bit menunjukkan penempatan di bahagian kedua. Untuk mengelakkan hasil pendua apabila menukar bahagian, kami sentiasa menetapkan elemen pertama kepada bahagian pertama. Ini meninggalkan (2^(n-1))-1 corak dua bahagian yang unik.
Pembahagian Rekursif
Dengan teknik pembahagian dua bahagian, kami boleh membina semua partition secara rekursif.
Pelaksanaan C#
Pelaksanaan C# berikut menggunakan algoritma pembahagian rekursif:
using System; using System.Collections.Generic; using System.Linq; namespace PartitionTest { public static class Partitioning { public static IEnumerable<T[][]> GetAllPartitions<T>(T[] elements) { return GetAllPartitions(new T[][]{}, elements); } private static IEnumerable<T[][]> GetAllPartitions<T>(T[][] fixedParts, T[] suffixElements) { // Trivial partition: fixed parts followed by all suffix elements as a single block yield return fixedParts.Concat(new[] { suffixElements }).ToArray(); // Two-group-partitions of suffix elements and their recursive sub-partitions var suffixPartitions = GetTuplePartitions(suffixElements); foreach (Tuple<T[], T[]> suffixPartition in suffixPartitions) { var subPartitions = GetAllPartitions( fixedParts.Concat(new[] { suffixPartition.Item1 }).ToArray(), suffixPartition.Item2); foreach (var subPartition in subPartitions) { yield return subPartition; } } } private static IEnumerable<Tuple<T[], T[]>> GetTuplePartitions<T>(T[] elements) { if (elements.Length < 2) yield break; for (int pattern = 1; pattern < 1 << (elements.Length - 1); pattern++) { List<T>[] resultSets = { new List<T> { elements[0] }, new List<T>() }; for (int index = 1; index < elements.Length; index++) { resultSets[(pattern >> (index - 1)) & 1].Add(elements[index]); } yield return Tuple.Create(resultSets[0].ToArray(), resultSets[1].ToArray()); } } } }
Atas ialah kandungan terperinci Bagaimana Kita Boleh Menjana Semua Pembahagian Set Set Diberikan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!