问题描述
我有以下Mathematica代码来将图形的边长缩放为等于边权重。 (ref)
edges = {1 <-> 2,1 <-> 3,1 <-> 4,2 <-> 5,2 <-> 6,5 <-> 6,3 <-> 4,3 <-> 7,6 <-> 7,7 <-> 8,2 <-> 9};
vd = {{75.,25.,0},{115.,45.,{10.,5.,{45.,{90.,60.,55.,{0,50.,0}};
vl = Range[Length@vd];
vcoords = MapIndexed[#2[[1]] -> # &,vd];
ew = {1 \[UndirectedEdge] 2 -> 49.6,1 \[UndirectedEdge] 3 -> 74.4,1 \[UndirectedEdge] 4 -> 49.6,2 \[UndirectedEdge] 5 -> 37.2,2 \[UndirectedEdge] 6 -> 74.4,5 \[UndirectedEdge] 6 -> 49.6,3 \[UndirectedEdge] 4 -> 37.2,3 \[UndirectedEdge] 7 -> 24.8,6 \[UndirectedEdge] 7 -> 62,7 \[UndirectedEdge] 8 -> 37.2,2 \[UndirectedEdge] 9 -> 24.8}
g3d = Graph3D[vl,edges,VertexCoordinates -> vcoords,EdgeWeight -> ew,VertexLabels -> Placed["Name",Center],EdgeLabels -> {e_ :> Placed["EdgeWeight",Center]},VertexSize -> .3,VertexStyle -> Red]
vars3d = Array[Through[{x,y,z}@#] &,Length @ vd];
λ = 1/100.;
obj3d = Total[(Norm[vars3d[[First@#]] - vars3d[[Last@#]]] - # /. ew)^2 & /@
EdgeList[g3d]] + λ Total[Norm /@ (vars3d - vd)];
lbnd = 0;
ubnd = 500;
solution3d = Last@Minimize[{obj3d,And @@ Thread[lbnd <= Join @@ vars3d <= ubnd]},Join @@ vars3d];
edgeLengths3d = # -> Norm[vars3d[[First@#]] - vars3d[[Last@#]]] /.
solution3d & /@ EdgeList[g3d];
Grid[Prepend[{#,# /. ew,# /. edgeLengths3d} & /@
EdgeList[g3d],{"edge","EdgeWeight","Edge Length"}],Dividers -> All]
我正在尝试用Python重写相同的代码。输入已转换为 python数据类型列表和字典。
edges = [(1,2),(1,3),4),(2,5),6),(5,(3,7),(6,(7,8),9)];
vl = [1,2,3,4,5,6,7,8,9]
ew = {(1,2) : 49.6,3): 74.4,4) : 49.6,5): 37.2,6) : 74.4,6): 49.6,4) : 37.2,7):24.8,7) : 62,8) : 37.2,9) : 24.8}
vd = {1:[75.,0],2:[115.,3:[10.,4:[45.,5:[90.,6:[45.,7:[0,8:[10.,9:[115.,0]};
我不确定必须如何在Python中转换优化命令。
有关如何在Python中编写obj3d
和solution3d
行的建议将很有帮助。
解决方法
如何将Mathematica中的代码转换为Python?
如果代码很小(几百行),则最好手动进行转换(或分包)。
您需要阅读Mathematica和Python的文档。
如果代码很大(成千上万行),则可以考虑对source to source转换器进行编码。为此,请阅读Dragon book,然后选择高级编程语言(例如Ocaml或SBCL或Haskell)来编写这样的翻译器(使用解析器生成器工具,例如Menhir,ANTLR以及受Iburg等启发的方法...)。预算半年的全职工作。
,将Mathematica转换为Python
这只是在某种程度上使用了各种语言和工具完成的,到目前为止,我还不知道完整的解决方案。
我研究了一下,可行的路线可能是:
Mathematica -> SymPy / ANTLR -> Python
要么
Mathematica -> C / Fortran -> Callable from Python
(自然地)Mathematica的处理方式比面向对象的方式更具功能性,因此直接转换为Python可能是可行的,但会导致看上去有些毛茸茸的Python代码。
如果您确实想继续沿Mathematica -> Python
路线走,那会有一个非常聪明的人(量子信息与基金会组织CSIC的资深科学家),名叫JuanJoséGarcíaRipoll,他已经启动了转换Mathematica笔记本的工具直接使用Python。
它使用了一个非常简单的基于解析器的方法,该方法基本上会爬过Mathematica表达式,将运算符转换为Python等效项,并从中创建有效的Python表达式。 暂时它可以用于最简单的操作,但是如果您不想从头开始,那将是一个不错的起点。
它已经能够翻译Mathematica表达式,例如:
进入Python代码,所以这不是那基本的。不错的起点。
您可以下载包含代码和示例的Mathematica Notebook文件 here
解释该工具的博客文章为here
Mathics项目在同一域中还包含一些有趣的代码。您可能想查看相关的source files。
我知道这不能完全回答您的问题,但是它确实提供了使其可行的解决方案的指针,尽管这需要一些工作。