本博客所有文章分類的總目錄:本博客博文總目錄-實時更新
本博客其他.NET開源項目文章目錄:【目錄】本博客其他.NET開源項目文章目錄
前言
本文今天介紹的.NET開源組件是 KwCombinatorics,它是.NET平台一個高效的生成排列組合序列的開源類庫,它提供了4種生成排列與組合序列的方式。雖然原理和功能都很簡單,但是這個類庫在軟件測試、組合數學以及密碼學等方面都有很大的用處。很早就接觸了這個類庫,以前在一些小程序中也使用過,有時候為了遍歷所有可能的組合,自己去寫循環,生成,的確很繁瑣,有了 KwCombinatorics 之后,都變得簡單寫了,接下來將詳細介紹該類庫的使用。A = {1,2}; B = {3,4} A × B = {1,2} × {3,4} = {(1,3), (1,4), (2,3), (2,4)} B × A = {3,4} × {1,2} = {(3,1), (3,2), (4,1), (4,2)} A = B = {1,2} A × B = B × A = {1,2} × {1,2} = {(1,1), (1,2), (2,1), (2,2)}
1.Product 類基本介紹
Product類就是根據多個數據源(A ,B ..),選擇指定個數的元素,進行組合。就是上面的笛卡爾積的選擇方式,看看Product幾個主要的構造函數如下:
1 Product()//Make an empty Product. 2 Product(Int32[])//Make a new Product from the supplied column sizes of Rank 0. 3 Product(Product)//Make a copy of a Product. 4 Product(Int32[],Int32[])//Make a new Product of the supplied column sizes from the supplied values. 5 Product(Int32[],Int64)//Make a new Product from the supplied column sizes of the supplied rank.
參數主要有下面幾個注意點,參數的意義和Combination有些不一樣:
sizes:是指每個乘數(A,B,C...)的長度數組,例如:{2,3},代表A,B的長度為2,3,這樣就會初始化一個{0,1},{0,1,2}的元素數組進行笛卡爾積的計算
source:的用法如Rank有些類似,該數組長度和siezes一樣,其意義就是分別取對應乘數位置的 元素,進行組合得到的列表;
rank:這個屬性和source可以根據實際情況使用,rank是直接獲取相對總數的位置的列表;而source是指定每個元素進行組合。
下面用幾個例子說明幾個主要方法的使用情況。
2.獲取所有的笛卡爾積列表
為了便於簡單觀察結果,我簡單的計算3個元素列表{0,1} * {0,1} ,{0,1} 的笛卡爾積,獲取所有的組合情況有哪些呢?直接上代碼,比較容易看得懂:
大家可以修改代碼,看看其他結果:
1 int[] sizes = { 2, 2, 2 }; 2 3 var pt = new Product (sizes); 4 5 Console.WriteLine (" ( " + String.Join (", ", sizes) + " )"); 6 7 foreach (var row in pt.GetRows()) 8 Console.WriteLine ("{0,2}: {1}", row.Rank, row);
運行結果如下:
1 ( 2, 2, 2 ) 2 0: { 0, 0, 0 } 3 1: { 0, 0, 1 } 4 2: { 0, 1, 0 } 5 3: { 0, 1, 1 } 6 4: { 1, 0, 0 } 7 5: { 1, 0, 1 } 8 6: { 1, 1, 0 } 9 7: { 1, 1, 1 }
3.獲取任意對象的笛卡爾積列表
1 var oneThing = new List<object>{"apple","bench","chair"}; 2 3 var twoThing = new List<object>{"A","B"}; 4 5 var sources = new List<object>[]{oneThing,twoThing}; 6 7 int[] sizes = { oneThing.Count, twoThing.Count }; 8 9 var pt = new Product (sizes); 10 11 Console.WriteLine (" ( " + String.Join (", ", sizes) + " )"); 12 13 foreach (var row in pt.GetRows()) 14 { 15 Console.Write("Rank = {0}: ", row.Rank); 16 foreach (var element in Product.Permute(row,sources)) 17 { 18 Console.Write(element + " "); 19 } 20 Console.WriteLine(); 21 }
結果如下:
1 ( 3, 2 ) 2 Rank = 0: apple A 3 Rank = 1: apple B 4 Rank = 2: bench A 5 Rank = 3: bench B 6 Rank = 4: chair A 7 Rank = 5: chair B
當然其他對象也類似,大家可以依次類推。
4.高級—獲取任意Rank位置的組合
這個類也提供了Rank功能,也是需要獲取指定位置的排列,為了和組合的對比,我們采用了幾乎一樣的代碼,但參數不一樣,看代碼和結果就知道了:
int[] sizes = { 7, 6, 5 }; long rank = 43; // Create a cartesian product row of the supplied rank: var pt = new Product (sizes, rank); Console.WriteLine ("{0} w={1}, rank={2}\n", pt, pt.Width, pt.Rank); pt.Rank = -1; string text = pt.ToString() + " w=" + pt.Width + ", last=" + pt.Rank; Console.WriteLine (text); pt.Rank = pt.Rank + 1; Console.WriteLine ("\n{0} w={1}, rank={2}", pt, pt.Width, pt.Rank); Console.ReadKey();
結果:
1 { 1, 2, 3 } w=3, rank=43 2 3 { 6, 5, 4 } w=3, last=209 4 5 { 0, 0, 0 } w=3, rank=0
5.總結
在這里,這個組件的3個主要功能就介紹完成了,這里要說的是,這3篇文章也只是介紹了組件的一些常規應用。大家可以看源碼的例子,發現更多的應用。例如,還可以將你的實體類繼承 組合 或者 排列 類,可以讓一些對象生成排列組合的使用更簡單。希望這幾篇文章對大家有用。
6.資源
資源參考前一篇文章的資源,幾乎一樣:開源.NET排列組合組件KwCombinatorics使用(一)——組合生成類
如果本文章資源下載不了,或者文章顯示有問題,請參考 本文原文地址:http://www.cnblogs.com/asxinyu/p/4262001.html