Оценка дерева без необходимости создания интерпретатора (Python) - PullRequest
0 голосов
/ 26 октября 2019

Ранее на этой неделе я задал общий вопрос в связанном SO-сообществе относительно построения математических деревьев с использованием ООП. Основной вывод состоял в том, что шаблоны Composite и Interpreter были шаблонами перехода для этого вида приложений.

Затем я потратил несколько дней, просматривая в Интернете ресурсы о том, как они построены. Я все еще убежден, что мне не нужно создавать весь интерпретатор и что для моих целей может быть достаточно составного.

Из другого вопроса, который я пытался построить это дерево:

enter image description here

Без использования ООП я бы, вероятно, сделал что-то вроде этого:

import numpy as np

def root(B, A):
    return B+A

def A(x,y,z):
    return x*np.log(y)+y**z

def B(alpha, y):
    return alpha*y

def alpha(x,y,w):
    return x*y+w

if __name__=='__main__':

    x,y,z,w = 1,2,3,4
    result = root(B(alpha(x,y,w),y), A(x,y,z))

Это даст правильный результат 20.693147180559947. Я попытался использовать составной шаблон, чтобы сделать что-то подобное:

class ChildElement:
    '''Class representing objects at the bottom of the hierarchy tree.'''
    def __init__(self, value):
        self.value = value
    def __repr__(self):
        return "class ChildElement with value"+str(self.value)
    def component_method(self):
        return self.value


class CompositeElement:
    '''Class representing objects at any level of the hierarchy tree except for the bottom level.
      Maintains the child objects by adding and removing them from the tree structure.'''
    def __init__(self, func):
        self.func = func
        self.children = []
    def __repr__(self):
        return "class Composite element"
    def append_child(self, child):
        '''Adds the supplied child element to the list of children elements "children".'''
        self.children.append(child)
    def remove_child(self, child):
        '''Removes the supplied child element from the list of children elements "children".'''
        self.children.remove(child)
    def component_method(self):
        '''WHAT TO INCLUDE HERE?'''


if __name__=='__main__':

    import numpy as np

    def e_func(A, B):
        return A+B

    def A_func(x,y,z):
        return x*np.log(y)+y**z

    def B_func(alpha,y):
        return alpha*y

    def alpha_func(x,y,w):
        return x*y+w

    x = ChildElement(1)
    y = ChildElement(2)
    z = ChildElement(3)
    w = ChildElement(4)

    e = CompositeElement(e_func)
    A = CompositeElement(A_func)
    B = CompositeElement(B_func)
    alpha = CompositeElement(alpha_func)

    e.children = [A, B]
    A.children = [x, y, z]
    B.children = [alpha, y]
    alpha.children = [x, y, w]
    e.component_method()

Однако я застрял в последней строке. Кажется, что если я вызову component_method на уровне экземпляра составного класса e, он не будет работать, так как архитектура не предназначена для обработки добавления двух дочерних или составных объектов.

Как я могузаставить это работать? Что должен содержать component_method для моего CompositeElement класса?

Спасибо

1 Ответ

1 голос
/ 26 октября 2019
def component_method(self):
    values = [child.component_method() for child in self.children]
    return self.func(*values)

Это будет оценивать дочерние узлы и передавать значения в функцию самого узла, возвращая значение.

...