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


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

本博客其他.NET開源項目文章目錄:【目錄】本博客其他.NET開源項目文章目錄

 

前言

  本文今天介紹的.NET開源組件是 KwCombinatorics,它是.NET平台一個高效的生成排列組合序列的開源類庫,它提供了4種生成排列與組合序列的方式。雖然原理和功能都很簡單,但是這個類庫在軟件測試、組合數學以及密碼學等方面都有很大的用處。很早就接觸了這個類庫,以前在一些小程序中也使用過,有時候為了遍歷所有可能的組合,自己去寫循環,生成,的確很繁瑣,有了 KwCombinatorics 之后,都變得簡單寫了,接下來將詳細介紹該類庫的使用。
  KwCombinatorics類庫的主頁是: http://kwcombinatorics.codeplex.com/
  本文后面的資源提供了所有源碼和幫助文件,以及dll文件的打包下載。可以下載到最新的源代碼和幫助文檔,目前最新的穩定率版本是4.0,相比之前又增加了幾個新功能,並進行了一些優化。
  該類庫簡單,只有5個類,dll文件也只有幾十kb,下面將介紹幾個主要的功能。
  排列組合是組合學最基本的概念:
  排列,是指從給定個數的元素中取出指定個數的元素進行排序的所有情況。
  組合,是指從給定個數的元素中僅僅取出指定個數的元素,不考慮排序的所有情況。
 
  上面的2篇文章詳細介紹了排列和組合生成使用,這一篇將介紹 KwCombinatorics最后一個主要功能:使用Product生成笛卡爾積的組合
   
  
   笛卡爾積的定義還是直接看下面的表達式,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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM