輸入:半徑R,尺寸d
例如,python代碼:
from itertools import *
# we have to write this function ourselves because python doesn't have it...
def partitions(n, maxSize):
if n==0:
yield []
else:
for p in partitions(n-1, maxSize):
if len(p)<maxSize:
yield [1] + p
if p and (len(p)<2 or p[1]>p[0]):
yield [ p[0]+1 ] + p[1:]
# MAIN CODE
def points(R, D):
for part in partitions(R,D): # e.g. 4->[3,1]
part = part + [0]*(D-len(part)) # e.g. [3,1]->[3,1,0] (padding)
for perm in set(permutations(part)): # e.g. [1,3,0], [1,0,3], ...
for point in product(*[ # e.g. [1,3,0], [-1,3,0], [1,-3,0], [-...
([-x,x] if x!=0 else [0]) for x in perm
]):
yield point
演示爲半徑= 4,尺寸= 3:
>>> result = list(points(4,3))
>>> result
[(-1, -2, -1), (-1, -2, 1), (-1, 2, -1), (-1, 2, 1), (1, -2, -1), (1, -2, 1), (1, 2, -1), (1, 2, 1), (-2, -1, -1), (-2, -1, 1), (-2, 1, -1), (-2, 1, 1), (2, -1, -1), (2, -1, 1), (2, 1, -1), (2, 1, 1), (-1, -1, -2), (-1, -1, 2), (-1, 1, -2), (-1, 1, 2), (1, -1, -2), (1, -1, 2), (1, 1, -2), (1, 1, 2), (0, -2, -2), (0, -2, 2), (0, 2, -2), (0, 2, 2), (-2, 0, -2), (-2, 0, 2), (2, 0, -2), (2, 0, 2), (-2, -2, 0), (-2, 2, 0), (2, -2, 0), (2, 2, 0), (-1, 0, -3), (-1, 0, 3), (1, 0, -3), (1, 0, 3), (-3, -1, 0), (-3, 1, 0), (3, -1, 0), (3, 1, 0), (0, -1, -3), (0, -1, 3), (0, 1, -3), (0, 1, 3), (-1, -3, 0), (-1, 3, 0), (1, -3, 0), (1, 3, 0), (-3, 0, -1), (-3, 0, 1), (3, 0, -1), (3, 0, 1), (0, -3, -1), (0, -3, 1), (0, 3, -1), (0, 3, 1), (0, -4, 0), (0, 4, 0), (0, 0, -4), (0, 0, 4), (-4, 0, 0), (4, 0, 0)]
>>> len(result)
66
(以上我用set(permutations(...))
得到不重複,這不是一般的高效率排列,但它可能這裏無關緊要因的性質點。如果效率很重要,你可以用自己選擇的語言編寫自己的遞歸函數。)
這種方法是有效的,因爲它不會隨着hypervolume擴展,而只是隨着超曲面擴展,這就是你想要的枚舉(除非是非常大的半徑,可能無關緊要:例如,如果您的半徑爲100,則會爲您節省大約100倍的速度)。
每個座標值可以採用的值集合是{0,1},對不對? –
@SteveJessop:我會說這是無邊界的網格,它的原點在某處,所以每個座標都可以取任何正整數值或零。 (xi屬於{0,1,2,...}) – izhak
在這種情況下,答案是「無限多」。從給定點開始,漢明距離1處的點集合是每個精確到1座標的點,這意味着它是通過'X'點繪製的一組完整的N軸。唯一的好消息是,它可以算是無限的,所以如果你有無限的時間,你可以枚舉它們;-) –