1. 程式人生 > >.NET平臺開源專案速覽(11)KwCombinatorics排列組合使用案例(1)

.NET平臺開源專案速覽(11)KwCombinatorics排列組合使用案例(1)

    今年上半年,我在KwCombinatorics系列文章中,重點介紹了KwCombinatorics元件的使用情況,其實這個元件我5年前就開始用了,非常方便,麻雀雖小五臟俱全。所以一直非常喜歡,才寫了幾篇文章推薦給大家。最近在計算足球彩票結果組合過程中,使用的到了其功能,生成排列,非常具有代表性,而且也有網友諮詢過類似的問題,所以就封裝為擴充套件方法,方便呼叫。

1.KwCombinatorics基本介紹

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

   關於KwCombinatorics基本使用入門的文章有: 

2.足球彩票排列組合應用

     在足球彩票玩法中,經常要選擇幾場比賽,以及每場比賽不同的結果組合,進行投注,這個時候就要生成所有的排列組合了,以便進行下一步的平衡投注計算。例如,看下面一個截圖:

    例如,上午選擇了3場比賽,前2場,每場選擇2個結果,第三場做膽,進行3串1玩法,當然這裡的例子很簡單,大家腦袋想一想就知道是4個結果。如果是其他玩法,每個有3,4個選擇,有5串1 ,那就麻煩了,何苦都必須要自動生成出組合來。所以必須得考慮一個通用的情況。而且在進行預測以及分析的時候,通常要對包含所有結果的幾場比賽進行串分析,就需要計算所有排列組合的結果形式了例如下面這種總進球的多串1選擇:

3.排列組合生成程式碼與測試

3.1 N場單個玩法所有結果的組合

    比如勝平負有3個玩法,【3,1,0】,那麼我有N場比賽,要進行串組合,計算所有的組合情況。寫一個通用的函式,使用KwCombinatorics的笛卡爾積來完成,直接看程式碼和註釋,注意使用之前要引用對應的dll和名稱空間:

/// <summary>單個不同玩法,任意場次數的結果全部結果組合</summary>
/// <typeparam name="T">結果型別,主要分字串,整數</typeparam>
/// <param name="source">該玩法的所有結果列表</param>
/// <param name="count">場次數量:每一個場次都可能會出現source中的結果</param>
/// <returns>所有組合的列表</returns>
public static IEnumerable<List<T>> PermuteResultForSingle<T>(this List<T> source, int count)
{
	//例項化N場比賽的所有結果陣列,每一個List都包括所有結果
	List<T>[] sourceList = new List<T>[count];
	Int32[] sizes = new Int32[count];

	for (int i = 0; i < count; i++)
	{
		sourceList[i] = source;
		sizes[i] = source.Count;
	}
	//使用笛卡爾積的形式來生成
	var pt = new Product(sizes);
	//依次生產所有組合,每一個組合都是結果的集合
	foreach (var row in pt.GetRows())
	{
		yield return Product.Permute(row, sourceList);
	}
}

    考慮到呼叫方便,這裡寫成了擴充套件方法,並使用了泛型,也就是說可以直接處理整數結果形式,也可以處理漢字字串結果形式。那我們進行一下測試看看。

先看測試程式碼,我們假設勝平負玩法,2場比賽,應該是有9種結果:

static void Test1()
{
	//先定義每一個玩法的所有結果型別,勝平負有3個結果
	var result = new List<Int32>() { 3,1,0};
	//直接擴充套件方法計算,並傳入場次數量引數,我們計算2場的所有組合
	var combList = result.PermuteResultForSingle<Int32>(2);
	foreach (var item in combList)
	{
		//將結果轉換為字串依次列印
		//ArrayToString是一個將陣列列表轉換為字串的擴充套件方法
		Console.WriteLine(item.ArrayToString());
	}
}

看看結果:

    其實還可以處理字串型別的情況,例如我們把程式碼改成這樣:

