วิธีใช้ Mathematica จาก Python
ฉันใช้โค้ดบรรทัดต่อไปนี้เพื่อสร้างเรขาคณิต 3 มิติ ( อ้างอิง ) ปัจจัยการผลิตedges, vd, vlและewมาจากงูใหญ่ในรูปแบบดังต่อไปนี้
edges = [(1,2), (1,3), (1,4), (2,5), (2,6), (5,6), (3,4), (3,7), (6,7), (7,8), (2,9)];
vl = [1,2,3,4,5,6,7,8,9]
ew = {(1, 2) : 49.6, (1,3): 74.4, (1, 4) : 49.6, (2,5): 37.2, (2, 6) : 74.4, (5, 6): 49.6,
(3, 4) : 37.2, (3, 7):24.8, (6, 7) : 62, (7, 8) : 37.2, (2, 9) : 24.8}
vd = {1:[75., 25., 0], 2:[115., 45., 0], 3:[10., 5., 0], 4:[45., 0, 0],
5:[90., 60., 0], 6:[45., 55., 0], 7:[0, 25., 0], 8:[10., 50., 0], 9:[115., 25.,0]};
ฉันแปลงด้านบนเป็นรูปแบบอินพุตที่ใช้ใน Mathematica ด้วยตนเอง ฉันต้องการทราบวิธีหลีกเลี่ยงการแปลงด้วยตนเองนี้และรวมและเรียกใช้โค้ด Mathematica จาก Python โดยตรง
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., 0}, {10., 5., 0}, {45., 0, 0},
{90., 60., 0}, {45., 55., 0}, {0, 25., 0}, {10., 50., 0}, {115., 25.,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]
คำแนะนำเกี่ยวกับวิธีดำเนินการต่อและเชื่อมต่อ Mathematica จาก Python จะเป็นประโยชน์มาก
แก้ไข: PythonExpressionคำตอบที่โพสต์ด้านล่างจะช่วยในการส่งผ่านข้อมูลจากการขัดแย้งหลามใช้ ต่อไปฉันต้องการประเมินนิพจน์ Mathematica เหล่านี้จากสคริปต์ python ตามความคิดเห็นด้านล่างฉันติดตั้ง Wolframclient และทำสิ่งต่อไปนี้
from wolframclient.evaluation import WolframLanguageSession
session = WolframLanguageSession()
from wolframclient.language import wlexpr
session.evaluate(wlexpr('')) # I would like to know how to inclide Mathematica expressions here
EDIT2: ฉันทำได้
session.evaluate(wlexpr(
'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., 0}, {10., 5., 0}, {45., 0, 0},{90., 60., 0}, {45., 55., 0}, {0, 25., 0}, {10., 50., 0}, {115., 25.,0}};'
'vl = Range[Length@vd];'))
ฉันเหนื่อย,
from wolframclient.evaluation import WolframLanguageSession
session = WolframLanguageSession()
from wolframclient.language import wlexpr
session.evaluate(wlexpr(
'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., 0}, {10., 5., 0}, {45., 0, 0},{90., 60., 0}, {45., 55., 0}, {0, 25., 0}, {10., 50., 0}, {115., 25.,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];'
'z1 = Values[solution3d] // Partition[#, 3] &;'
'theFile = File["op.txt"];'
'Export[theFile, z1, "Table"];'
))
แต่ฉันได้รับข้อผิดพลาดต่อไปนี้
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Undefined message MessageName[Message, msgl] with arguments {$MessageList}
The problem may be unbounded. Specifying a value for MaxIterations greater than 5000 may improve the solution.
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Undefined message MessageName[Message, msgl] with arguments {$MessageList}
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Further output of MessageName[StringForm, string] will be suppressed during this calculation.
The problem may be unbounded. Specifying a value for MaxIterations greater than 5000 may improve the solution.
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Undefined message MessageName[Message, msgl] with arguments {$MessageList}
The problem may be unbounded. Specifying a value for MaxIterations greater than 5000 may improve the solution.
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Undefined message MessageName[Message, msgl] with arguments {$MessageList}
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Further output of MessageName[StringForm, string] will be suppressed during this calculation.
The problem may be unbounded. Specifying a value for MaxIterations greater than 5000 may improve the solution.
คุณช่วยแนะนำวิธีแก้ไขได้ไหม ดังที่แสดงด้านล่างไม่มีปัญหาในการเรียกใช้นิพจน์เดียวกันในสมุดบันทึก MMA
คำตอบ
นี่เป็นวิธีหนึ่งในการทำสิ่งที่คุณต้องการใน Mathematica
ขั้นแรกการใช้ "PythonExpression" สามารถนำเข้า / ส่งออกสิ่งต่างๆได้สะดวก:
{edges,vl,ew,vd}=ImportString[#,"PythonExpression"]&/@ {"[(1,2),(1,3),(1,4),(2,5),(2,6),(5,6),(3,4),(3,7),(6,7),(7,8),(2,9)]",
"[1,2,3,4,5,6,7,8,9]","{(1,2):49.6,(1,3):74.4,(1,4):49.6,(2,5):37.2,(2,6):74.4,(5,6):49.6,(3,4):37.2,(3,7):24.8,(6,7):62,(7,8):37.2,(2,9):24.8}",
"{1:[75.,25.,0],2:[115.,45.,0],3:[10.,5.,0],4:[45.,0,0],5:[90.,60.,0],6:[45.,55.,0],7:[0,25.,0],8:[10.,50.,0],9:[115.,25.,0]}"};
น่าเสียดายที่กราฟยังใช้ไม่ได้กับการเชื่อมโยงดังนั้นคุณต้องมีรายการและขอบควรใช้สัญลักษณ์เช่นUndirectedEdgeหรือDirectedEdge:
edges = UndirectedEdge @@@ edges; vcoords = List @@ vd;
ew = Normal @ KeyMap[UndirectedEdge @@ # &,ew];
g3d = Graph3D[vl, edges, VertexCoordinates -> vcoords,
EdgeWeight->ew, VertexLabels->Placed["Name",Center],
EdgeLabels->{e_:>Placed["EdgeWeight",Center]}, VertexSize->.5, BaseStyle->16]
การคำนวณของคุณเกือบจะใช้งานได้ แต่คุณต้องทำให้ขอบเป็นกฎ:
vars3d = Array[Through[{x, y, z}@#] &, Length@vd];
\[Lambda] = 1/100.; lbnd = 0; ubnd = 500;
obj3d = Total[(Norm[vars3d[[First@#]] - vars3d[[Last@#]]] - # /. (Rule @@@ ew))^2 & /@ EdgeList[g3d]] + \[Lambda] * Total[Norm /@ (vars3d - Values@vd)];
solution3d = Last @ Minimize[{obj3d, And @@ Thread[lbnd <= Join @@ vars3d <= ubnd]}, Join @@ vars3d]
จากนั้นก็ใช้งานได้ดี:
edgeLengths3d = # -> Norm[vars3d[[First@#]] - vars3d[[Last@#]]] /.
solution3d & /@ EdgeList[g3d];
ResourceFunction["PrettyGrid"][{#, # /. ew, # /. edgeLengths3d} & /@
EdgeList[g3d], "ColumnHeadings" -> {"edge", "EdgeWeight", "Edge Length"}]
ขออภัยฉันเข้าใจผิดและจำไม่ได้ว่าคุณต้องการใช้ MMA จาก Python ไม่ใช่ในทางกลับกัน ExternalEvaluate ["Python", str] เป็นคำสั่ง MMA ไม่ใช่ Python
วิธีป้อนข้อมูล MMA จาก Python มีอธิบายไว้ที่นี่: "https://reference.wolfram.com/language/workflow/EvaluateAWolframLanguageExpressionFromPython.html"
หลังจากเริ่ม Python คุณจะดำเนินการใน Python:
from wolframclient.evaluation import WolframLanguageSession
session = WolframLanguageSession()
from wolframclient.language import wlexpr
session.evaluate(wlexpr('myCommandString'))
โดย myCommandString คือสตริงที่มีคำสั่ง Mathematica ของคุณ เช่นใน Python:
myCommandString="a=1;b=2;a+b"
หรือถ้าคุณต้องการสิ่งนี้หลายบรรทัด:
myCommandString="a=1;"
myCommandString=myCommandString+"b=2;"
myCommandString=myCommandString+"a+b"
หวังว่านี่จะช่วยได้
หากคุณมีบล็อกของโค้ดที่ครอบคลุมในหลายบรรทัดอาจเป็นประโยชน์ในการวางไว้ในไฟล์. m และGetไฟล์จาก python นี่คือตัวอย่าง:
ขั้นแรกให้สร้างไฟล์และเขียนรหัสภาษา Wolfram ที่คุณต้องการประเมินในไฟล์ เรียกไฟล์/tmp/test.mกันเถอะ
ตอนนี้ใน Python:
from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl
# important note: the session is automatically closed.
with WolframLanguageSession() as s:
s.evaluate(wl.Get('/tmp/test.m'))
อย่าลืมปิดไม่WolframLanguageSessionเช่นนั้นคุณจะได้เมล็ดข้าวกำพร้า (ข้อมูลเพิ่มเติมที่นี่ )
อย่างที่คุณเห็นขั้นตอนการประเมินตอนนี้อยู่ในบรรทัดเดียว คุณมีอิสระที่จะอัปเดตโค้ดของคุณในโปรแกรมแก้ไขที่คุณชื่นชอบ นั่นคือสิ่งที่ฉันทำกับรหัสเริ่มต้นของคุณฉันเพิ่งเพิ่มเครื่องหมายอัฒภาคที่ขาดหายไปสองตัวและส่งออกผลลัพธ์ตามที่ดำเนินการในภายหลัง
นี่คือ/tmp/test.mไฟล์ของฉัน:
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., 0}, {10., 5., 0}, {45., 0, 0}, {90.,
60., 0}, {45., 55., 0}, {0, 25., 0}, {10., 50., 0}, {115., 25.,
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];
\[Lambda] = 1/100.;
obj3d = Total[(Norm[vars3d[[First@#]] - vars3d[[Last@#]]] - # /.
ew)^2 & /@ EdgeList[g3d]] + \[Lambda] 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];
z1 = Values[solution3d] // Partition[#, 3] &;
Export["/tmp/result.txt", z1, "Table"];
```