基本上我想列出一些像......
这样的东西a 345
b 762
c 983
d 425
e 45
...
并给定最大距离,为包含该范围内其他元素的每个元素创建聚类。例如,如果我将上面的最大距离指定为300,则群集将是......
a 345
d 425
e 45
b 762
c 983
c 983
b 762
d 425
a 345
e 45
a 345
明智的约束,我正在阅读文件中的条目,这与我正在做的工作很常见。因此,我通常将我的算法集中在工作上,因为它读取条目,而不是读取文件中的所有内容,将其存储在一些方便的结构中,然后对其进行操作。无论如何,存储文件中的条目然后根据这些值执行排序,然后只是通过排序列表并进行适当的输出是我试图避免的。
我做了一些外行头脑风暴,但在我花了很多时间做一个彻底的分析之前,我觉得我已经在某个地方看过这个或者有一个非常类似的算法。我不是要求某人提出算法,除非你感到如此倾向,只是想知道是否有任何解决这个问题的现有问题或者与之类似的问题。
感谢。
答案 0 :(得分:0)
另一种可能的泛滥填充算法,使用一些修改后的二进制搜索来减少所需的比较量:
Pseudo-code:
def clustersWithinRange(values, distance): //Should run in O(n log n)
sortedValues = values.sorted()
valueCount = values.len()
clusters = Array()
cachedLower = 0
cachedUpper = values.len
cachedValue = null
for i in range(0, valueCount):
value = sortedValues.get(i)
if (cachedValue == value): //duplicate value, no need to calculate twice
clusters.add(clusters.get(i).copy()) //simply clone last cluster or nop if no duplicate clusters wanted
else:
lower = sortedValues.binaryBoundSearch(values, value, distance, cachedLower, i, LowerBoundMatchFlag)
upper = sortedValues.binaryBoundSearch(values, value, distance, cachedUpper, valueCount, UpperBoundMatchFlag)
clusters.add(sortedValues[lower:upper+1])//add sublist within (and including) lower...upper to clusters
cachedLower = lower
cachedUpper = upper
return clusters
def withinDistance(valueA, valueB, distance):
return abs(valueA - valueB) <= distance
def binaryBoundSearch(values, value, distance, low, high, searchFlag):
// Possible values of searchFlag:
// "LowerBoundMatchFlag" to get the leftmost found match.
// "UpperBoundMatchFlag" to get the rightmost found match.
if (high < low):
return -1 // not found
mid = low + ((high - low) / 2)
matchPosition = -1
aValue = values[mid]
if (withinDistance(aValue, value, distance)):
matchPosition = mid
displacement = (searchFlag == LowerBoundMatchFlag) ? -1 : 1
if (mid > low && mid < high && withinDistance(values.get(mid + displacement), value, distance)):
newLow = (searchFlag == LowerBoundMatchFlag) ? low : mid + displacement
newHigh = (searchFlag == LowerBoundMatchFlag) ? mid + displacement : high
matchPosition = binaryBoundSearch(values, value, newLow, newHigh, searchFlag)
else:
flag = compare(aValue, value)
if (flag < 0): // current position too far left
matchPosition = binaryBoundSearch(values, value, mid + 1, high, searchFlag)
else if (flag > 0): // current position too far right
matchPosition = binaryBoundSearch(values, value, low, mid - 1, searchFlag)
return matchPosition