Braggy
Braggy

Reputation: 25

Identify Combinations

I have a question that is similar, but not identical, to the one answered here: Fastest way to identify the combinations of items

I will explain the background first.

I have a Purchase Order issued by different Customers which contains Customer ID and the item that they wish to purchase. (Sample Format Below - similar to the question prev asked)

CUS#,ITEM  
1, Soap
1, Brush
2, Brush
2, Toothpaste
2, Razor
2, Razor Blades
3, Razor Blades
3, Razor

Any Customer may order any number of items (as in the above example Cus1-2items, Cus2-4items).

I'm trying to identify the combination of items that are very popular among different customers. The following is a list all combination of items from a particular customer and their count of appearance(s).

Razor , Razor Blades - 2 Customers
Soap, Brush - 1 Customer
Brush, Toothpaste- 1 Customer
Brush, Razor - 1 Customer
Brush, Razor Blades - 1 Customer
Toothpaste , Razor - 1 Customer
Toothpaste , Razor Blades - 1 Customer

I tried to do this by the following logic (pseudo code):

For Each Customer_ID:

Identify_The_Combinations_Of_Orders

For Each Combination:
   Check if the combination already exists, if yes, count one more, if no, start counting from 1

This code was easy to implement, except it took longer time to execute. Is there a smarter way to execute this with .NET?

Now, what I want also to check is the order completions. Say if Razor and Razor Blades are ordered together, I want to check, if the combination appears, does it complete the entire order? (meaning, are they two the only ones ordered by the customer?) If so, how many times? (the combination may appear in multiple customer orders but only one might have ordered only these two).

I would sincerely appreciate any help.

Upvotes: 1

Views: 108

Answers (3)

Nitin Joshi
Nitin Joshi

Reputation: 1668

Use following code:

List<dynamic> lstOrders = new List<dynamic>();
lstOrders.Add(new { CustID = 1, Item = "Soap" });
lstOrders.Add(new { CustID = 1, Item = "Brush" });
lstOrders.Add(new { CustID = 2, Item = "Brush" });
lstOrders.Add(new { CustID = 2, Item = "Toothpaste" });
lstOrders.Add(new { CustID = 2, Item = "Razor" });
lstOrders.Add(new { CustID = 2, Item = "Razor Blades" });
lstOrders.Add(new { CustID = 3, Item = "Razor" });
lstOrders.Add(new { CustID = 3, Item = "Razor Blades" });

var items = lstOrders.Select(x => x.Item).Distinct();

var orders = lstOrders.SelectMany((value, index) => lstOrders.Skip(index + 1),
                                           (first, second) => new { Item1 = first, Item2 = second }).Where(x => x.Item1.CustID == x.Item2.CustID);

var combinations = from r in orders
                   select new { CustID = r.Item1.CustID, Combination = new { Item1 = r.Item1.Item, Item2 = r.Item2.Item } };

var group = combinations.GroupBy(x => x.Combination);

foreach (var grpItem in group)
  {
    Console.WriteLine(string.Format("Item combination {{{0}, {1}}} has been purchased by {2} customer(s).", grpItem.Key.Item1, grpItem.Key.Item2, grpItem.Count()));
  }
Console.Read();

Upvotes: 1

tinstaafl
tinstaafl

Reputation: 6948

One of the simplest ways is most likely with a Dictionary(Of List(Of String), Integer) if the combination converted to a list of string is already in the dictionary then increment the value by 1 else add the list as the key with a value of 1 to the dictionary. The combinations with the highest value are most popular.

Without your code that implements your class(es) it will be difficult to give you a meaningful example to go by. Don't worry about length. As long as every class and method that is referenced is included. If people have to guess what a class or a method does it might be difficult to get meaningful answers.

Upvotes: 0

domskey
domskey

Reputation: 1112

i don't have enough rep to comment, so i'll ask my question here. Do you have a code sample of your algorithm for checking the combinations. It stands to reason that if that is what you are having a problem with, that's what we would need the most detail on.

For example do your items have unique ids? How do you store the data? How do you search the combination metadata, or do you search every purchase order every time?

Upvotes: 0

Related Questions