改变方程的 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 中,那就太好了。 请评论您的代码并提供测试示例/单元测试。
This is a continuation of my last question. I want to parse an equation and work on the ast I get. What I want to do is basically randomly scramble it so I get a new equation, that has to be also a valid function. This is to be used in a genetic algorithm.
Here is where I start:
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
What I want to get out is something like this :
res= e**(delta*((one/delta_w*one)**2)))
or another valid random equation of some sort. This will be used in a Fortran program, so it would be nice if the resulting equation can also be transferred into Fortran.
Please comment your code and provide a test sample/unit test.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
那么输入和输出是Fortran代码吗?您想使用任意 Fortran 表达式/语句吗? (包括数组切片,...?)Fortran 是一种相当复杂的语言;阅读它几乎需要一个完整的解析器。
也许您想使用已经可以直接操作 Fortran 的程序转换工具。这样的工具将读取 Fortran 代码,构建 AST,让您使用一组随机选择的转换对其进行“随机化”,然后重新生成有效的 Fortran 代码。
我们的 DMS 软件重组工具包及其 Fortran 前端 可以直接用于此目的。
2011 年 8 月 26 日编辑:OP 确认他想要“进化”(转换)真正的 Fortran 代码。值得注意的是,构建一个真正的 Fortran 解析器(就像为任何其他真实语言构建解析器一样)非常困难;我们花了几个月的时间,我们的工具确实非常擅长定义解析器(我们已经使用 DMS 完成了大约 40 种语言和各种方言)。对于他来说,构建自己的真正的 Fortran 解析器可能不是一个好主意,至少如果他想继续他的生活或他的实际任务的话。
OP 有可能将 Fortran 代码限制在一个非常有限的子集,并为此构建一个解析器。
So the input and the output are Fortran code? And you want to use arbitrary Fortran expressions/statements? (Including array slices, ...?) Fortran is a pretty complex language; reading it requires pretty much a full parser.
Perhaps you want to use an program transformation tool that can already manipulate Fortran directly. Such a tool would read the Fortran code, build an AST, let you "randomize" it using a set of randomly chosen transformations, and then regenerate valid Fortran code.
Our DMS Software Reengineering Toolkit with its Fortran front end could be directly used for this.
EDIT Aug 26 2011: OP confirms he wants to "evolve" (transform) real Fortran code. It is worth noting that building a real Fortran parser (like building parsers for any other real language) is pretty hard; it took us months and our tools are really good at defining parsers (we've done some 40 languages and a variety of dialects using DMS). It is probably not a good idea for him to build his own real Fortran parser, at least not if he wants to get on with his life or his actual task.
It might be possible for OP to constrain the Fortran code to a very restricted subset, and build a parser for that.
你想做什么?寻找方程的正确排列可能很容易,但很耗时(n!种可能性),但生成新方程并使用遗传算法优化它们是不可能的,因为这不是一个优化问题......例如 x^ 0.00 和 x^0.01 是根本不同的。此外,您无法针对正确的运算符进行优化,这是行不通的。对不起。
虽然,情况并没有那么糟糕。寻找正确的功能是一项极其常见的任务。我现在假设您不知道该函数,但您从测量中知道几个点(无论如何您都需要它来计算遗传算法中的适应度,不是吗?)。现在,您可以使用 拉格朗日 来获取通过这些给定点的多项式。维基百科文章中间有两个很好的例子,拉格朗日很容易实现(我猜不到 10 行代码)。另请注意,您只需添加更多参考点即可提高多项式的准确性。
What are you trying to do? Looking for the right permutation of an equation might be easy but time consuming (n! possibilities), but generating new ones and optimize those using a genetic algorithm is imho impossible, because it`s not an optimization problem... For example x^0.00 and x^0.01 are fundamental different. Also, you can not optimize for the right operator, that just won't work. Sorry.
Although, the situation isn't that bad. Looking for the right function is an extremely common task. I am now assuming that you do not know the function, but you know a couple of points from measurements (you would have needed that to calculate the fitness in your genetic algorithm anyway, didn't you?). You now can use Lagrange to get a polynomial which passes those given points. There are two good examples in the middle of the wikipedia article, and lagrange is quite easy to implement (<10 lines of code I guess). Also note that you have the ability to improve the accuracy of the polynomial just by adding more reference points.