对于我正在实施的一系列算法,我需要模拟诸如称重的硬币组或汇集的血液样本之类的事情。最重要的目标是在一组其他相同的项目中识别一组稀疏的有趣项目。这种识别是通过一起测试项目组来完成的。例如,经典问题是在一组 81 枚(相同)硬币中找到一枚轻质假币,使用尽可能少的平底秤的权重。诀窍是将 81 枚硬币分成三组,然后将两组相互称重。然后,您在剩下 2 个硬币之前对不平衡的组执行此操作。
上面讨论的关键点是,有趣的项目集在更广泛的集合中是稀疏的——对于这种类型的输入,我正在实现的算法都优于二分搜索等。
我需要的是一种测试整个向量的方法,该方法指示存在单个或多个向量,而无需逐个扫描向量。
即一种在 O(1) 操作中返回向量的汉明权重的方法 - 这将准确模拟在平底秤中汇集血液样本/称重硬币组。
关键是向量没有被扫描——但输出应该表明向量中至少有一个 1。通过扫描,我的意思是使用二进制搜索等算法查看向量或依次查看每个元素。这需要模拟项目(例如血液样本)的汇集组和表明存在 1 的组的单个测试。
我目前已经将这个“向量”实现为一个列表,但这不需要一成不变。任务是通过测试子列表的组来确定向量中的 1 所在的位置。该列表的一个示例是:
sparselist = [0]*100000
sparselist[1024] = 1
但这同样可能是一个很长/设置/其他的东西,如下所示。
目前我正在使用 any() 作为测试,但有人向我指出 any() 将扫描向量 - 违背了我想要实现的目的。
以下是使用 any 测试组的简单二分搜索示例:
def binary_search(inList):
low = 0
high = len(inList)
while low < high:
mid = low + (high-low) // 2
upper = inList[mid:high]
lower = inList[low:mid]
if any(lower):
high = mid
elif any(upper):
low = mid+1
else:
# Neither side has a 1
return -1
return mid
如果此代码不是生产质量,我深表歉意。任何改进它的建议(除了 any() 测试)将不胜感激。
我正在尝试提出比 any() 更好的测试,因为有人指出 any() 将扫描列表 - 违背了我正在尝试做的事情。测试不需要返回准确的汉明权重——它只需要指出被测试的组中有(或没有!)1(即上面代码中的上/下)。
我也想过使用二进制异或,但不知道如何以非组件化的方式使用它。