这是我刚遇到的一个问题,或者更确切地说是一个捕捉核心问题的简化。
想象一下,我有一个包含多个列的电子表格,每个列都有标记,还有很多行。
我想确定何时可以从另一列中的值推断出一列中的值。例如,我们可能会发现,每当“1”出现在 a 列中时,“5”始终显示在 d 列中,但每当“2”出现在列 a ,a 3始终显示在 d 列中。我们观察到 a 列中的值可靠地预测列 c 中的值。
目标是确定列之间的所有此类关系。
天真的解决方案是从所有列对列表开始,(a,b),(a,c),(a,d)......(b,c),(b,d)。 .. 等等。我们将这些称为“符合条件”的列表。
对于这些对中的每一对,我们跟踪对中第一个的值,以及第二个中的对应值。如果我们注意到我们看到第一对中的第一个值相同,但是对中第二个值的值不同,则该对不再符合条件。
这个过程结束时留下的是一组有效的关系。
不幸的是,随着列数的增加,这很快就变得不切实际,因为我们必须存储的数据量是列数的平方数。
有人能想到一种有效的方法吗?
答案 0 :(得分:0)
我认为你不能改进n列的O(n ^ 2):考虑任何一对之间不存在关系的情况。发现这一点的唯一方法是测试所有对,即O(n ^ 2)。
答案 1 :(得分:0)
我怀疑你最好建立这种关系,而不是削弱它。
您可能需要存储n ^ 2条信息,其中您有n列。例如,如果列永远不会重复(即每行的值不同),则该列会预测所有其他列。如果每列都是这样的,那么每列都会相互预测。您可以使用二维表,例如,按列数索引,如果预测b,则使用pred(a,b)为真。 pred(a,b)可以有3个值中的任何一个:true,false和unknown。
预测关系是可传递的,即如果预测b和b预测c则预测c。如果行数很大,那么检查行是否预测另一行是昂贵的,那么使用传递性来填写你可以做的事情可能是值得的:如果你刚刚计算出pred(a,b)是真的并且你有已经为每个x计算了pred(b,x),那么你可以为pred(b,y)为真的每个y设置pred(a,y)true。
要填写pred(a,。),你可以从a构建一个临时数组对(value,row-index),然后按值排序;这使您可以轻松访问a为常量的索引集。如果这些集合中的每一个都是单个集合,则对于每个b,pred(a,b)为真;否则检查是否预测b(如果它还不知道)你需要检查b在每个索引集(有多个成员)上是否恒定,其中a是常数。
优化可能是如果pred(a,b)为真,并且pred(b,a)为真,那么对于每个c,pred(a,c)当且仅当pred(b,c);因此,在这种情况下,如果你已经填写了pred(b,。),你可以通过复制填写所有pred(a,。)。