我有一个组合元素的公式列表:
A + B + C = X
D + E + F = Y
G + H + I = Z
我想确保给定任意随机4个元素,永远不会有超过1个适用的公式。例如,不允许使用下面的公式,就像我得到元素A,B,C和D那样两者都适用:
A + B + C = X
B + C + D = Y
每个公式都包含LHS上的3个元素,它是我想要强制执行规则的LHS。 如果有帮助,这些元素是可排序的。
另一个等效问题:
我有一个包含3个元素的数组的列表:List<Element[3]>
如何确保没有2个元素出现在多个数组中。
对于大量元素和大量公式(超出暴力强制)执行此操作的合理有效(运行时速度)方法是什么?
答案 0 :(得分:2)
基本上,这归结为一个排除问题:来自您的示例数据,
并且您要确保列表中的任何新条目
根据元组的大小,创建一个详尽的子集列表可能很昂贵或不是
这应该适用于小集(子集的廉价列表)
Keep dictionary of formulas
On new formula
Normalize variable list (e.g. (D,A,c)=>"ACD")
Check if normalized variable list exists in dictionary
If it exists, reject new formula and break
For all subsets of variable list
Check if normalized variable list of subset exists in dictionary
If it exists, reject new formula and break
End For
End On
答案 1 :(得分:1)
您可以将方程组的约束表示为图形。顶点是元素,方程n[i]
中有i
个元素。对于等式i
,因此有n[i]*(n[i]-1)/2
个元素对;这些变成了边缘。迭代方程,将边添加到图中。无论何时您想要添加已存在的边缘,您都会发现冲突。
对于每条边,您可以存储一组可以生成边的方程数;这允许识别特定冲突,而不仅仅是冲突的存在。
让N
为方程的数量,M
为具有最多元素的等式中的元素数量。时间复杂度为O(M^2*N)
,空间复杂度也是如此。如果所有方程都具有固定数量的元素,则时间和空间使用将为O(N)
。
答案 2 :(得分:1)
此解决方案的灵感来自Michael J. Barber的解决方案。
初始化哈希表
如果您有M个变量的等式,请将大小为M-1的所有组合添加到哈希表中。例如:对于A + B + C + D = Z,添加(A,B,C),(A,B,D),(A,C,D)和(B,C,D)
< / LI>当您想测试具有M个变量的新等式的可能性时,请检查所有M-1子集是否都不在散列中。
复杂性:O(mnlog(mn))。
答案 3 :(得分:0)
您可以从另一侧定义该问题:没有任何一对公式,元素的并集包含少于5个元素。如果通过该测试,则指向比较每对公式的算法。我知道它的蛮力,但我无法想象更好的atm。
答案 4 :(得分:0)
也许您可以利用一些LINQ设置操作。由于您将问题描述为具有列表列表,希望“确保没有2个元素出现在多个列表中”,因此无法将其描述为检查是否存在交集任何一个清单?或者我有点离开这里?
James Michael Hare在LINQ中有a nice article on the various set operations。你可以先看一下: - )
答案 5 :(得分:-1)
将您的值存储在矩阵中,并确保矩阵[i] [j]!=矩阵[k] [j]与i!= k。
<强>更新强>
这种方法如果在解决线性方程问题时经常使用。矩阵中的元素表示多项式函数的系数。然后,您可以在行之间操作以将矩阵转换为特殊形式。
但在这种情况下,您只需将元素存储在矩阵中并在添加行(某些元素组合)之前验证矩阵。
这种方法的优势在于效率最高,但您需要正确处理初始大小和调整大小策略。
更新2:
A + B + C = X
B + C + D = Y
m[0][1] = B
m[1][0] = B
这个例子打破规则矩阵[i] [j]!= matrix [k] [j]与i!= k
然后你不能使用公式B + C + D = Y,因为A + B + C = X.