我正在寻找一种算法,该算法将为使用几何系列创建的任何树中的任何节点提供祖先线,其中a = 1
和r
等于任何整数。例如,下图中的树r = 2
和26
的祖先行是[26, 13, 6, 3, 1]
。
我自己也有过这方面的答案,并且得出了一个答案,似乎能够为我尝试的r
的价值提供正确的答案。但在我创建一个使用此算法提供文件系统资源的应用程序之前,我想确保我不会遗漏某些边缘案例。感觉就像那种问题必须有一个既定的解决方案,几乎肯定比我的更优雅。有谁知道什么?
# My python implementation.
import math
def findLevelOfFolder(folder):
""" Find the 'level' on which a given folder sits. """
if folder == 1:
return 1
else:
level = 2
while True:
lower, upper= boundsOfLevel(level)
if folder >= lower and folder <= upper:
return level
level += 1
def sumOfProgression(r, upToAndIncludingTerm):
"""
Sums a simple geometric series.
If r = 2, and upToAndIncludingTerm = 6, we'refinding the value of...
pow(2, 0) + pow(2, 1) + pow(2, 3) + ... + pow(2, 5)
"""
rRepeated = [r] * upToAndIncludingTerm
powers = range(0, upToAndIncludingTerm)
return sum(map(pow, rRepeated, powers))
def boundsOfLevel(level):
"""
A levels 'bounds' refers to the number of the first folder and the last folder
on that level. For example, when r == 2, and the level == 3, the
bounds is (4, 7). The smallest possible level is 1, which, for any
value of r always returns (1, 1).
"""
assert(level > 0, "Smallest possible level is 1.")
if level == 1:
return 1, 1
else:
lower = sumOfProgression(foldersPerFolder, level-1) + 1
upper = lower + pow(foldersPerFolder, level-1) - 1
return lower, upper
def ancestorsOfFolder(folder, ancestors):
""" Find the shortest route from folder '1' for the specified folder value.
On completion, ancestors will contain a list of numbers each of which
represents a folder in the ancestral line of 'folder'. The first number in
the list will always be 'folder' and the last number will always be 1."""
# First get the level...
level = findLevelOfFolder(folder)
lowerBoundOfPreviousLevel, _ = boundsOfLevel(level-1)
relativePosition = folder - sumOfProgression(foldersPerFolder, level-1)
parent = (lowerBoundOfPreviousLevel - 1) + math.ceil(relativePosition/foldersPerFolder)
ancestors.append(parent)
if parent != 1:
ancestorsOfFolder(parent, ancestors)
# 'r' value
foldersPerFolder = 2
# looking for ancestral line of...
folder = 23
print(ancestorsOfFolder(folder, [folder])) # -> [23, 11, 5, 2, 1]
答案 0 :(得分:3)
如果您将根编号为0,则更容易看到模式。
对于r = 4:
0
1 2 3 4
5..8 9..12 13..16 17..20
在这种情况下,每个节点k
都将floor((k-1)/r)
作为其父级。
如果你在1开始编号,就像在
中一样 1
2 3 4 5
6..9 10..13 14..17 18..21
它变得有点乱。在除以4
之前,您需要减去某些内容,然后再添加其他内容。这些事情对我来说并不是很清楚。我的建议:如果可能的话,使用基于0的树:)
答案 1 :(得分:1)
第三次的魅力(无论如何,第三次编辑)。
每个级别的父级都可以使用等式def ancestorsOfFolder(folder, r):
ancestors = []
while folder > 0:
ancestors.append(folder)
folder = (folder - 2) // r + 1
return ancestors
找到:
folder = (folder - 1) // r
编辑:我同意,最好使用从零开始的树。可以使用等式def ancestorsOfFolder(folder, r):
ancestors = []
while folder > 0:
ancestors.append(folder)
folder = (folder - 1) // r
ancestors.append(0)
return ancestors
找到父母。这是代码:
SELECT DISTINCT tmp.Arrival, tmp.Flight,
COUNT(*) OVER (PARTITION BY Flight) as NumPassengers,
SUM(CASE WHEN SegmentNumber = 1 AND LegNumber = 1 THEN 1 ELSE 0 END) OVER
(PARTITION BY Flight, Arrival)
) as NumLocalPassengers,
STD, STA
FROM #TempLocalOrg tmp;