var result = new List<String>() { "勝","平","負"};
//直接擴充套件方法計算,並傳入場次數量引數,我們計算2場的所有組合
var combList = result.PermuteResultForSingle<String>(2);
foreach (var item in combList)
{
	//將結果轉換為字串依次列印	
	Console.WriteLine(item.ArrayToString());
}

    結果如下,當然你可以修改數量,計算更多複雜的情況,一 一進行處理。

3.2 混合玩法的多個結果組合

    在競彩的混投玩法中,可以選擇任意場次的不同玩法進行組合,比如,你A比賽可以選擇勝平負結果,而B比賽選擇大小球,然後串起來進行投注。情況有時候會更復雜,這種情況下,玩家為了刺激,會適當增加結果數量,然後進行串投注。其實整體思路和3.1差不多,只不過由於每個玩法的結果型別不一樣,需要將引數轉換為object,才更好處理。看看程式碼,也是擴充套件方法:

/// <summary>混合不同玩法,任意場次的多個結果的組合</summary>
/// <param name="source">場次按順序選擇的玩法的所有結果列表</param>
/// <returns></returns>
public static IEnumerable<List<Object>> PermuteResultForMixture(this List<Object>[] source)
{
	//初始化所有場次玩法結果的資料
	Int32[] sizes = new Int32[source.Length];
	for (int i = 0; i < source.Length; i++) sizes[i] = source[i].Count;
	//使用笛卡爾積,只不過這裡都是Object,不在針對同一種玩法了
	var pt = new Product(sizes);
	foreach (var row in pt.GetRows())
	{
		yield return Product.Permute(row, source);
	}
}

    看看實際的測試結果,當然你也可以把所有玩法都搞一樣的,相對是同一種玩法的N場比賽,選擇不同部分結果進行的組合了:

//勝平負場次的結果選擇
var R1 = new List<Object>() { "勝","平"};
//總進球數結果的選擇
var R2 = new List<Object>() { 2,3,4 };
//半全場結果的選擇
var R3 = new List<Object>() { "勝負" ,"平負"};
//綜合所有選擇
var result = new List<Object>[] { R1, R2, R3 };
//計算所有組合
var combList = result.PermuteResultForMixture();
foreach (var item in combList)
{
	//列印組合,逗號分割,應該有2*3*2=12種組合
	Console.WriteLine(item.ArrayToString());
}

    看結果:

    其他使用很簡單了,依次類推吧。KwCombinatorics的確是很強大,只要和排列組合相關的需求,沒有搞不定的。程式碼,效率都值得點贊。本文程式碼很簡單,就不列舉了,詳細的可以看上面的系列文章。

相關推薦

.NET平臺開源專案(11)KwCombinatorics排列組合使用案例(1)

    今年上半年,我在KwCombinatorics系列文章中,重點介紹了KwCombinatorics元件的使用情況,其實這個元件我5年前就開始用了,非常方便,麻雀雖小五臟俱全。所以一直非常喜歡,才寫了幾篇文章推薦給大家。最近在計算足球彩票結果組合過程中,使用的到了其功能,生成排列,非常具有代表性,而且也

.NET平臺開源專案-最快的物件對映元件Tiny Mapper之專案實踐

心情小札:近期換了工作,苦逼於22:00後下班,房間一篇狼藉~ 小翠鄙視到:"你就適合生活在垃圾堆中!!!" 看評論也是挺有價值,同時也看到許多新手同學問道在實際專案中使用的情況。 下面就原作者的程式碼的基礎上略作調整,闡述一下在實際專案場景中的使用: 第一步:瞭解類庫方法:TinyMapper 主

.NET平臺開源專案(14)最快的物件對映元件Tiny Mapper

    好久沒有寫文章,工作甚忙,但每日還是關注.NET領域的開源專案。五一休息,放鬆了一下之後,今天就給大家介紹一個輕量級的物件對映工具Tiny Mapper:號稱是.NET平臺最快的物件對映元件。那就一起看看呢。 臨時更新:感謝@ 的意見,為了避免新手誤解,這裡說明一下,Tiny Mappe

