改变方程的ast.NodeTransformer的示例

时间:2011-06-17 11:48:10

标签: python abstract-syntax-tree genetic-programming

这是我上一个问题的延续。我想解析一个方程式并按照我得到的方式工作。我想要做的基本上是随机加扰它,所以我得到一个新的等式,它必须也是一个有效的函数。这将用于遗传算法。

这是我开始的地方:

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中,那就太好了。 请评论您的代码并提供测试样本/单元测试。

2 个答案:

答案 0 :(得分:1)

那么输入输出是Fortran代码吗?你想使用任意Fortran表达式/语句? (包括数组切片,......?)Fortran是一种非常复杂的语言;阅读它需要几乎完整的解析器。

也许你想使用一个可以直接操作Fortran的程序转换工具。这样的工具会读取Fortran代码,构建一个AST,让你使用一组随机选择的转换“随机化”它,然后重新生成有效的Fortran代码。

我们的DMS Software Reengineering Toolkit及其Fortran front end可以直接用于此。

编辑2011年8月26日:OP确认他想“进化”(转换)真正的Fortran代码。值得注意的是,构建一个真正的Fortran解析器(比如为任何其他真实语言构建解析器)非常困难;花了我们几个月的时间,我们的工具非常擅长定义解析器(我们使用DMS完成了大约40种语言和各种方言)。他建立自己真正的Fortran解析器可能不是一个好主意,至少不是因为他想要继续他的生活或他的实际任务。

OP可能会将Fortran代码约束到一个非常有限的子集,并为此构建一个解析器。

答案 1 :(得分:-1)

你想做什么?寻找方程的正确排列可能很容易但耗时(n!可能性),但生成新的并使用遗传算法优化那些是不可能的,因为它不是优化问题...例如x ^ 0.00和x ^ 0.01是根本不同的。此外,您无法针对合适的操作员进行优化,这是行不通的。遗憾。

虽然,情况并没有那么糟糕。寻找合适的功能是一项非常常见的任务。我现在假设你不知道这个功能,但你知道测量的几个要点(无论如何你都需要计算遗传算法的适应度,不是吗?)。您现在可以使用Lagrange来获取通过这些给定点的多项式。在wikipedia文章的中间有两个很好的例子,lagrange很容易实现(我估计有10行代码)。另请注意,您可以通过添加更多参考点来提高多项式的准确性。