├── .gitignore ├── Apriori.ncrunchsolution ├── Apriori.ncrunchsolution.user ├── Apriori.sln ├── Apriori.sln.docstates.suo ├── Apriori.suo ├── Apriori.vsmdi ├── AprioriAlgorithm ├── AprioriAlgorithm.csproj ├── AprioriAlgorithm.ncrunchproject ├── ContainerProvider.cs ├── Contracts │ ├── IApriori.cs │ └── ISorter.cs ├── Entities │ ├── Item.cs │ ├── Output.cs │ └── Rule.cs ├── Implementation │ ├── Apriori.cs │ └── Sorter.cs ├── IndexedDictionary.cs ├── Properties │ └── AssemblyInfo.cs ├── bin │ └── Debug │ │ ├── AprioriAlgorithm.dll │ │ └── AprioriAlgorithm.pdb └── obj │ └── Debug │ ├── AprioriAlgorithm.csproj.FileListAbsolute.txt │ ├── AprioriAlgorithm.dll │ ├── AprioriAlgorithm.pdb │ └── DesignTimeResolveAssemblyReferencesInput.cache ├── Local.testsettings ├── README.md ├── References ├── Moq.dll ├── Moq.pdb └── Moq.xml ├── TraceAndTestImpact.testsettings ├── UnitTests ├── AprioriAlgorithm Tests │ ├── AprioriTest.cs │ └── SorterTest.cs ├── ObservableSetTest.cs ├── Properties │ └── AssemblyInfo.cs ├── Test References │ └── AprioriAlgorithm.accessor ├── UI Tests │ ├── CharacterOnlyRuleTest.cs │ └── MainViewModelTest.cs ├── UnitTests.csproj ├── UnitTests.ncrunchproject ├── bin │ └── Debug │ │ ├── AprioriAlgorithm.dll │ │ ├── AprioriAlgorithm.pdb │ │ ├── AprioriAlgorithm_Accessor.dll │ │ ├── AprioriAlgorithm_Accessor.pdb │ │ ├── Moq.dll │ │ ├── Moq.pdb │ │ ├── Moq.xml │ │ ├── UnitTests.dll │ │ ├── UnitTests.pdb │ │ ├── WPFClient.exe │ │ └── WPFClient.pdb └── obj │ └── Debug │ ├── AprioriAlgorithm_Accessor.dll │ ├── AprioriAlgorithm_Accessor.pdb │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ ├── ResolveAssemblyReference.cache │ ├── UnitTests.csproj.FileListAbsolute.txt │ ├── UnitTests.dll │ ├── UnitTests.pdb │ ├── WPFClient_Accessor.exe │ └── WPFClient_Accessor.pdb ├── WPFClient ├── Abstract │ └── IResult.cs ├── App.xaml ├── App.xaml.cs ├── Commands │ └── RelayCommand.cs ├── ContainerProvider.cs ├── Models │ ├── Item.cs │ └── ObservableSet.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── ValidationRules │ └── CharacterOnlyRule.cs ├── ViewModels │ ├── MainViewModel.cs │ └── ViewModelBase.cs ├── Views │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Result.xaml │ └── Result.xaml.cs ├── WPFClient.csproj ├── WPFClient.ncrunchproject ├── bin │ └── Debug │ │ ├── AprioriAlgorithm.dll │ │ ├── AprioriAlgorithm.pdb │ │ ├── WPFClient.exe │ │ ├── WPFClient.pdb │ │ └── WPFClient.vshost.exe └── obj │ └── x86 │ └── Debug │ ├── App.g.cs │ ├── App.g.i.cs │ ├── DesignTimeResolveAssemblyReferences.cache │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ ├── GenerateResource.read.1.tlog │ ├── GenerateResource.write.1.tlog │ ├── GeneratedInternalTypeHelper.g.cs │ ├── GeneratedInternalTypeHelper.g.i.cs │ ├── MainWindow.g.i.cs │ ├── ResolveAssemblyReference.cache │ ├── Result.g.i.cs │ ├── TempPE │ └── Properties.Resources.Designer.cs.dll │ ├── Views │ ├── MainWindow.baml │ ├── MainWindow.g.cs │ ├── MainWindow.g.i.cs │ ├── Result.baml │ ├── Result.g.cs │ └── Result.g.i.cs │ ├── WPFClient.Properties.Resources.resources │ ├── WPFClient.csproj.FileListAbsolute.txt │ ├── WPFClient.exe │ ├── WPFClient.g.resources │ ├── WPFClient.pdb │ ├── WPFClient_MarkupCompile.cache │ ├── WPFClient_MarkupCompile.i.cache │ ├── WPFClient_MarkupCompile.i.lref │ └── WPFClient_MarkupCompile.lref └── _NCrunch_Apriori └── Apriori.crunchsolution.cache /.gitignore: -------------------------------------------------------------------------------- 1 | /TestResults 2 | -------------------------------------------------------------------------------- /Apriori.ncrunchsolution: -------------------------------------------------------------------------------- 1 | 2 | 1 3 | False 4 | true 5 | UseDynamicAnalysis 6 | UseStaticAnalysis 7 | UseStaticAnalysis 8 | UseStaticAnalysis 9 | Run all tests automatically:BFRydWU=;Run all tests manually:BUZhbHNl;Run impacted tests automatically, others manually (experimental!):CklzSW1wYWN0ZWQ=;Run pinned tests automatically, others manually:CElzUGlubmVk 10 | 11 | 12 | -------------------------------------------------------------------------------- /Apriori.ncrunchsolution.user: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/Apriori.ncrunchsolution.user -------------------------------------------------------------------------------- /Apriori.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AprioriAlgorithm", "AprioriAlgorithm\AprioriAlgorithm.csproj", "{49F14BB7-E49E-4574-8038-25ABB6D5CF46}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{C82787D0-76FA-49D9-8894-78F2644A7000}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8979F4F3-23F8-40A0-AB35-7882426FD50F}" 9 | ProjectSection(SolutionItems) = preProject 10 | Apriori.vsmdi = Apriori.vsmdi 11 | Local.testsettings = Local.testsettings 12 | TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings 13 | EndProjectSection 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFClient", "WPFClient\WPFClient.csproj", "{B20F3B49-50C0-4160-BA1B-87FDF077CD79}" 16 | EndProject 17 | Global 18 | GlobalSection(TestCaseManagementSettings) = postSolution 19 | CategoryFile = Apriori.vsmdi 20 | EndGlobalSection 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Debug|Mixed Platforms = Debug|Mixed Platforms 24 | Debug|x86 = Debug|x86 25 | Release|Any CPU = Release|Any CPU 26 | Release|Mixed Platforms = Release|Mixed Platforms 27 | Release|x86 = Release|x86 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 33 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 34 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Debug|x86.ActiveCfg = Debug|Any CPU 35 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 38 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Release|Mixed Platforms.Build.0 = Release|Any CPU 39 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46}.Release|x86.ActiveCfg = Release|Any CPU 40 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 43 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 44 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Debug|x86.ActiveCfg = Debug|Any CPU 45 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 48 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Release|Mixed Platforms.Build.0 = Release|Any CPU 49 | {C82787D0-76FA-49D9-8894-78F2644A7000}.Release|x86.ActiveCfg = Release|Any CPU 50 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Debug|Any CPU.ActiveCfg = Debug|x86 51 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 52 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Debug|Mixed Platforms.Build.0 = Debug|x86 53 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Debug|x86.ActiveCfg = Debug|x86 54 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Debug|x86.Build.0 = Debug|x86 55 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Release|Any CPU.ActiveCfg = Release|x86 56 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Release|Mixed Platforms.ActiveCfg = Release|x86 57 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Release|Mixed Platforms.Build.0 = Release|x86 58 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Release|x86.ActiveCfg = Release|x86 59 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79}.Release|x86.Build.0 = Release|x86 60 | EndGlobalSection 61 | GlobalSection(SolutionProperties) = preSolution 62 | HideSolutionNode = FALSE 63 | EndGlobalSection 64 | EndGlobal 65 | -------------------------------------------------------------------------------- /Apriori.sln.docstates.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/Apriori.sln.docstates.suo -------------------------------------------------------------------------------- /Apriori.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/Apriori.suo -------------------------------------------------------------------------------- /Apriori.vsmdi: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AprioriAlgorithm/AprioriAlgorithm.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46} 9 | Library 10 | Properties 11 | AprioriAlgorithm 12 | AprioriAlgorithm 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /AprioriAlgorithm/AprioriAlgorithm.ncrunchproject: -------------------------------------------------------------------------------- 1 | 2 | false 3 | false 4 | false 5 | true 6 | false 7 | false 8 | false 9 | false 10 | true 11 | true 12 | false 13 | true 14 | true 15 | 60000 16 | 17 | 18 | 19 | AutoDetect 20 | -------------------------------------------------------------------------------- /AprioriAlgorithm/ContainerProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition.Hosting; 3 | 4 | namespace AprioriAlgorithm 5 | { 6 | internal static class ContainerProvider 7 | { 8 | private static CompositionContainer container; 9 | 10 | public static CompositionContainer Container 11 | { 12 | get 13 | { 14 | if (container == null) 15 | { 16 | List catalogList = new List(); 17 | catalogList.Add(new AssemblyCatalog(typeof(ISorter).Assembly)); 18 | container = new CompositionContainer(new AggregateCatalog(catalogList)); 19 | } 20 | 21 | return container; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /AprioriAlgorithm/Contracts/IApriori.cs: -------------------------------------------------------------------------------- 1 | namespace AprioriAlgorithm 2 | { 3 | using System.Collections.Generic; 4 | 5 | public interface IApriori 6 | { 7 | Output ProcessTransaction(double minSupport, double minConfidence, IEnumerable items, string[] transactions); 8 | } 9 | } -------------------------------------------------------------------------------- /AprioriAlgorithm/Contracts/ISorter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | namespace AprioriAlgorithm 3 | { 4 | interface ISorter 5 | { 6 | string Sort(string token); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /AprioriAlgorithm/Entities/Item.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace AprioriAlgorithm 3 | { 4 | public class Item : IComparable 5 | { 6 | #region Public Properties 7 | 8 | public string Name { get; set; } 9 | public double Support { get; set; } 10 | 11 | #endregion 12 | 13 | #region IComparable 14 | 15 | public int CompareTo(Item other) 16 | { 17 | return Name.CompareTo(other.Name); 18 | } 19 | 20 | #endregion 21 | } 22 | } -------------------------------------------------------------------------------- /AprioriAlgorithm/Entities/Output.cs: -------------------------------------------------------------------------------- 1 | namespace AprioriAlgorithm 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class Output 6 | { 7 | #region Public Properties 8 | 9 | public IList StrongRules { get; set; } 10 | 11 | public IList MaximalItemSets { get; set; } 12 | 13 | public Dictionary> ClosedItemSets { get; set; } 14 | 15 | public ItemsDictionary FrequentItems { get; set; } 16 | 17 | #endregion 18 | } 19 | } -------------------------------------------------------------------------------- /AprioriAlgorithm/Entities/Rule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AprioriAlgorithm 4 | { 5 | public class Rule : IComparable 6 | { 7 | #region Member Variables 8 | 9 | string combination, remaining; 10 | double confidence; 11 | 12 | #endregion 13 | 14 | #region Constructor 15 | 16 | public Rule(string combination, string remaining, double confidence) 17 | { 18 | this.combination = combination; 19 | this.remaining = remaining; 20 | this.confidence = confidence; 21 | } 22 | 23 | #endregion 24 | 25 | #region Public Properties 26 | 27 | public string X { get { return combination; } } 28 | 29 | public string Y { get { return remaining; } } 30 | 31 | public double Confidence { get { return confidence; } } 32 | 33 | #endregion 34 | 35 | #region IComparable Members 36 | 37 | public int CompareTo(Rule other) 38 | { 39 | return X.CompareTo(other.X); 40 | } 41 | 42 | #endregion 43 | 44 | public override int GetHashCode() 45 | { 46 | ISorter sorter = new Sorter(); 47 | string sortedXY = sorter.Sort(X + Y); 48 | return sortedXY.GetHashCode(); 49 | } 50 | 51 | public override bool Equals(object obj) 52 | { 53 | var other = obj as Rule; 54 | if (other == null) 55 | { 56 | return false; 57 | } 58 | 59 | return other.X == this.X && other.Y == this.Y || 60 | other.X == this.Y && other.Y == this.X; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /AprioriAlgorithm/Implementation/Apriori.cs: -------------------------------------------------------------------------------- 1 | namespace AprioriAlgorithm 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.ComponentModel.Composition; 6 | using System.Text; 7 | 8 | [Export(typeof(IApriori))] 9 | public class Apriori : IApriori 10 | { 11 | #region Member Variables 12 | 13 | readonly ISorter _sorter; 14 | 15 | #endregion 16 | 17 | #region Constructor 18 | 19 | public Apriori() 20 | { 21 | _sorter = ContainerProvider.Container.GetExportedValue(); 22 | } 23 | 24 | #endregion 25 | 26 | #region IApriori 27 | 28 | Output IApriori.ProcessTransaction(double minSupport, double minConfidence, IEnumerable items, string[] transactions) 29 | { 30 | IList frequentItems = GetL1FrequentItems(minSupport, items, transactions); 31 | ItemsDictionary allFrequentItems = new ItemsDictionary(); 32 | allFrequentItems.ConcatItems(frequentItems); 33 | IDictionary candidates = new Dictionary(); 34 | double transactionsCount = transactions.Count(); 35 | 36 | do 37 | { 38 | candidates = GenerateCandidates(frequentItems, transactions); 39 | frequentItems = GetFrequentItems(candidates, minSupport, transactionsCount); 40 | allFrequentItems.ConcatItems(frequentItems); 41 | } 42 | while (candidates.Count != 0); 43 | 44 | HashSet rules = GenerateRules(allFrequentItems); 45 | IList strongRules = GetStrongRules(minConfidence, rules, allFrequentItems); 46 | Dictionary> closedItemSets = GetClosedItemSets(allFrequentItems); 47 | IList maximalItemSets = GetMaximalItemSets(closedItemSets); 48 | 49 | return new Output 50 | { 51 | StrongRules = strongRules, 52 | MaximalItemSets = maximalItemSets, 53 | ClosedItemSets = closedItemSets, 54 | FrequentItems = allFrequentItems 55 | }; 56 | } 57 | 58 | #endregion 59 | 60 | #region Private Methods 61 | 62 | private List GetL1FrequentItems(double minSupport, IEnumerable items, IEnumerable transactions) 63 | { 64 | var frequentItemsL1 = new List(); 65 | double transactionsCount = transactions.Count(); 66 | 67 | foreach (var item in items) 68 | { 69 | double support = GetSupport(item, transactions); 70 | 71 | if (support / transactionsCount >= minSupport) 72 | { 73 | frequentItemsL1.Add(new Item { Name = item, Support = support }); 74 | } 75 | } 76 | frequentItemsL1.Sort(); 77 | return frequentItemsL1; 78 | } 79 | 80 | private double GetSupport(string generatedCandidate, IEnumerable transactionsList) 81 | { 82 | double support = 0; 83 | 84 | foreach (string transaction in transactionsList) 85 | { 86 | if (CheckIsSubset(generatedCandidate, transaction)) 87 | { 88 | support++; 89 | } 90 | } 91 | 92 | return support; 93 | } 94 | 95 | private bool CheckIsSubset(string child, string parent) 96 | { 97 | foreach (char c in child) 98 | { 99 | if (!parent.Contains(c)) 100 | { 101 | return false; 102 | } 103 | } 104 | 105 | return true; 106 | } 107 | 108 | private Dictionary GenerateCandidates(IList frequentItems, IEnumerable transactions) 109 | { 110 | Dictionary candidates = new Dictionary(); 111 | 112 | for (int i = 0; i < frequentItems.Count - 1; i++) 113 | { 114 | string firstItem = _sorter.Sort(frequentItems[i].Name); 115 | 116 | for (int j = i + 1; j < frequentItems.Count; j++) 117 | { 118 | string secondItem = _sorter.Sort(frequentItems[j].Name); 119 | string generatedCandidate = GenerateCandidate(firstItem, secondItem); 120 | 121 | if (generatedCandidate != string.Empty) 122 | { 123 | double support = GetSupport(generatedCandidate, transactions); 124 | candidates.Add(generatedCandidate, support); 125 | } 126 | } 127 | } 128 | 129 | return candidates; 130 | } 131 | 132 | private string GenerateCandidate(string firstItem, string secondItem) 133 | { 134 | int length = firstItem.Length; 135 | 136 | if (length == 1) 137 | { 138 | return firstItem + secondItem; 139 | } 140 | else 141 | { 142 | string firstSubString = firstItem.Substring(0, length - 1); 143 | string secondSubString = secondItem.Substring(0, length - 1); 144 | 145 | if (firstSubString == secondSubString) 146 | { 147 | return firstItem + secondItem[length - 1]; 148 | } 149 | 150 | return string.Empty; 151 | } 152 | } 153 | 154 | private List GetFrequentItems(IDictionary candidates, double minSupport, double transactionsCount) 155 | { 156 | var frequentItems = new List(); 157 | 158 | foreach (var item in candidates) 159 | { 160 | if (item.Value / transactionsCount >= minSupport) 161 | { 162 | frequentItems.Add(new Item { Name = item.Key, Support = item.Value }); 163 | } 164 | } 165 | 166 | return frequentItems; 167 | } 168 | 169 | private Dictionary> GetClosedItemSets(ItemsDictionary allFrequentItems) 170 | { 171 | var closedItemSets = new Dictionary>(); 172 | int i = 0; 173 | 174 | foreach (var item in allFrequentItems) 175 | { 176 | Dictionary parents = GetItemParents(item.Name, ++i, allFrequentItems); 177 | 178 | if (CheckIsClosed(item.Name, parents, allFrequentItems)) 179 | { 180 | closedItemSets.Add(item.Name, parents); 181 | } 182 | } 183 | 184 | return closedItemSets; 185 | } 186 | 187 | private Dictionary GetItemParents(string child, int index, ItemsDictionary allFrequentItems) 188 | { 189 | var parents = new Dictionary(); 190 | 191 | for (int j = index; j < allFrequentItems.Count; j++) 192 | { 193 | string parent = allFrequentItems[j].Name; 194 | 195 | if (parent.Length == child.Length + 1) 196 | { 197 | if (CheckIsSubset(child, parent)) 198 | { 199 | parents.Add(parent, allFrequentItems[parent].Support); 200 | } 201 | } 202 | } 203 | 204 | return parents; 205 | } 206 | 207 | private bool CheckIsClosed(string child, Dictionary parents, ItemsDictionary allFrequentItems) 208 | { 209 | foreach (string parent in parents.Keys) 210 | { 211 | if (allFrequentItems[child].Support == allFrequentItems[parent].Support) 212 | { 213 | return false; 214 | } 215 | } 216 | 217 | return true; 218 | } 219 | 220 | private IList GetMaximalItemSets(Dictionary> closedItemSets) 221 | { 222 | var maximalItemSets = new List(); 223 | 224 | foreach (var item in closedItemSets) 225 | { 226 | Dictionary parents = item.Value; 227 | 228 | if (parents.Count == 0) 229 | { 230 | maximalItemSets.Add(item.Key); 231 | } 232 | } 233 | 234 | return maximalItemSets; 235 | } 236 | 237 | private HashSet GenerateRules(ItemsDictionary allFrequentItems) 238 | { 239 | var rulesList = new HashSet(); 240 | 241 | foreach (var item in allFrequentItems) 242 | { 243 | if (item.Name.Length > 1) 244 | { 245 | IEnumerable subsetsList = GenerateSubsets(item.Name); 246 | 247 | foreach (var subset in subsetsList) 248 | { 249 | string remaining = GetRemaining(subset, item.Name); 250 | Rule rule = new Rule(subset, remaining, 0); 251 | 252 | if (!rulesList.Contains(rule)) 253 | { 254 | rulesList.Add(rule); 255 | } 256 | } 257 | } 258 | } 259 | 260 | return rulesList; 261 | } 262 | 263 | private IEnumerable GenerateSubsets(string item) 264 | { 265 | IEnumerable allSubsets = new string[] { }; 266 | int subsetLength = item.Length / 2; 267 | 268 | for (int i = 1; i <= subsetLength; i++) 269 | { 270 | IList subsets = new List(); 271 | GenerateSubsetsRecursive(item, i, new char[item.Length], subsets); 272 | allSubsets = allSubsets.Concat(subsets); 273 | } 274 | 275 | return allSubsets; 276 | } 277 | 278 | private void GenerateSubsetsRecursive(string item, int subsetLength, char[] temp, IList subsets, int q = 0, int r = 0) 279 | { 280 | if (q == subsetLength) 281 | { 282 | StringBuilder sb = new StringBuilder(); 283 | 284 | for (int i = 0; i < subsetLength; i++) 285 | { 286 | sb.Append(temp[i]); 287 | } 288 | 289 | subsets.Add(sb.ToString()); 290 | } 291 | 292 | else 293 | { 294 | for (int i = r; i < item.Length; i++) 295 | { 296 | temp[q] = item[i]; 297 | GenerateSubsetsRecursive(item, subsetLength, temp, subsets, q + 1, i + 1); 298 | } 299 | } 300 | } 301 | 302 | private string GetRemaining(string child, string parent) 303 | { 304 | for (int i = 0; i < child.Length; i++) 305 | { 306 | int index = parent.IndexOf(child[i]); 307 | parent = parent.Remove(index, 1); 308 | } 309 | 310 | return parent; 311 | } 312 | 313 | private IList GetStrongRules(double minConfidence, HashSet rules, ItemsDictionary allFrequentItems) 314 | { 315 | var strongRules = new List(); 316 | 317 | foreach (Rule rule in rules) 318 | { 319 | string xy = _sorter.Sort(rule.X + rule.Y); 320 | AddStrongRule(rule, xy, strongRules, minConfidence, allFrequentItems); 321 | } 322 | 323 | strongRules.Sort(); 324 | return strongRules; 325 | } 326 | 327 | private void AddStrongRule(Rule rule, string XY, List strongRules, double minConfidence, ItemsDictionary allFrequentItems) 328 | { 329 | double confidence = GetConfidence(rule.X, XY, allFrequentItems); 330 | 331 | if (confidence >= minConfidence) 332 | { 333 | Rule newRule = new Rule(rule.X, rule.Y, confidence); 334 | strongRules.Add(newRule); 335 | } 336 | 337 | confidence = GetConfidence(rule.Y, XY, allFrequentItems); 338 | 339 | if (confidence >= minConfidence) 340 | { 341 | Rule newRule = new Rule(rule.Y, rule.X, confidence); 342 | strongRules.Add(newRule); 343 | } 344 | } 345 | 346 | private double GetConfidence(string X, string XY, ItemsDictionary allFrequentItems) 347 | { 348 | double supportX = allFrequentItems[X].Support; 349 | double supportXY = allFrequentItems[XY].Support; 350 | return supportXY / supportX; 351 | } 352 | 353 | #endregion 354 | } 355 | } -------------------------------------------------------------------------------- /AprioriAlgorithm/Implementation/Sorter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.Composition; 3 | using System.Collections.Generic; 4 | 5 | namespace AprioriAlgorithm 6 | { 7 | [Export(typeof(ISorter))] 8 | class Sorter : ISorter 9 | { 10 | string ISorter.Sort(string token) 11 | { 12 | char[] tokenArray = token.ToCharArray(); 13 | Array.Sort(tokenArray); 14 | return new string(tokenArray); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /AprioriAlgorithm/IndexedDictionary.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using System.Collections.Generic; 3 | 4 | namespace AprioriAlgorithm 5 | { 6 | public class ItemsDictionary : KeyedCollection 7 | { 8 | protected override string GetKeyForItem(Item item) 9 | { 10 | return item.Name; 11 | } 12 | 13 | internal void ConcatItems(IList frequentItems) 14 | { 15 | foreach (var item in frequentItems) 16 | { 17 | this.Add(item); 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /AprioriAlgorithm/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("AprioriAlgorithm")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("AprioriAlgorithm")] 13 | [assembly: AssemblyCopyright("Copyright © 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("19c54d58-c13a-43ff-aaef-a410e67393fd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | 38 | [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("UnitTests")] -------------------------------------------------------------------------------- /AprioriAlgorithm/bin/Debug/AprioriAlgorithm.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/AprioriAlgorithm/bin/Debug/AprioriAlgorithm.dll -------------------------------------------------------------------------------- /AprioriAlgorithm/bin/Debug/AprioriAlgorithm.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/AprioriAlgorithm/bin/Debug/AprioriAlgorithm.pdb -------------------------------------------------------------------------------- /AprioriAlgorithm/obj/Debug/AprioriAlgorithm.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\Omar\Downloads\2-Apriori Source Code\AprioriAlgorithm\bin\Debug\AprioriAlgorithm.dll 2 | C:\Users\Omar\Downloads\2-Apriori Source Code\AprioriAlgorithm\bin\Debug\AprioriAlgorithm.pdb 3 | C:\Users\Omar\Downloads\2-Apriori Source Code\AprioriAlgorithm\obj\Debug\ResolveAssemblyReference.cache 4 | C:\Users\Omar\Downloads\2-Apriori Source Code\AprioriAlgorithm\obj\Debug\AprioriAlgorithm.dll 5 | C:\Users\Omar\Downloads\2-Apriori Source Code\AprioriAlgorithm\obj\Debug\AprioriAlgorithm.pdb 6 | C:\Users\Omar\Desktop\Git\Apriori Source Code\AprioriAlgorithm\bin\Debug\AprioriAlgorithm.dll 7 | C:\Users\Omar\Desktop\Git\Apriori Source Code\AprioriAlgorithm\bin\Debug\AprioriAlgorithm.pdb 8 | C:\Users\Omar\Desktop\Git\Apriori Source Code\AprioriAlgorithm\obj\Debug\ResolveAssemblyReference.cache 9 | C:\Users\Omar\Desktop\Git\Apriori Source Code\AprioriAlgorithm\obj\Debug\AprioriAlgorithm.dll 10 | C:\Users\Omar\Desktop\Git\Apriori Source Code\AprioriAlgorithm\obj\Debug\AprioriAlgorithm.pdb 11 | D:\Git\Apriori Source Code\AprioriAlgorithm\bin\Debug\AprioriAlgorithm.dll 12 | D:\Git\Apriori Source Code\AprioriAlgorithm\bin\Debug\AprioriAlgorithm.pdb 13 | D:\Git\Apriori Source Code\AprioriAlgorithm\obj\Debug\ResolveAssemblyReference.cache 14 | D:\Git\Apriori Source Code\AprioriAlgorithm\obj\Debug\AprioriAlgorithm.dll 15 | D:\Git\Apriori Source Code\AprioriAlgorithm\obj\Debug\AprioriAlgorithm.pdb 16 | -------------------------------------------------------------------------------- /AprioriAlgorithm/obj/Debug/AprioriAlgorithm.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/AprioriAlgorithm/obj/Debug/AprioriAlgorithm.dll -------------------------------------------------------------------------------- /AprioriAlgorithm/obj/Debug/AprioriAlgorithm.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/AprioriAlgorithm/obj/Debug/AprioriAlgorithm.pdb -------------------------------------------------------------------------------- /AprioriAlgorithm/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/AprioriAlgorithm/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /Local.testsettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | These are default test settings for a local test run. 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Apriori-Algorithm 2 | ================= 3 | 4 | Apriori is a classic algorithm for learning association rules. 5 | Apriori is designed to operate on databases containing transactions (for example, collections of items bought by customers, or details of a website frequentation). 6 | 7 | 8 | for more info visit: 9 | http://www.codeproject.com/Articles/70371/Apriori-Algorithm -------------------------------------------------------------------------------- /References/Moq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/References/Moq.dll -------------------------------------------------------------------------------- /References/Moq.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/References/Moq.pdb -------------------------------------------------------------------------------- /TraceAndTestImpact.testsettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | These are test settings for Trace and Test Impact. 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /UnitTests/AprioriAlgorithm Tests/AprioriTest.cs: -------------------------------------------------------------------------------- 1 | using AprioriAlgorithm; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System; 6 | 7 | namespace UnitTests 8 | { 9 | [TestClass()] 10 | public class AprioriTest 11 | { 12 | #region Member Variables 13 | 14 | readonly double _minSupport; 15 | readonly double _minConfidence; 16 | readonly IEnumerable _items; 17 | readonly string[] _transactions; 18 | readonly Apriori_Accessor _target; 19 | 20 | #endregion 21 | 22 | #region Constructor 23 | 24 | public AprioriTest() 25 | { 26 | _minSupport = .5; 27 | _minConfidence = .8; 28 | _items = new string[5] { "a", "b", "c", "d", "e" }; 29 | _transactions = new string[4] { "acd", "bce", "abce", "be" }; 30 | _target = new Apriori_Accessor(); 31 | } 32 | 33 | #endregion 34 | 35 | #region Test Methods 36 | 37 | [TestMethod()] 38 | public void ProcessTransactionTest() 39 | { 40 | //Arrange 41 | IApriori target = new Apriori(); 42 | 43 | //Act 44 | Output actual = target.ProcessTransaction(_minSupport, _minConfidence, _items, _transactions); 45 | 46 | //Assert 47 | Assert.AreEqual(9, actual.FrequentItems.Count); 48 | Assert.AreEqual(2, actual.FrequentItems["a"].Support); 49 | Assert.AreEqual(3, actual.FrequentItems["b"].Support); 50 | Assert.AreEqual(3, actual.FrequentItems["c"].Support); 51 | Assert.AreEqual(3, actual.FrequentItems["e"].Support); 52 | Assert.AreEqual(2, actual.FrequentItems["ac"].Support); 53 | Assert.AreEqual(2, actual.FrequentItems["bc"].Support); 54 | Assert.AreEqual(3, actual.FrequentItems["be"].Support); 55 | Assert.AreEqual(2, actual.FrequentItems["ce"].Support); 56 | Assert.AreEqual(2, actual.FrequentItems["bce"].Support); 57 | 58 | Assert.AreEqual(2, actual.MaximalItemSets.Count); 59 | Assert.AreEqual("ac", actual.MaximalItemSets[0]); 60 | Assert.AreEqual("bce", actual.MaximalItemSets[1]); 61 | 62 | Assert.AreEqual(5, actual.StrongRules.Count); 63 | } 64 | 65 | [TestMethod()] 66 | public void GetL1FrequentItemsTest() 67 | { 68 | //Act 69 | IList actual = _target.GetL1FrequentItems(_minSupport, _items, _transactions); 70 | 71 | //Assert 72 | Assert.AreEqual(4, actual.Count); 73 | Assert.AreEqual(2, actual[0].Support); 74 | Assert.AreEqual(3, actual[1].Support); 75 | Assert.AreEqual(3, actual[2].Support); 76 | Assert.AreEqual(3, actual[3].Support); 77 | } 78 | 79 | [TestMethod()] 80 | public void GetSupportTest() 81 | { 82 | //Arrange 83 | string candidate = "a"; 84 | 85 | //Act 86 | double actual = _target.GetSupport(candidate, _transactions); 87 | 88 | //Assert 89 | Assert.AreEqual(2, actual); 90 | } 91 | 92 | [TestMethod()] 93 | public void CheckIsSubsetTest() 94 | { 95 | //Arrange 96 | string child = "abc"; 97 | string parent = "abcde"; 98 | 99 | //Act 100 | bool actual = _target.CheckIsSubset(child, parent); 101 | 102 | //Assert 103 | Assert.IsTrue(actual); 104 | } 105 | 106 | [TestMethod()] 107 | public void GenerateCandidatesTest() 108 | { 109 | //Arrange 110 | var frequentItems = new List 111 | { 112 | new Item {Name= "a",Support=2}, 113 | new Item {Name= "b",Support=3}, 114 | new Item {Name= "c",Support=3}, 115 | new Item {Name= "e",Support=3}, 116 | }; 117 | 118 | //Act 119 | Dictionary actual = _target.GenerateCandidates(frequentItems, _transactions); 120 | 121 | //Assert 122 | Assert.AreEqual(actual.Count, 6); 123 | 124 | Assert.AreEqual(actual["ab"], 1); 125 | Assert.AreEqual(actual["ac"], 2); 126 | Assert.AreEqual(actual["ae"], 1); 127 | Assert.AreEqual(actual["bc"], 2); 128 | Assert.AreEqual(actual["be"], 3); 129 | Assert.AreEqual(actual["ce"], 2); 130 | } 131 | 132 | [TestMethod()] 133 | public void GenerateCandidate_SameFirstElementTest() 134 | { 135 | //Act 136 | string actual = _target.GenerateCandidate("be", "bc"); 137 | 138 | //Assert 139 | Assert.AreEqual(actual, "bec"); 140 | } 141 | 142 | [TestMethod()] 143 | public void GenerateCandidate_SingleElementsTest() 144 | { 145 | //Act 146 | string actual = _target.GenerateCandidate("a", "b"); 147 | 148 | //Assert 149 | Assert.AreEqual(actual, "ab"); 150 | } 151 | 152 | [TestMethod()] 153 | public void GenerateCandidate_DifferentFirstElementTest() 154 | { 155 | //Act 156 | string actual = _target.GenerateCandidate("ce", "be"); 157 | 158 | //Assert 159 | Assert.AreEqual(actual, string.Empty); 160 | } 161 | 162 | [TestMethod()] 163 | public void GetFrequentItemsTest() 164 | { 165 | //Arrange 166 | var candidates = new Dictionary 167 | { 168 | {"ab", 1}, 169 | {"ac", 2}, 170 | {"ae", 1}, 171 | {"bc", 2}, 172 | {"be", 3}, 173 | {"ce", 2} 174 | }; 175 | 176 | //Act 177 | IList actual = _target.GetFrequentItems(candidates, _minSupport, _transactions.Count()); 178 | 179 | //Assert 180 | Assert.AreEqual(actual.Count, 4); 181 | 182 | Assert.AreEqual(actual[0].Support, 2); 183 | Assert.AreEqual(actual[1].Support, 2); 184 | Assert.AreEqual(actual[2].Support, 3); 185 | Assert.AreEqual(actual[3].Support, 2); 186 | } 187 | 188 | [TestMethod()] 189 | public void GenerateSubsetsRecursiveTest() 190 | { 191 | //Arrange 192 | string item = "abcd"; 193 | int subsetLength = 2; 194 | char[] temp = new char[item.Length]; 195 | IList subsets = new List(); 196 | 197 | //Act 198 | _target.GenerateSubsetsRecursive(item, subsetLength, temp, subsets); 199 | 200 | //Assert 201 | Assert.AreEqual(6, subsets.Count); 202 | Assert.AreEqual("ab", subsets[0]); 203 | Assert.AreEqual("ac", subsets[1]); 204 | Assert.AreEqual("ad", subsets[2]); 205 | Assert.AreEqual("bc", subsets[3]); 206 | Assert.AreEqual("bd", subsets[4]); 207 | Assert.AreEqual("cd", subsets[5]); 208 | 209 | } 210 | 211 | [TestMethod()] 212 | public void GenerateSubsetsTest() 213 | { 214 | //Arrange 215 | string item = "abcd"; 216 | 217 | //Act 218 | IEnumerable actual = _target.GenerateSubsets(item); 219 | 220 | //Assert 221 | Assert.AreEqual(10, actual.Count()); 222 | } 223 | 224 | [TestMethod()] 225 | public void GetRemainingTest() 226 | { 227 | //Arrange 228 | string child = "ac"; 229 | string parent = "abcd"; 230 | 231 | //Act 232 | string actual = _target.GetRemaining(child, parent); 233 | 234 | //Assert 235 | Assert.AreEqual("bd", actual); 236 | } 237 | 238 | [TestMethod()] 239 | public void GetClosedItemSetsTest() 240 | { 241 | //Arrange 242 | ItemsDictionary allFrequentItems = new ItemsDictionary(); 243 | allFrequentItems.Add(new Item { Name = "a", Support = 2 }); 244 | allFrequentItems.Add(new Item { Name = "b", Support = 3 }); 245 | allFrequentItems.Add(new Item { Name = "c", Support = 3 }); 246 | allFrequentItems.Add(new Item { Name = "e", Support = 3 }); 247 | allFrequentItems.Add(new Item { Name = "ac", Support = 2 }); 248 | allFrequentItems.Add(new Item { Name = "bc", Support = 2 }); 249 | allFrequentItems.Add(new Item { Name = "be", Support = 3 }); 250 | allFrequentItems.Add(new Item { Name = "ce", Support = 2 }); 251 | allFrequentItems.Add(new Item { Name = "bce", Support = 2 }); 252 | 253 | //Act 254 | Dictionary> actual = _target.GetClosedItemSets(allFrequentItems); 255 | 256 | //Assert 257 | Assert.AreEqual(4, actual.Count, "ClosedItemSets calculation is wrong"); 258 | Assert.IsTrue(actual.ContainsKey("c")); 259 | Assert.IsTrue(actual.ContainsKey("be")); 260 | Assert.IsTrue(actual.ContainsKey("ac")); 261 | Assert.IsTrue(actual.ContainsKey("bce")); 262 | } 263 | 264 | [TestMethod()] 265 | public void GetItemParentsTest() 266 | { 267 | //Arrange 268 | string child = "a"; 269 | int index = 1; 270 | 271 | ItemsDictionary allFrequentItems = new ItemsDictionary(); 272 | allFrequentItems.Add(new Item { Name = "e", Support = 3 }); 273 | allFrequentItems.Add(new Item { Name = "ac", Support = 2 }); 274 | allFrequentItems.Add(new Item { Name = "bc", Support = 2 }); 275 | allFrequentItems.Add(new Item { Name = "be", Support = 3 }); 276 | allFrequentItems.Add(new Item { Name = "ce", Support = 2 }); 277 | allFrequentItems.Add(new Item { Name = "bce", Support = 2 }); 278 | 279 | //Act 280 | Dictionary actual = _target.GetItemParents(child, index, allFrequentItems); 281 | 282 | //Assert 283 | Assert.AreEqual(1, actual.Count); 284 | Assert.AreEqual(2, actual["ac"]); 285 | 286 | } 287 | 288 | [TestMethod()] 289 | public void CheckIsClosed_OpenItemTest() 290 | { 291 | //Arrange 292 | string child = "a"; 293 | Dictionary parents = new Dictionary(); 294 | parents.Add("ac", 2); 295 | ItemsDictionary allFrequentItems = new ItemsDictionary(); 296 | allFrequentItems.Add(new Item { Name = "a", Support = 2 }); 297 | allFrequentItems.Add(new Item { Name = "ac", Support = 2 }); 298 | 299 | //Act 300 | bool actual = _target.CheckIsClosed(child, parents, allFrequentItems); 301 | 302 | //Assert 303 | Assert.IsFalse(actual); 304 | } 305 | 306 | [TestMethod()] 307 | public void CheckIsClosed_ClosedItemTest() 308 | { 309 | //Arrange 310 | string child = "c"; 311 | Dictionary parents = new Dictionary(); 312 | parents.Add("ac", 2); 313 | parents.Add("bc", 2); 314 | parents.Add("ce", 2); 315 | 316 | ItemsDictionary allFrequentItems = new ItemsDictionary(); 317 | allFrequentItems.Add(new Item { Name = "c", Support = 3 }); 318 | allFrequentItems.Add(new Item { Name = "ac", Support = 2 }); 319 | allFrequentItems.Add(new Item { Name = "bc", Support = 2 }); 320 | allFrequentItems.Add(new Item { Name = "ce", Support = 2 }); 321 | 322 | //Act 323 | bool actual = _target.CheckIsClosed(child, parents, allFrequentItems); 324 | 325 | //Assert 326 | Assert.IsTrue(actual); 327 | } 328 | 329 | [TestMethod()] 330 | public void GetMaximalItemSetsTest() 331 | { 332 | //Arrange 333 | var closedItemSets = new Dictionary>(); 334 | closedItemSets.Add("a", new Dictionary()); 335 | closedItemSets.Add("b", new Dictionary() { { "x", 2 } }); 336 | 337 | //Act 338 | IList actual = _target.GetMaximalItemSets(closedItemSets); 339 | 340 | //Assert 341 | Assert.AreEqual(1, actual.Count); 342 | Assert.AreEqual("a", actual[0]); 343 | } 344 | 345 | [TestMethod()] 346 | public void GenerateRulesTest() 347 | { 348 | //Arrange 349 | ItemsDictionary allFrequentItems = new ItemsDictionary(); 350 | allFrequentItems.Add(new Item { Name = "ac", Support = 2 }); 351 | allFrequentItems.Add(new Item { Name = "bc", Support = 2 }); 352 | allFrequentItems.Add(new Item { Name = "be", Support = 3 }); 353 | allFrequentItems.Add(new Item { Name = "ce", Support = 2 }); 354 | allFrequentItems.Add(new Item { Name = "bce", Support = 2 }); 355 | 356 | //Act 357 | HashSet actual = _target.GenerateRules(allFrequentItems); 358 | 359 | //Assert 360 | Assert.AreEqual(7, actual.Count); 361 | } 362 | 363 | [TestMethod()] 364 | public void GetStrongRulesTest() 365 | { 366 | //Arrange 367 | double minConfidence = .8; 368 | HashSet rules = new HashSet(); 369 | rules.Add(new Rule("a", "c", 0)); 370 | rules.Add(new Rule("b", "c", 0)); 371 | 372 | ItemsDictionary allFrequentItems = new ItemsDictionary(); 373 | allFrequentItems.Add(new Item { Name = "a", Support = 2 }); 374 | allFrequentItems.Add(new Item { Name = "b", Support = 3 }); 375 | allFrequentItems.Add(new Item { Name = "c", Support = 3 }); 376 | allFrequentItems.Add(new Item { Name = "ac", Support = 2 }); 377 | allFrequentItems.Add(new Item { Name = "bc", Support = 2 }); 378 | 379 | //Act 380 | IList actual = _target.GetStrongRules(minConfidence, rules, allFrequentItems); 381 | 382 | //Assert 383 | Assert.AreEqual(1, actual.Count); 384 | } 385 | 386 | #endregion 387 | } 388 | } -------------------------------------------------------------------------------- /UnitTests/AprioriAlgorithm Tests/SorterTest.cs: -------------------------------------------------------------------------------- 1 | using AprioriAlgorithm; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace UnitTests 5 | { 6 | [TestClass()] 7 | public class SorterTest 8 | { 9 | [TestMethod()] 10 | public void SortTest() 11 | { 12 | //Arrange 13 | ISorter target = new Sorter(); 14 | var token = "cba"; 15 | 16 | //Act 17 | string actual = target.Sort(token); 18 | 19 | //Assert 20 | Assert.AreEqual(actual, "abc"); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /UnitTests/ObservableSetTest.cs: -------------------------------------------------------------------------------- 1 | using WPFClient; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace UnitTests 5 | { 6 | [TestClass()] 7 | public class ObservableSetTest 8 | { 9 | [TestMethod()] 10 | public void InsertItemTest() 11 | { 12 | //Arrange 13 | ObservableSet target = new ObservableSet(); 14 | var item = "Item"; 15 | 16 | //Act 17 | target.Add(item); 18 | target.Add(item); 19 | 20 | //Assert 21 | Assert.AreEqual(1, target.Count); 22 | 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UnitTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UnitTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("d25d621c-8cae-41ab-9741-407bb4d968f3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /UnitTests/Test References/AprioriAlgorithm.accessor: -------------------------------------------------------------------------------- 1 | AprioriAlgorithm.dll 2 | Desktop 3 | -------------------------------------------------------------------------------- /UnitTests/UI Tests/CharacterOnlyRuleTest.cs: -------------------------------------------------------------------------------- 1 | using WPFClient; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | 6 | namespace UnitTests 7 | { 8 | [TestClass()] 9 | public class CharacterOnlyRuleTest 10 | { 11 | [TestMethod()] 12 | public void ValidateInput_Test() 13 | { 14 | //Arrange 15 | CharacterOnlyRule target = new CharacterOnlyRule(); 16 | object value = "abcd"; 17 | CultureInfo cultureInfo = null; 18 | 19 | //Act 20 | ValidationResult actual = target.Validate(value, cultureInfo); 21 | 22 | //Assert 23 | Assert.IsTrue(actual.IsValid); 24 | } 25 | 26 | [TestMethod()] 27 | public void InValidateInput_Test() 28 | { 29 | //Arrange 30 | CharacterOnlyRule target = new CharacterOnlyRule(); 31 | object value = "321780/"; 32 | CultureInfo cultureInfo = null; 33 | 34 | //Act 35 | ValidationResult actual = target.Validate(value, cultureInfo); 36 | 37 | //Assert 38 | Assert.IsFalse(actual.IsValid); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /UnitTests/UI Tests/MainViewModelTest.cs: -------------------------------------------------------------------------------- 1 | using WPFClient; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Moq; 4 | using System.Collections.ObjectModel; 5 | using System.Linq; 6 | using System.Collections.Generic; 7 | 8 | namespace UnitTests 9 | { 10 | [TestClass()] 11 | public class MainViewModelTest 12 | { 13 | #region Member Variables 14 | 15 | readonly Mock _aprioriMock; 16 | readonly Mock _resultWindowMock; 17 | readonly MainViewModel _target; 18 | 19 | #endregion 20 | 21 | #region Constructor 22 | 23 | public MainViewModelTest() 24 | { 25 | _aprioriMock = new Mock(); 26 | _resultWindowMock = new Mock(); 27 | _target = new MainViewModel(_aprioriMock.Object, _resultWindowMock.Object); 28 | } 29 | 30 | #endregion 31 | 32 | #region TestMethods 33 | 34 | [TestMethod()] 35 | public void AddItemTest() 36 | { 37 | //Arrange 38 | _target.NewItem = "a"; 39 | 40 | //Act 41 | _target.AddItem.Execute(null); 42 | 43 | //Assert 44 | Assert.AreEqual(1, _target.Items.Count); 45 | } 46 | 47 | [TestMethod()] 48 | public void RemoveItemTest() 49 | { 50 | //Arrange 51 | var itemA = new Item { Name = 'a' }; 52 | var itemB = new Item { Name = 'b' }; 53 | 54 | _target.Items = new ObservableSet { itemA, itemB }; 55 | 56 | //Act 57 | _target.SelectedItem = itemA; 58 | _target.RemoveItem.Execute(null); 59 | 60 | //Assert 61 | Assert.AreEqual(1, _target.Items.Count); 62 | Assert.AreEqual(itemB.Name, _target.Items[0].Name); 63 | } 64 | 65 | [TestMethod()] 66 | public void RemoveItemInTransactionTest() 67 | { 68 | //Arrange 69 | var itemA = new Item { Name = 'a' }; 70 | var itemB = new Item { Name = 'b' }; 71 | _target.Items = new ObservableSet { itemA, itemB }; 72 | string transaction = itemA.Name + "" + itemB.Name; 73 | _target.Transactions = new ObservableCollection { transaction }; 74 | 75 | //Act 76 | _target.SelectedItem = itemA; 77 | _target.RemoveItem.Execute(null); 78 | 79 | //Assert 80 | Assert.AreEqual(2, _target.Items.Count); 81 | Assert.AreNotEqual(string.Empty, _target.Error); 82 | } 83 | 84 | [TestMethod()] 85 | public void AddTransactionTest() 86 | { 87 | //Arrange 88 | var itemA = new Item { Name = 'a', Selected = true }; 89 | var itemB = new Item { Name = 'b' }; 90 | var itemC = new Item { Name = 'c', Selected = true }; 91 | 92 | _target.Items = new ObservableSet { itemA, itemB, itemC }; 93 | 94 | //Act 95 | _target.AddTransaction.Execute(null); 96 | 97 | //Assert 98 | Assert.AreEqual(1, _target.Transactions.Count); 99 | Assert.AreEqual("ac", _target.Transactions[0]); 100 | } 101 | 102 | [TestMethod()] 103 | public void CanAddTransactionWhenNoItemsSelectedTest() 104 | { 105 | //Arrange 106 | var itemA = new Item { Name = 'a' }; 107 | var itemB = new Item { Name = 'b' }; 108 | 109 | _target.Items = new ObservableSet { itemA, itemB }; 110 | 111 | //Assert 112 | Assert.IsFalse(_target.AddTransaction.CanExecute(null)); 113 | } 114 | 115 | [TestMethod()] 116 | public void CanAddTransactionTest() 117 | { 118 | //Arrange 119 | var itemA = new Item { Name = 'a', Selected = true }; 120 | var itemB = new Item { Name = 'b' }; 121 | 122 | _target.Items = new ObservableSet { itemA, itemB }; 123 | 124 | //Assert 125 | Assert.IsTrue(_target.AddTransaction.CanExecute(null)); 126 | } 127 | 128 | [TestMethod()] 129 | public void DeleteTransactionTest() 130 | { 131 | //Arrange 132 | var transaction = "ab"; 133 | _target.Transactions = new ObservableCollection { transaction, "cd" }; 134 | 135 | //Act 136 | _target.SelectedTransaction = transaction; 137 | _target.DeleteTransaction.Execute(null); 138 | 139 | //Assert 140 | Assert.AreEqual(1, _target.Transactions.Count); 141 | } 142 | 143 | [TestMethod()] 144 | public void ClearAllTransactionsTest() 145 | { 146 | //Arrange 147 | var transaction = "ab"; 148 | _target.Transactions = new ObservableCollection { transaction, "cd" }; 149 | 150 | //Act 151 | _target.SelectedTransaction = transaction; 152 | _target.ClearAllTransactions.Execute(null); 153 | 154 | //Assert 155 | Assert.AreEqual(0, _target.Transactions.Count); 156 | } 157 | 158 | [TestMethod()] 159 | public void ProcessTransactionsTest() 160 | { 161 | //Arrange 162 | IEnumerable items = _target.Items.Select(t => t.Name.ToString()); 163 | string[] transactionsList = _target.Transactions.ToArray(); 164 | 165 | //Act 166 | _target.ProcessTransactions.Execute(null); 167 | 168 | //Assert 169 | _aprioriMock.Verify(a => a.ProcessTransaction(_target.MinSupport / 100, _target.MinConfidence / 100, items, transactionsList), Times.Once()); 170 | _resultWindowMock.Verify(r => r.Show(It.IsAny()), Times.Once()); 171 | 172 | } 173 | 174 | [TestMethod()] 175 | public void CanRemoveItemWhenSelectedItemIsNull() 176 | { 177 | //Act 178 | _target.RemoveItem.Execute(null); 179 | 180 | //Assert 181 | Assert.IsFalse(_target.RemoveItem.CanExecute(null)); 182 | } 183 | 184 | [TestMethod()] 185 | public void CanDeleteTransactionWhenSelectedTransactionIsNull() 186 | { 187 | //Act 188 | _target.DeleteTransaction.Execute(null); 189 | 190 | //Assert 191 | Assert.IsFalse(_target.DeleteTransaction.CanExecute(null)); 192 | } 193 | 194 | #endregion 195 | } 196 | } -------------------------------------------------------------------------------- /UnitTests/UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {C82787D0-76FA-49D9-8894-78F2644A7000} 10 | Library 11 | Properties 12 | UnitTests 13 | UnitTests 14 | v4.0 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | ..\References\Moq.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 3.5 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | False 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | {49F14BB7-E49E-4574-8038-25ABB6D5CF46} 71 | AprioriAlgorithm 72 | 73 | 74 | {B20F3B49-50C0-4160-BA1B-87FDF077CD79} 75 | WPFClient 76 | 77 | 78 | 79 | 80 | 81 | 82 | 89 | -------------------------------------------------------------------------------- /UnitTests/UnitTests.ncrunchproject: -------------------------------------------------------------------------------- 1 | 2 | false 3 | false 4 | false 5 | true 6 | false 7 | false 8 | false 9 | false 10 | true 11 | true 12 | false 13 | true 14 | true 15 | 60000 16 | 17 | 18 | 19 | AutoDetect 20 | MSTestAccessorsExist 21 | -------------------------------------------------------------------------------- /UnitTests/bin/Debug/AprioriAlgorithm.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/AprioriAlgorithm.dll -------------------------------------------------------------------------------- /UnitTests/bin/Debug/AprioriAlgorithm.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/AprioriAlgorithm.pdb -------------------------------------------------------------------------------- /UnitTests/bin/Debug/AprioriAlgorithm_Accessor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/AprioriAlgorithm_Accessor.dll -------------------------------------------------------------------------------- /UnitTests/bin/Debug/AprioriAlgorithm_Accessor.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/AprioriAlgorithm_Accessor.pdb -------------------------------------------------------------------------------- /UnitTests/bin/Debug/Moq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/Moq.dll -------------------------------------------------------------------------------- /UnitTests/bin/Debug/Moq.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/Moq.pdb -------------------------------------------------------------------------------- /UnitTests/bin/Debug/UnitTests.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/UnitTests.dll -------------------------------------------------------------------------------- /UnitTests/bin/Debug/UnitTests.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/UnitTests.pdb -------------------------------------------------------------------------------- /UnitTests/bin/Debug/WPFClient.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/WPFClient.exe -------------------------------------------------------------------------------- /UnitTests/bin/Debug/WPFClient.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/bin/Debug/WPFClient.pdb -------------------------------------------------------------------------------- /UnitTests/obj/Debug/AprioriAlgorithm_Accessor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/obj/Debug/AprioriAlgorithm_Accessor.dll -------------------------------------------------------------------------------- /UnitTests/obj/Debug/AprioriAlgorithm_Accessor.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/obj/Debug/AprioriAlgorithm_Accessor.pdb -------------------------------------------------------------------------------- /UnitTests/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /UnitTests/obj/Debug/ResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/obj/Debug/ResolveAssemblyReference.cache -------------------------------------------------------------------------------- /UnitTests/obj/Debug/UnitTests.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\bin\Debug\UnitTests.dll 2 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\bin\Debug\UnitTests.pdb 3 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm.dll 4 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm.pdb 5 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm_Accessor.dll 6 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm_Accessor.pdb 7 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\obj\Debug\ResolveAssemblyReference.cache 8 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\obj\Debug\UnitTests.dll 9 | C:\Users\Omar\Downloads\2-Apriori Source Code\UnitTests\obj\Debug\UnitTests.pdb 10 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\bin\Debug\UnitTests.dll 11 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\bin\Debug\UnitTests.pdb 12 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm.dll 13 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm.pdb 14 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm_Accessor.dll 15 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm_Accessor.pdb 16 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\obj\Debug\ResolveAssemblyReference.cache 17 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\obj\Debug\UnitTests.dll 18 | C:\Users\Omar\Desktop\Git\Apriori Source Code\UnitTests\obj\Debug\UnitTests.pdb 19 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\UnitTests.dll 20 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\UnitTests.pdb 21 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm.dll 22 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\Moq.dll 23 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\WPFClient.exe 24 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm.pdb 25 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\WPFClient.pdb 26 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\Moq.pdb 27 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\Moq.xml 28 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm_Accessor.dll 29 | D:\Git\Apriori Source Code\UnitTests\bin\Debug\AprioriAlgorithm_Accessor.pdb 30 | D:\Git\Apriori Source Code\UnitTests\obj\Debug\ResolveAssemblyReference.cache 31 | D:\Git\Apriori Source Code\UnitTests\obj\Debug\UnitTests.dll 32 | D:\Git\Apriori Source Code\UnitTests\obj\Debug\UnitTests.pdb 33 | -------------------------------------------------------------------------------- /UnitTests/obj/Debug/UnitTests.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/obj/Debug/UnitTests.dll -------------------------------------------------------------------------------- /UnitTests/obj/Debug/UnitTests.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/obj/Debug/UnitTests.pdb -------------------------------------------------------------------------------- /UnitTests/obj/Debug/WPFClient_Accessor.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/obj/Debug/WPFClient_Accessor.exe -------------------------------------------------------------------------------- /UnitTests/obj/Debug/WPFClient_Accessor.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omar-Salem/Apriori-Algorithm/e4d373ecfa9157d8b42b48e92f4f3afdd4835784/UnitTests/obj/Debug/WPFClient_Accessor.pdb -------------------------------------------------------------------------------- /WPFClient/Abstract/IResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AprioriAlgorithm; 3 | 4 | namespace WPFClient 5 | { 6 | public interface IResult 7 | { 8 | void Show(Output output); 9 | } 10 | } -------------------------------------------------------------------------------- /WPFClient/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WPFClient/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows; 7 | 8 | namespace WPFClient 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WPFClient/Commands/RelayCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | using System.Diagnostics; 4 | 5 | namespace WPFClient 6 | { 7 | /// 8 | /// Taken from http://msdn.microsoft.com/en-us/magazine/dd419663.aspx 9 | /// 10 | public class RelayCommand : ICommand 11 | { 12 | #region Members 13 | 14 | private readonly Func _canExecute; 15 | private readonly Action _execute; 16 | 17 | #endregion Members 18 | 19 | #region Constructors 20 | 21 | public RelayCommand(Action execute) 22 | : this(execute, null) 23 | { 24 | } 25 | 26 | public RelayCommand(Action execute, Func canExecute) 27 | { 28 | if (execute == null) 29 | throw new ArgumentNullException("execute"); 30 | _execute = execute; 31 | _canExecute = canExecute; 32 | } 33 | 34 | #endregion Constructors 35 | 36 | #region ICommand Members 37 | 38 | public event EventHandler CanExecuteChanged 39 | { 40 | add 41 | { 42 | if (_canExecute != null) 43 | CommandManager.RequerySuggested += value; 44 | } 45 | remove 46 | { 47 | if (_canExecute != null) 48 | CommandManager.RequerySuggested -= value; 49 | } 50 | } 51 | 52 | [DebuggerStepThrough] 53 | public Boolean CanExecute(Object parameter) 54 | { 55 | return _canExecute == null ? true : _canExecute(); 56 | } 57 | 58 | public void Execute(Object parameter) 59 | { 60 | _execute(); 61 | } 62 | 63 | #endregion ICommand Members 64 | } 65 | } -------------------------------------------------------------------------------- /WPFClient/ContainerProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition.Hosting; 3 | using AprioriAlgorithm; 4 | 5 | namespace WPFClient 6 | { 7 | internal static class ContainerProvider 8 | { 9 | private static CompositionContainer container; 10 | 11 | public static CompositionContainer Container 12 | { 13 | get 14 | { 15 | if (container == null) 16 | { 17 | List catalogList = new List(); 18 | catalogList.Add(new AssemblyCatalog(typeof(IApriori).Assembly)); 19 | catalogList.Add(new AssemblyCatalog(typeof(IResult).Assembly)); 20 | container = new CompositionContainer(new AggregateCatalog(catalogList)); 21 | } 22 | 23 | return container; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /WPFClient/Models/Item.cs: -------------------------------------------------------------------------------- 1 | namespace WPFClient 2 | { 3 | public class Item 4 | { 5 | public char Name { get; set; } 6 | 7 | public bool Selected { get; set; } 8 | 9 | public override bool Equals(object obj) 10 | { 11 | var other = obj as Item; 12 | 13 | if (other == null) 14 | { 15 | return false; 16 | } 17 | 18 | return Name == other.Name; 19 | } 20 | 21 | public override int GetHashCode() 22 | { 23 | return Name.GetHashCode(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /WPFClient/Models/ObservableSet.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace WPFClient 5 | { 6 | public class ObservableSet : ObservableCollection 7 | { 8 | readonly HashSet _items; 9 | 10 | public ObservableSet() 11 | { 12 | _items = new HashSet(); 13 | } 14 | 15 | protected override void InsertItem(int index, T item) 16 | { 17 | if (!_items.Contains(item)) 18 | { 19 | base.InsertItem(index, item); 20 | _items.Add(item); 21 | } 22 | } 23 | 24 | protected override void RemoveItem(int index) 25 | { 26 | T item = base[index]; 27 | _items.Remove(item); 28 | base.RemoveItem(index); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /WPFClient/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("WPFClient")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("WPFClient")] 15 | [assembly: AssemblyCopyright("Copyright © 2012")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | 57 | [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("UnitTests")] -------------------------------------------------------------------------------- /WPFClient/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.269 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WPFClient.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WPFClient.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /WPFClient/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /WPFClient/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.269 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WPFClient.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WPFClient/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /WPFClient/ValidationRules/CharacterOnlyRule.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace WPFClient 5 | { 6 | public class CharacterOnlyRule : ValidationRule 7 | { 8 | public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) 9 | { 10 | string input = value as string; 11 | Regex reg = new Regex("^[a-zA-Z]+$"); 12 | 13 | if (input == null || !reg.IsMatch(input)) 14 | { 15 | return new ValidationResult(false, "Characters only"); 16 | } 17 | 18 | return new ValidationResult(true, null); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WPFClient/ViewModels/MainViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Collections.ObjectModel; 4 | using AprioriAlgorithm; 5 | using System.Windows.Input; 6 | using System.Windows.Controls; 7 | 8 | namespace WPFClient 9 | { 10 | class MainViewModel : ViewModelBase 11 | { 12 | #region Member Variables 13 | 14 | ObservableSet _items; 15 | ObservableCollection _transactions; 16 | string _selectedTransaction, _newItem, _error; 17 | double _minSupport = 1, _minConfidence = 1; 18 | Item _selectedItem; 19 | readonly IResult _resultWindow; 20 | readonly IApriori _apriori; 21 | 22 | #endregion 23 | 24 | #region Constructor 25 | 26 | public MainViewModel(IApriori apriori, IResult resultWindow) 27 | { 28 | _items = new ObservableSet(); 29 | _transactions = new ObservableCollection(); 30 | this._apriori = apriori; 31 | this._resultWindow = resultWindow; 32 | } 33 | 34 | #endregion 35 | 36 | #region Public Properties 37 | 38 | public string NewItem 39 | { 40 | get { return _newItem; } 41 | set 42 | { 43 | if (_newItem != value) 44 | { 45 | _newItem = value; 46 | OnPropertyChanged("NewItem"); 47 | } 48 | } 49 | } 50 | 51 | public Item SelectedItem 52 | { 53 | get { return _selectedItem; } 54 | set 55 | { 56 | if (_selectedItem != value) 57 | { 58 | _selectedItem = value; 59 | OnPropertyChanged("SelectedItem"); 60 | } 61 | } 62 | } 63 | 64 | public ObservableSet Items 65 | { 66 | get { return _items; } 67 | set 68 | { 69 | if (_items != value) 70 | { 71 | _items = value; 72 | OnPropertyChanged("Items"); 73 | } 74 | } 75 | } 76 | 77 | public ObservableCollection Transactions 78 | { 79 | get { return _transactions; } 80 | set 81 | { 82 | if (_transactions != value) 83 | { 84 | _transactions = value; 85 | OnPropertyChanged("Transactions"); 86 | } 87 | } 88 | } 89 | 90 | public string SelectedTransaction 91 | { 92 | get { return _selectedTransaction; } 93 | set 94 | { 95 | if (_selectedTransaction != value) 96 | { 97 | _selectedTransaction = value; 98 | OnPropertyChanged("SelectedTransaction"); 99 | } 100 | } 101 | } 102 | 103 | public double MinSupport 104 | { 105 | get { return _minSupport; } 106 | set 107 | { 108 | if (_minSupport != value) 109 | { 110 | _minSupport = value; 111 | OnPropertyChanged("MinSupport"); 112 | } 113 | } 114 | } 115 | 116 | public double MinConfidence 117 | { 118 | get { return _minConfidence; } 119 | set 120 | { 121 | if (_minConfidence != value) 122 | { 123 | _minConfidence = value; 124 | OnPropertyChanged("MinConfidence"); 125 | } 126 | } 127 | } 128 | 129 | public string Error 130 | { 131 | get { return _error; } 132 | set 133 | { 134 | if (_error != value) 135 | { 136 | _error = value; 137 | OnPropertyChanged("Error"); 138 | } 139 | } 140 | } 141 | 142 | #endregion Public Properties 143 | 144 | #region Commands 145 | 146 | public ICommand AddItem 147 | { 148 | get { return new RelayCommand(AddItemExecute, CanAddItemExecute); } 149 | } 150 | 151 | public ICommand RemoveItem 152 | { 153 | get { return new RelayCommand(RemoveItemExecute, () => SelectedItem != null); } 154 | } 155 | 156 | public ICommand AddTransaction 157 | { 158 | get { return new RelayCommand(AddTransactionExecute, CanAddTransactionExecute); } 159 | } 160 | 161 | public ICommand DeleteTransaction 162 | { 163 | get { return new RelayCommand(DeleteTransactionExecute, () => SelectedTransaction != null); } 164 | } 165 | 166 | public ICommand ClearAllTransactions 167 | { 168 | get { return new RelayCommand(ClearAllTransactionsExecute, () => Transactions.Count != 0); } 169 | } 170 | 171 | public ICommand ProcessTransactions 172 | { 173 | get { return new RelayCommand(ProcessTransactionsExecute, () => Transactions.Count != 0); } 174 | } 175 | 176 | #endregion Commands 177 | 178 | #region Commands Methods 179 | 180 | private void AddItemExecute() 181 | { 182 | Items.Add(new Item { Name = NewItem[0] }); 183 | NewItem = string.Empty; 184 | } 185 | 186 | private bool CanAddItemExecute() 187 | { 188 | CharacterOnlyRule characterOnlyRule = new CharacterOnlyRule(); 189 | ValidationResult validationResult = characterOnlyRule.Validate(NewItem, System.Globalization.CultureInfo.CurrentCulture); 190 | 191 | return validationResult.IsValid; 192 | } 193 | 194 | private void RemoveItemExecute() 195 | { 196 | if (SelectedItem != null) 197 | { 198 | if (CheckItemIsInTransaction()) 199 | { 200 | Error = "Item present in a transaction, cannot delete"; 201 | } 202 | else 203 | { 204 | Error = string.Empty; 205 | Items.Remove(SelectedItem); 206 | } 207 | } 208 | } 209 | 210 | private void AddTransactionExecute() 211 | { 212 | IEnumerable selectedItems = Items.Where(i => i.Selected).Select(i => i.Name); 213 | Transactions.Add(new string(selectedItems.ToArray())); 214 | } 215 | 216 | private bool CanAddTransactionExecute() 217 | { 218 | IEnumerable selectedItems = Items.Where(i => i.Selected); 219 | return selectedItems.Count() != 0; 220 | } 221 | 222 | private void DeleteTransactionExecute() 223 | { 224 | Transactions.Remove(SelectedTransaction); 225 | } 226 | 227 | private void ClearAllTransactionsExecute() 228 | { 229 | Transactions.Clear(); 230 | } 231 | 232 | private void ProcessTransactionsExecute() 233 | { 234 | IEnumerable items = Items.Select(t => t.Name.ToString()); 235 | Output output = _apriori.ProcessTransaction(MinSupport / 100, MinConfidence / 100, items, Transactions.ToArray()); 236 | _resultWindow.Show(output); 237 | } 238 | 239 | #endregion 240 | 241 | #region Helper Methods 242 | 243 | private bool CheckItemIsInTransaction() 244 | { 245 | foreach (var item in Transactions) 246 | { 247 | if (item.Contains(SelectedItem.Name)) 248 | { 249 | return true; 250 | } 251 | } 252 | 253 | return false; 254 | } 255 | 256 | #endregion 257 | } 258 | } -------------------------------------------------------------------------------- /WPFClient/ViewModels/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace WPFClient 4 | { 5 | public abstract class ViewModelBase : INotifyPropertyChanged 6 | { 7 | public event PropertyChangedEventHandler PropertyChanged; 8 | 9 | protected void OnPropertyChanged(string propertyName) 10 | { 11 | PropertyChangedEventHandler handler = PropertyChanged; 12 | 13 | if (handler != null) 14 | { 15 | handler(this, new PropertyChangedEventArgs(propertyName)); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /WPFClient/Views/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | Characters only 12 | 13 | 14 | 15 | 16 | 17 | 18 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 45 |