.NET平臺開源專案(20)Newlife.Core中簡單靈活的配置檔案

如果用知乎,可以關注專欄: 記得5年前開始拼命翻讀X元件的原始碼,特別是XCode,但對Newlife.Core 的東西瞭解很少,最多隻是會用用,而且用到的只是九牛一毛。裡面好用的東西太多了。 最近一年時間,零零散散又學了很多,也瞭解了很多,不會寫那總要學會用吧,今天就給大家介紹裡面非常好用的自定義配置檔

.NET平臺開源專案(19)Power BI神器DAX Studio

  PowerBI更新頻繁,已經有點更不上的節奏,一直在關注和學習中,基本的一些操作大概是沒問題,更重要的是注重Power Query,M函式,以及DAX的使用,這才是核心。     上個月研究了DAX的一些語法和公式,發現這玩意看起來簡單,但其實功能非常強大,所以就想和寫程式碼一樣,弄個工具試一下。

.NET平臺開源專案(21)Cron任務排程CronNET

Quartznet大名鼎鼎應該很少有人不知道,相關的開源專案很多,不過那東東對新手來說,有點晦澀,加上哪個Cron表示式,可能一進去雲裡霧裡的。今天給大家介紹一個簡單的在.NET平臺上執行Cron計劃任務的元件CronNET。同時也給大家推介幾個Cron表示式的工具。 1.Cron介紹和工具

.NET平臺開源專案(7)關於NoSQL資料庫LiteDB的分頁查詢解決過程

  在文章:這些.NET開源專案你知道嗎?讓.NET開源來得更加猛烈些吧!(第二輯) 與 .NET平臺開源專案速覽(3)小巧輕量級NoSQL檔案資料庫LiteDB中,介紹了LiteDB的基本使用情況以及部分技術細節,我還沒有在實際系統中大量使用,但文章釋出後,有不少網友( )反應在實際專案中使用過,效果還

.NET平臺開源專案(1)SharpConfig配置檔案讀寫元件

在.NET平臺日常開發中,讀取配置檔案是一個很常見的需求。以前都是使用System.Configuration.ConfigurationSettings來操作,這個說實話,搞起來比較費勁。不知道大家有沒有同感。所以更多時候我還是喜歡使用開源的東西,更加方便簡潔,也穩定。省去自己的麻煩。今天就介紹一個非常精緻

.NET平臺開源專案(3)小巧輕量級NoSQL檔案資料庫LiteDB

    今天給大家介紹一個不錯的小巧輕量級的NoSQL檔案資料庫LiteDB。本部落格在2013年也介紹過2款.NET平臺的開源資料庫:     上面2個數據庫我的實際的專案中用過,還不錯。當然資料量很小,主要是客戶比較變態,必須要用xml檔案儲存,就想到了,另外NDatabase只是自己覺得好玩,

.NET平臺開源專案(9)軟體序列號生成元件SoftwareProtector介紹與使用

  在文章:這些.NET開源專案你知道嗎?讓.NET開源來得更加猛烈些吧!(第二輯)中,給大家初步介紹了一下Software Protector序列號生成元件。今天就通過一篇簡單的文章來預覽一下其強大的功能。雖然我人為其已經基本滿足了一個軟體序列號的所有要素,但至於大家用不用得上,還得看大家的需求。總的來

.NET平臺開源專案(10)FluentValidation驗證元件深入使用(二)

    在上一篇文章:.NET平臺開源專案速覽(6)FluentValidation驗證元件介紹與入門(一) 中,給大家初步介紹了一下FluentValidation驗證元件的使用情況。文章從構建間的驗證器開始,到最後的結果,以及複雜驗證等都做了比較深入的講解和使用。但其實一個完整的元件是麻雀雖小五臟俱全

