Ваш пример импортирует случайные и случайные числа, но никогда не использует их. У него также есть «для i в диапазоне (2))» без тела. Это явно недопустимый код Python.
Вы не определяете, какой «груз» и какие узлы должны содержать. Кажется, что «cargo» - это число, поскольку оно происходит из itertools.count (). Next (). Но это не имеет смысла, так как вы хотите, чтобы результат был eval'able строкой Python.
Если вы выполняете разовую оценку дерева, то самым быстрым решением было бы оценить его непосредственно на месте, но без реального примера данных, с которыми вы работаете, я не могу показать пример .
Если вы хотите сделать это еще быстрее, смотрите дальше вверх по течению. Почему вы генерируете дерево, а затем оцениваете его? Разве вы не можете оценить компоненты непосредственно в коде, который в настоящее время генерирует древовидную структуру? Если у вас есть такие операторы, как «+» и «*», рассмотрите возможность использования вместо этого operator.add и operator.mul, которые могут работать непосредственно с данными без промежуточного шага.
== Обновление ==
Это основано на ответе Пола Ханкина. Я убрал промежуточную древовидную структуру и просто оценил выражение напрямую.
def build_tree2(n):
if n == 0:
return random.randrange(100)
else:
left = build_tree2(n-1)
right = build_tree2(n-1)
return left+right
Это примерно в 5 раз быстрее, чем решение Павла.
Возможно, вам нужно знать фактическую древовидную структуру наилучшего решения или верхнюю часть k N, где k << N. Если это так, то вы можете восстановить эти деревья в последующем, если вы также сохраните отслеживание состояния ГСЧ, используемого для генерации результатов. Например: </p>
def build_tree3(n, rng=random._inst):
state = rng.getstate()
return _build_tree3(n, rng.randrange), state
def _build_tree3(n, randrange):
if n == 0:
return randrange(100)
else:
left = _build_tree3(n-1, randrange)
right = _build_tree3(n-1, randrange)
return left+right
Как только вы найдете лучшие значения, используйте ключ для восстановления дерева
# Build Paul's tree data structure given a specific RNG
def build_tree4(n, rng):
if n == 0:
return ConstantNode(rng.randrange(100))
else:
left = build_tree4(n-1, rng)
right = build_tree4(n-1, rng)
return ArithmeticOperatorNode("+", left, right)
# This is a O(n log(n)) way to get the best k.
# An O(k log(k)) time solution is possible.
rng = random.Random()
best_5 = sorted(build_tree3(8, rng) for i in range(10000))[:5]
for value, state in best_5:
rng.setstate(state)
tree = build_tree4(8, rng)
print tree.eval(), "should be", value
print " ", str(tree)[:50] + " ..."
Вот как это выглядит, когда я запускаю его
10793 should be 10793
((((((((92 + 75) + (35 + 69)) + ((39 + 79) + (6 + ...
10814 should be 10814
((((((((50 + 63) + (6 + 21)) + ((75 + 98) + (76 + ...
10892 should be 10892
((((((((51 + 25) + (5 + 32)) + ((40 + 71) + (17 + ...
11070 should be 11070
((((((((7 + 83) + (77 + 56)) + ((16 + 29) + (2 + 1 ...
11125 should be 11125
((((((((69 + 80) + (11 + 64)) + ((33 + 21) + (95 + ...