天天看點

【原創】開源.NET排列組合元件KwCombinatorics使用(三)——笛卡爾積組合

【原創】開源.NET排列組合元件KwCombinatorics使用(三)——笛卡爾積組合

本文今天介紹的.NET開源元件KwCombinatorics的笛卡爾積組合生成功能,它是.NET平台一個高效的生成排列組合序列的開源類庫,它提供了4種生成排列與組合序列的方式。雖然原理和功能都很簡單,但是這個類庫在軟體測試、組合數學以及密碼學等方面都有很大的用處。很早就接觸了這個類庫,以前在一些小程式中也使用過,有時候為了周遊所有可能的組合,自己去寫循環,生成,的确很繁瑣,有了KwCombinatorics 之後,都變得簡單寫了,接下來将詳細介紹該類庫的使用

       本部落格所有文章分類的總目錄:本部落格博文總目錄-實時更新

本部落格其他.NET開源項目文章目錄:【目錄】本部落格其他.NET開源項目文章目錄

KwCombinatorics元件文章目錄:

1.【原創】開源.NET排列組合元件KwCombinatorics使用(一)—組合生成 

2.【原創】開源.NET排列組合元件KwCombinatorics使用(二)——排列生成

3.【原創】開源.NET排列組合元件KwCombinatorics使用(三)——笛卡爾積組合

前言

  本文今天介紹的.NET開源元件是KwCombinatorics,它是.NET平台一個高效的生成排列組合序列的開源類庫,它提供了4種生成排列與組合序列的方式。雖然原理和功能都很簡單,但是這個類庫在軟體測試、組合數學以及密碼學等方面都有很大的用處。很早就接觸了這個類庫,以前在一些小程式中也使用過,有時候為了周遊所有可能的組合,自己去寫循環,生成,的确很繁瑣,有了KwCombinatorics 之後,都變得簡單寫了,接下來将詳細介紹該類庫的使用。

  KwCombinatorics類庫的首頁是:http://kwcombinatorics.codeplex.com/

  本文後面的資源提供了所有源碼和幫助檔案,以及dll檔案的打包下載下傳。可以下載下傳到最新的源代碼和幫助文檔,目前最新的穩定率版本是4.0,相比之前又增加了幾個新功能,并進行了一些優化。

  該類庫簡單,隻有5個類,dll檔案也隻有幾十kb,下面将介紹幾個主要的功能。

  排列組合是組合學最基本的概念:

  排列,是指從給定個數的元素中取出指定個數的元素進行排序的所有情況。

  組合,是指從給定個數的元素中僅僅取出指定個數的元素,不考慮排序的所有情況。

  上面的2篇文章詳細介紹了排列群組合生成使用,這一篇将介紹KwCombinatorics最後一個主要功能:使用Product生成笛卡爾積的組合

   

  本文原始位址:http://www.cnblogs.com/asxinyu/p/4262001.html 

  

   笛卡爾積的定義還是直接看下面的表達式,Product的作用也就是幹這個的:

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

.NET資料挖掘與機器學習,作者部落格:

http://www.cnblogs.com/asxinyu

E-mail:[email protected]