.NET平臺開源專案(2)Compare .NET Objects物件比較元件

    .NET平臺開源專案速覽今天介紹一款小巧強大的物件比較元件。可以更詳細的獲取2個物件的差別,並記錄具體差別,比較過程和要求可以靈活配置。 1.Compare .NET Objects介紹     Compare .NET Objects元件是.NET平臺用於深入比較2個.NET物件的開源元

.NET平臺開源專案(13)機器學習元件Accord.NET框架功能介紹

    Accord.NET Framework是在AForge.NET專案的基礎上封裝和進一步開發而來。因為AForge.NET更注重與一些底層和廣度,而Accord.NET Framework更注重與機器學習演算法以及提供計算機視訊、音訊、訊號處理以及統計應用相關的解決方案。該專案使用C#語言編寫,專

.NET平臺開源專案(5)深入使用與擴充套件SharpConfig元件

  上個月在文章:這些.NET開源專案你知道嗎?讓.NET開源來得更加猛烈些吧  和 .NET平臺開源專案速覽(1)SharpConfig配置檔案讀寫元件 中都提到了SharpConfig元件,簡單輕量級,速度快,而且還有比較深入的使用介紹。在文章釋出後,也有網友提到一些問題,當時我也沒仔細去分析,在這次我親

.NET平臺開源專案(8)Expression Evaluator表示式計算元件使用

  在文章:這些.NET開源專案你知道嗎?讓.NET開源來得更加猛烈些吧!(第二輯)中,給大家初步介紹了一下Expression Evaluator驗證元件。那裡只是概述了一下,並沒有對其使用和強大功能做深入研究,所以今天就通過一篇簡單的文章來預覽一下其強大的功能。本文曾在【原創】.NET開源表示式計算元

.NET平臺開源專案(4).NET文件生成工具ADB及使用

    很久以前就使用ADB這個工具來生成專案的幫助文件。功能強大,在學習一些開源專案的過程中,官方沒有提供CHM幫助文件,所以為了快速的瞭解專案結構和註釋。就生成文件來自己看,非常好用。這也是一個學習方法吧。例如本文在:   上述2篇文章中最後的資源中就手動製作了CHM幫助文件。有時候我們還可

.NET平臺開源專案(6)FluentValidation驗證元件介紹與入門(一)

    在文章:這些.NET開源專案你知道嗎?讓.NET開源來得更加猛烈些吧!(第二輯)中,給大家初步介紹了一下FluentValidation驗證元件。那裡只是概述了一下,並沒有對其使用和強大功能做深入研究,所以今天以及接下去的幾篇文章就專門介紹這個元件。不僅僅是它小,輕量級,優雅,而且一直在持續更新中

.NET平臺開源專案(12)雜湊演算法集合類庫HashLib

    .NET的System.Security.Cryptography名稱空間本身是提供加密服務,雜湊函式,對稱與非對稱加密演算法等功能。實際上,大部分情況下已經滿足了需求,而且.NET實現的都是目前國際上比較權威的,標準化的演算法,所以還是安全可靠的。但也有一些場合,需要自己實現一些安全雜湊演算法。

.NET平臺開源專案(18)C#平臺JSON實體類生成器JSON C# Class Generator

    去年,我在一篇文章用原始方法解析複雜字串,json一定要用JsonMapper麼?中介紹了簡單的JSON解析的問題,那種方法在當時的環境是非常方便的,因為不需要生成實體類,結構很容易解析。但隨著業務的變化,也會碰到超級變態的JSON,如果還按照以前的思路,會把人搞抽風掉,一旦結構變化,又要重來。所

.NET平臺開源專案(16)C#寫PDF檔案類庫PDF File Writer介紹

    1年前,我在文章:這些.NET開源專案你知道嗎?.NET平臺開源文件與報表處理元件集合(三)中(第9個專案),給大家推薦了一個開源免費的PDF讀寫元件 PDFSharp,PDFSharp我2年前就看過,用過簡單的例子,不過程式碼沒有寫成專門的文章。最近在查詢資料的時候,又發現一款小巧的寫PDF檔案