Подтвердить что ты не робот

Пример для ast.NodeTransformer, который мутирует уравнение

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

Здесь я начинаю:

class Py2do(ast.NodeTransformer):
def __init__(self):
  self.tree=[]
def generic_visit(self, node):
    print type(node).__name__
    self.tree.append(type(node).__name__)
    ast.NodeVisitor.generic_visit(self, node)
    depth=3
    s = node.__dict__.items()
    s = "    ".join("%s %r" % x for x in sorted(node.__dict__.items()))
    print( "%s%s\t%s" % (depth, str(type(node)), s) )
    for x in ast.iter_child_nodes(node):
      print (x, depth)

def visit_Name(self, node):
    # print 'Name :', node.id
    pass

def visit_Num(self, node):
    print 'Num :', node.__dict__['n']

def visit_Str(self, node):
    print "Str :", node.s

def visit_Print(self, node):
    print "Print :"
    ast.NodeVisitor.generic_visit(self, node)

def visit_Assign(self, node):
    print "Assign :"
    ast.NodeVisitor.generic_visit(self, node)

def visit_Expr(self, node):
    print "Expr :"
    ast.NodeVisitor.generic_visit(self, node)





if __name__ == '__main__':
    node = ast.parse("res= e**(((-0.5*one)*((delta_w*one/delta*one)**2)))")
    import ast_pretty
    print ast.dump(node)
    pprintAst(node)
    v = Py2do()
    v.visit(node)
    print v.tree

То, что я хочу выбраться, выглядит примерно так:

res= e**(delta*((one/delta_w*one)**2)))

или другое допустимое случайное уравнение. Это будет использоваться в программе Fortran, поэтому было бы неплохо, если бы полученное уравнение также можно было перенести в Fortran. Прокомментируйте свой код и предоставите тестовый образец/ unit test.

4b9b3361

Ответ 1

Итак, вход и выход - это код Fortran? И вы хотите использовать произвольные выражения/выражения Fortran? (Включая массивы,...?) Fortran - довольно сложный язык; его чтение требует довольно полного анализатора.

Возможно, вы хотите использовать инструмент преобразования программ, который уже может напрямую манипулировать Fortran. Такой инструмент мог бы прочитать код Fortran, построить AST, позволить вам "рандомизировать" его с помощью набора случайно выбранных преобразований, а затем восстановить действующий код Fortran.

Наш DMS Software Reengineering Toolkit с его Frontran Frontran может быть непосредственно использован для этого.

EDIT 26 августа 2011: OP подтверждает, что хочет "развить" (преобразовать) настоящий код Fortran. Стоит отметить, что создание реального синтаксического анализатора Fortran (например, парсеров для построения любого другого реального языка) довольно сложно; нам потребовались месяцы, и наши инструменты действительно хороши в определении парсеров (мы сделали около 40 языков и множество диалектов, используя DMS). Вероятно, это не очень хорошая идея для его создания собственного реального синтаксического анализатора Fortran, по крайней мере, нет, если он хочет продолжить свою жизнь или свою фактическую задачу.

Возможно, OP может ограничить код Fortran очень ограниченным подмножеством и построить для него синтаксический анализатор.

Ответ 2

Что вы пытаетесь сделать? Поиск правильной перестановки уравнения может быть легким, но требующим много времени (n! Возможностей), но генерируя новые и оптимизируя те, которые используют генетический алгоритм, является невозможным, потому что это не проблема оптимизации... Например, x ^ 0,00 и x ^ 0,01 являются принципиально разными. Кроме того, вы не можете оптимизировать для правильного оператора, который просто не сработает. К сожалению.

Хотя, ситуация не так уж плоха. Поиск правильной функции - чрезвычайно общая задача. Я теперь предполагаю, что вы не знаете эту функцию, но вы знаете пару баллов из измерений (вам понадобилось бы, чтобы вычислить пригодность в вашем генетическом алгоритме в любом случае, не так ли?). Теперь вы можете использовать Lagrange, чтобы получить полином, который передает эти данные. В середине статьи wikipedia есть два хороших примера, и лагранж довольно прост в реализации (и 10 строк кода, которые я предполагаю). Также обратите внимание, что у вас есть возможность улучшить точность полинома, просто добавив больше опорных точек.