1 #Region "Microsoft.VisualBasic::0c3e852a5ac5d3e681d3d88fdeea1ba6, Microsoft.VisualBasic.Core\ComponentModel\Algorithm\base\Combination\Combination.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module Combination
35     
36     '         Function: CreateCombos, FullCombination, Generate, (+2 Overloads) Iterates, Iteration
37     
38     
39     ' /********************************************************************************/
40
41 #End Region
42
43 Imports System.Runtime.CompilerServices
44 Imports Microsoft.VisualBasic.Language
45 Imports Microsoft.VisualBasic.Linq
46
47 Namespace ComponentModel.Algorithm.base
48
49     ''' <summary>
50     ''' 任意多个集合之间的对象之间相互组成组合输出
51     ''' </summary>
52     ''' <remarks></remarks>
53     Public Module Combination
54
55         ''' <summary>
56         ''' 生成两个序列的两两组合 ``{<paramref name="seq_1"/> -> <paramref name="seq_2"/>}()``
57         ''' </summary>
58         ''' <typeparam name="TA"></typeparam>
59         ''' <typeparam name="TB"></typeparam>
60         ''' <param name="seq_1"></param>
61         ''' <param name="seq_2"></param>
62         ''' <returns></returns>
63         <Extension>
64         Public Iterator Function CreateCombos(Of TA, TB)(seq_1 As IEnumerable(Of TA), seq_2 As IEnumerable(Of TB)) As IEnumerable(Of (a As TA, b As TB))
65             Dim b As TB() = seq_2.ToArray
66
67             For Each i As TA In seq_1
68                 For Each j As TB In b
69                     Yield (i, j)
70                 Next
71             Next
72         End Function
73
74         <MethodImpl(MethodImplOptions.AggressiveInlining)>
75         <Extension>
76         Public Function FullCombination(Of T)(seq As IEnumerable(Of T)) As IEnumerable(Of (a As T, b As T))
77             With seq.ToArray
78                 Return .CreateCombos(.ByRef)
79             End With
80         End Function
81
82         <Extension> Public Iterator Function Iteration(Of T)(source As T()()) As IEnumerable(Of T())
83             Dim first As T() = source.First
84
85             If source.Length = 2 Then ' 只剩下两个的时候,会退出递归操作
86                 Dim last As T() = source.Last
87
88                 For Each x As T In first
89                     For Each _item As T In last
90                         Yield {x, _item}
91                     Next
92                 Next
93             Else
94                 For Each x As T In first
95                     For Each subArray As T() In source.Skip(1).ToArray.Iteration   ' 递归组合迭代
96                         Yield New List(Of T)(x) + subArray
97                     Next
98                 Next
99             End If
100         End Function
101
102         Public Function Generate(Of T)(source As T()()) As T()()
103             Return source.Iteration.ToArray
104         End Function
105
106         <Extension>
107         Public Iterator Function Iterates(Of T)(comb As (T, T)) As IEnumerable(Of T)
108             Yield comb.Item1
109             Yield comb.Item2
110         End Function
111
112         <Extension>
113         Public Iterator Function Iterates(Of T)(comb As Tuple(Of T, T)) As IEnumerable(Of T)
114             Yield comb.Item1
115             Yield comb.Item2
116         End Function
117     End Module
118 End Namespace