给定2d数据数组,我如何找到最匹配的最大组合?
示例:
Cust # Prod # C1 P1 C1 P2 C2 P1 C2 P3 C3 P1 C3 P3 C3 P4
(使用haskell - 无法弄清楚如何在C#中轻松实现这一点) 子序列是:
> subsequences ["P1","P2","P3", "P4"] => [[],["P1"],["P2"],["P1","P2"],["P3"],["P1","P3"],["P2","P3"],["P1","P2","P3"],["P4"],["P1","P4"],["P2","P4"],["P1","P2","P4"],["P3","P4"],["P1","P3","P4"],["P2","P3","P4"],["P1","P2","P3","P4"]]
我想找到X大小的子序列,其中包含多于Y个匹配...
因此,对于此示例,具有多个匹配的最大子序列为:[“P1”,“P3”] - 具有2个计数
因为个别客户序列是:
C1 => ["P1, "P2"] C2 => ["P1", "P3"] C3 => ["P1", "P3", "P4"]
因此,这些集合中有两个[“P1”,“P3”]实例。
我最初的想法是生成子序列然后匹配,但我的数据集太大了。
注意:我的数据集有13000个独特的2D数据组合,因此子序列方法要么溢出要么根本不会完成,具体取决于语言。
编辑:我对最长的子集(未订购)感兴趣
编辑:@Jimmy:如果您将以下内容添加到列表中,我希望看到P1,P2,P4作为结果,因为它拥有最多的客户。遗憾的是,您的解决方案不起作用
{ "C4", new HashSet<string>(new[] { "P1", "P2","P4"})},
{ "C5", new HashSet<string>(new[] { "P1", "P2","P4"})},
{ "C6", new HashSet<string>(new[] { "P1", "P2","P4"})},
编辑:@Eric Lippert
我的理想输出是每个组合,每次都是一个子集。然后,我可以查询最大的篮子,并且该篮子中的商品数量最少。
编辑:从业务角度来看,我想找到许多客户购买的最常出现的商品。我意识到很多篮子的大小都很模糊 - 但这就是对结果进行分析的地方。
答案 0 :(得分:3)
这个问题可以表述如下(如果我理解你的话):
给定n组:C1 ... CN, 每个由元素{P1 ... PN}
组成找到这些子集的X与至少Y个元素的交集。
找到这些N个集合的最大子集交集的更复杂问题是NP-Hard (参见此proof)。
您的问题可能也是NP-Hard或NP-complete(因为它看起来像是找到最大交集的问题的决定版本)。您将无法找到解决问题的有效方法。
您应该查找最大子集交集问题的启发式方法,或者查找一些类似(但不同)和更受欢迎的问题(例如集合覆盖问题)的灵感。
答案 1 :(得分:0)
你所拥有的与此类似 1 a | 1 b | 1 c
2 a | 2 b
3 c | 3 d
相当于
abc | ab | cd
所以基本上你要解决的问题必须是 1.找到最大长度字符串 2.查找具有最大频率的字符串 3.其组合
将系列表示为矢量,为该矢量编写自定义比较函数,将它们添加到multiset,同时保持计数。并记住迄今为止最频繁序列遇到的最大计数,并记住插入的最长载体。
答案 2 :(得分:0)
只回答最长的子序列:
customer c = entryList[0].customer;
product p;
set s;
set largestSet = s;
for (every entry in entryList)
{
if(c ! = entry.customer)
{
c = entry.customer;
if (s.size > largestSet.size) largestSet = s;
s.clear();
}
s.add(entry.customer)
}
答案 3 :(得分:0)
您似乎正在寻找最长的成对子集。
这是一种蛮力的方式:
从元组列表(c,p)开始,制作一个{c:set(p1,p2,p3)}字典。
var dict = new Dictionary<string, HashSet<string>> {
{ "C1", new HashSet<string>(new[] { "P1", "P2"})},
{ "C2", new HashSet<string>(new[] { "P1", "P3"})},
{ "C3", new HashSet<string>(new[] { "P1", "P3","P4"})},
};
var max = from pair1 in dict
from pair2 in dict
where pair2.Key != pair1.Key
let s = pair1.Value.Intersect(pair2.Value).ToArray()
orderby s.Length descending
select s;
Console.WriteLine(string.Join(",", max.First()));
<小时/> 输出:
P1,P3
似乎是一个O(N ^ 3)算法。