Есть N-мерный единичный куб (все координаты вершин заданы бинарными числами).
Из вершины (0,0,...,0) начинает "расти змея". На каждом шаге змея смотрит на ребра графа идущие из текущей вершины. Змея может продолжить рост только в ту вершину, которая не инцидентна (не имеет общего ребра) ни с одной уже посещенной вершиной.
Так например для трехмерного куба решением является такая последовательность:
(0,0,0)-(1,0,0)-(1,1,0)-(1,1,1)-(0,1,1), то есть длина змеи будет 4.
Какую змею вы сможите построить для, скажем, 8ми мерного куба?
Н>>8 — не дождался... разброс ребер после захождения в тупик (от 14 — до 72)
Ещё бы, там примерно факториал от количества вершин.
Н>>Сдается мне, что задача численного решения не имеет
К>http://mathworld.wolfram.com/Snake.html
К>приводит значения ...2, 4, 8, 14, 26...
Набросал программу на питоне.
def adj(x,y) :
""" adjacent, т.е. смежны ли вершины x,y """
z = x^y # двоичный вектор расстояния
return (z&(z-1)) == 0 # истина, если не более одного бита взведено
def offside(x,path) :
""" проверка, что x не смежна ни с одной вершиной пути """
for y in path :
if adj(x,y) : return False
return True
class snake :
""" решатель задачи о змее на гиперкубе """
#
dim = 5 # размерность гиперкуба
orts = [] # множество ортов (пригодится ниже)
#
def init_orts(self) :
""" инициализация ортов """
self.orts = [1<<i for i in range(self.dim)]
#
def __init__(self,d) :
""" параметр змеи - размерность """
self.dim = d
self.init_orts()
#
maxbet = 0 # длина наилучшего найденного решения
#
def nexts(self,x) :
""" множество вершин, смежных с x """
return [x^o for o in self.orts]
#
def step(self,path) :
""" множество (генератор) поползновений змеи на одно ребро """
tail = path[0:-1] # хвост змеи (первые n-1 элементов)
head = path[-1] # голова змеи (последний элемент)
for x in self.nexts(head) : # куда змея в принципе может ползти
if offside(x,tail) : # условие несмежности с хвостом
yield path+[x]
#
def walk(self,path) :
""" генератор поползновений змеи (поиск вглубь); условие: каждое новое длиннее предыдущих """
bet1 = len(path)+1
for path1 in self.step(path) : # проползли на один шаг...
for path2 in self.walk(path1) : # и с этого места до упора
yield path2 # докуда доползли, это и вернули
if self.maxbet < bet1 : # если path1 лучше предыдущих решений (фактически, если не доползли)
self.maxbet = bet1
print "....<",bet1,">",path1
yield path1 # то запомним это решение как лучшее, и вернём
#
def run(self) :
self.maxbet = 0
best = []
for path in self.walk([0,1,3,7]) : # первая часть пути - однозначна
if len(best)<len(path) : # будем запоминать наилучшее из найденных решений
best = path
return best
snake(3).run()
#....< 5 > [0, 1, 3, 7, 6]
snake(4).run()
#....< 8 > [0, 1, 3, 7, 6, 14, 12, 13]
snake(5).run()
#....< 13 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24]
#....< 14 > [0, 1, 3, 7, 15, 14, 12, 28, 29, 25, 27, 26, 18, 22]
snake(6).run()
#....< 22 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52, 36, 37]
#....< 24 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 53, 52, 54, 50, 34, 42, 43, 47]
#....< 25 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 41, 43, 42, 34, 50, 51, 55, 53, 52, 36]
#....< 26 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 25, 27, 26, 18, 50, 51, 55, 63, 47, 43, 42, 40, 56, 60, 52, 36, 37]
#....< 27 > [0, 1, 3, 7, 15, 13, 12, 28, 20, 21, 53, 37, 36, 38, 46, 62, 63, 59, 43, 41, 40, 56, 48, 50, 18, 26, 10]
snake(7).run()
#....< 35 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52,
# 36, 37, 101, 103, 102, 98, 96, 104, 105, 107, 123, 122, 126, 124, 125]
#....< 40 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52,
# 36, 37, 101, 103, 102, 98, 96, 104, 105, 107, 123, 122, 126, 124, 92, 84,
# 85, 87, 83, 82]
#....< 41 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52,
# 36, 37, 101, 103, 102, 98, 96, 104, 105, 107, 123, 122, 126, 124, 92, 84,
# 86, 87, 83, 81, 89]
#....< 42 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52,
# 36, 37, 101, 103, 102, 98, 96, 104, 105, 73, 89, 81, 80, 82, 86, 94, 92,
# 124, 125, 127, 123, 122]
#....< 43 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52,
# 36, 37, 101, 103, 102, 98, 96, 104, 108, 124, 125, 127, 123, 107, 75, 73,
# 89, 81, 83, 82, 86, 84, 68]
#....< 44 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52,
# 36, 37, 101, 103, 102, 98, 96, 104, 72, 73, 89, 81, 80, 82, 86, 94, 92,
# 124, 125, 127, 123, 107, 43, 42]
#....< 45 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52,
# 36, 37, 101, 97, 96, 112, 80, 81, 89, 73, 72, 74, 106, 42, 43, 47, 111,
# 127, 119, 87, 86, 94, 92, 124, 108]
#....< 46 > [0, 1, 3, 7, 6, 14, 12, 13, 29, 31, 27, 26, 24, 56, 57, 49, 51, 50, 54, 52,
# 36, 37, 101, 69, 68, 84, 86, 87, 83, 81, 89, 73, 72, 74, 66, 98, 102, 110,
# 108, 124, 125, 127, 123, 107, 43, 42]
(дальше стало лень ждать; всё-таки питон это не С++, да и способ работы выбран не самый быстрый).