在我的asp.net c#应用程序中,我具有以下列出的项目组合。我想列出最常出现的组合。
根据上面的示例,我应该获得以下输出。
最经常出现的组合是
我的结构如下。
public class MyList
{
public List<MyItem> MyItems { get; set; }
}
public class MyItem
{
public string ItemName { get; set; }
}
答案 0 :(得分:1)
我想尽一切办法使用哈希将所有可能的组合映射起来,其中ab
与ba
相同(或者您可以按字母顺序对项目进行排序,然后对它们进行哈希处理),然后只计算哈希的出现...
答案 1 :(得分:0)
您可以从列表中创建一个加权图,其中两个节点之间的权重代表发生频率。 This StackExchange post提供了一些信息,您还可以在this previous SO post here上了解邻接矩阵。
根据我的看法,明智的做法是使用
HashSet<Tuple<Item1, Item2>>
代表一个连接,并将其值存储在字典中。
对于多个项目,问题类似于在图形的路径遍历算法中找出最经过的路径。
尽管对于非常大的数据集,我建议通过C#动态地通过SQL语句和分析查询使用SSAS和SSIS服务,以创建一个市场篮子分析,该分析应该为您生成所需的统计数据。
答案 2 :(得分:0)
这是一种快速而肮脏的方法,可以帮助您入门。您可能应该使用哈希表来提高性能,但我认为字典更易于可视化。
提琴:https://dotnetfiddle.net/yofkLf
public static void Main()
{
List<MyItem[]> MyItems = new List<MyItem[]>()
{
new MyItem[] { new MyItem("Item1") },
new MyItem[] { new MyItem("Item1"), new MyItem("Item2") },
new MyItem[] { new MyItem("Item3") },
new MyItem[] { new MyItem("Item1"), new MyItem("Item3"), new MyItem("Item2") },
new MyItem[] { new MyItem("Item3"), new MyItem("Item1") },
new MyItem[] { new MyItem("Item2"), new MyItem("Item1") }
};
Dictionary<Tuple<string, string>, int> results = new Dictionary<Tuple<string, string>, int>();
foreach (MyItem[] arr in MyItems)
{
// Iterate through the items in the array. Then, iterate through the items after that item in the array to get all combinations.
for (int i = 0; i < arr.Length; i++)
{
string s1 = arr[i].ItemName;
for (int j = i + 1; j < arr.Length; j++)
{
string s2 = arr[j].ItemName;
// Order the Tuple so that (Item1, Item2) is the same as (Item2, Item1).
Tuple<string, string> t = new Tuple<string, string>(s1, s2);
if (string.Compare(s1, s2) > 0)
{
t = new Tuple<string, string>(s2, s1);
}
if (results.ContainsKey(t))
{
results[t]++;
}
else
{
results[t] = 1;
}
}
}
}
// And here are your results.
// You can always use Linq to sort the dictionary by values.
foreach (var v in results)
{
Console.WriteLine(v.Key.ToString() + " = " + v.Value.ToString());
// Outputs:
// (Item1, Item2) = 3
// (Item1, Item3) = 2
// (Item2, Item3) = 1
}
}
...
public class MyItem
{
public string ItemName { get; set; }
public MyItem(string ItemName)
{
this.ItemName = ItemName;
}
}
当然,如果MyItems中没有该字符串属性,则情况会有所不同。
答案 3 :(得分:0)
这是一个粗略的O(N ^ 2)方法:
List<List<Item>>
)rowId
一些假设:
就像我上面说的那样,这是一种O(N ^ 2)方法,因此性能可能是一个问题。对于子集成员身份也有两项检查,这可能是性能问题。我也只是将ID作为字符串连接和拆分,您可能可以通过设置另一个跟踪ID的字典来获得更好的解决方案。 Dictionary.TryGetValue
还有一些改进的空间。提取所需的项目集留给读者作为练习,但这应该是简单的OrderBy(..).Where(...)
操作。但这应该可以帮助您入门。
public class MyItem
{
public string ItemName { get; set; }
}
class Program
{
public static void GetComboCount()
{
var itemsCollection = new List<List<MyItem>>() {
new List<MyItem>() { new MyItem() { ItemName = "Item1" } },
new List<MyItem>() { new MyItem() { ItemName = "Item1" }, new MyItem() { ItemName = "Item2" } },
new List<MyItem>() { new MyItem() { ItemName = "Item3" } },
new List<MyItem>() { new MyItem() { ItemName = "Item1" }, new MyItem() { ItemName = "Item3" }, new MyItem() { ItemName = "Item2" } },
new List<MyItem>() { new MyItem() { ItemName = "Item3" }, new MyItem() { ItemName = "Item1" } },
new List<MyItem>() { new MyItem() { ItemName = "Item2" }, new MyItem() { ItemName = "Item1" } }
};
var comboCount = new Dictionary<string, int>();
foreach (var row in itemsCollection)
{
var ids = row.Select(x => x.ItemName).OrderBy(x => x);
var rowId = String.Join(",", ids);
var rowIdCount = ids.Count();
var seen = false;
var comboCountList = comboCount.ToList();
int currentRowCount = 1;
foreach (var kvp in comboCountList)
{
var key = kvp.Key;
if (key == rowId)
{
seen = true;
currentRowCount++;
continue;
}
var keySplit = key.Split(',');
var keyIdCount = keySplit.Length;
if (ids.Where(x => keySplit.Contains(x)).Count() == keyIdCount)
{
comboCount[kvp.Key] = kvp.Value + 1;
}
else if (keySplit.Where(x => ids.Contains(x)).Count() == rowIdCount)
{
currentRowCount++;
}
}
if (!seen)
{
comboCount.Add(rowId, currentRowCount);
}
else
{
comboCount[rowId] = currentRowCount;
}
}
foreach (var kvp in comboCount)
{
Console.WriteLine(String.Format("{0}: {1}", kvp.Key, kvp.Value));
}
}
static void Main(string[] args)
{
GetComboCount();
}
}
控制台输出:
Item1: 5
Item1,Item2: 3
Item3: 3
Item1,Item2,Item3: 1
Item1,Item3: 2