กราฟระนาบของฉันคืออะไร?


29

งานของคุณคือการตรวจสอบว่ากราฟเป็นระนาบ

กราฟคือระนาบถ้ามันสามารถฝังตัวในระนาบหรือกล่าวอีกนัยหนึ่งว่าสามารถวาดได้โดยไม่ต้องข้ามขอบ

อินพุต:คุณจะได้รับกราฟที่ไม่ระบุทิศทางในรูปแบบที่คุณเลือกดังนี้:

  • รายการขอบเช่น [(0, 1), (0, 2), (0, 3)]

  • แผนที่ Adjacency เช่น {0: [1, 2, 3], 1:[0], 2:[0], 3:[0]}

  • เมทริกซ์ที่อยู่ติดกันเช่น [[0, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]

ชื่อโหนดอาจเป็นตัวเลขสตริงหรือคล้ายกัน แต่รูปแบบที่คุณเลือกจะต้องสามารถรองรับกราฟโดยพลการ ไม่มีการวางโค้ดในชื่อโหนด จะไม่มีลูปตัวเอง

ตัวเลือกอินพุตมาตรฐานรวมถึง STDIN อาร์กิวเมนต์บรรทัดคำสั่งและฟังก์ชันอาร์กิวเมนต์

เอาท์พุท:คุณควรส่งคืนเอาต์พุตที่เฉพาะเจาะจงสำหรับกราฟระนาบทั้งหมดและเอาท์พุทที่เฉพาะเจาะจงที่แตกต่างกันสำหรับกราฟ nonplanar ทั้งหมด

ตัวเลือกเอาต์พุตมาตรฐานรวมถึง STDOUT ค่าส่งคืนของฟังก์ชัน

ตัวอย่าง:

ระนาบ:

[]
[(0,1), (0,2), (0,3), (0,4), (0,5), (0,6)]
[(0,1), (0,2), (0,3), (1,2), (1,3), (2,3)]
[(0,2), (0,3), (0,4), (0,5), (1,2), (1,3), (1,4), (1,5), (2,3),
 (2,5), (3,4), (4,5)]

nonplanar:

[(0,1), (0,2), (0,3), (0,4), (1,2), (1,3), (1,4), (2,3), (2,4), (3,4)]
[(0,3), (0,4), (0,5), (1,3), (1,4), (1,5), (2,3), (2,4), (2,5)]
[(0,3), (0,4), (0,6), (1,3), (1,4), (1,5), (2,3), (2,4), (2,5), (5,6), 
 (7,8), (8,9), (7,9)]

ฟังก์ชั่นใด ๆ ที่ดำเนินการทดสอบระนาบอย่างชัดเจนหรือมิฉะนั้นการอ้างอิงเฉพาะงานแต่งงานภาพถ่ายจะไม่ได้รับอนุญาต

นี่คือรหัสกอล์ฟ อาจเป็นรหัสที่สั้นที่สุดชนะ


เป็นคำถามที่ดี!

เป็นเรื่องที่ดีมากที่นี่เป็นปัญหาแบบคลาสสิกและยังมีวิธีการที่เป็นไปได้หลายวิธีรวมถึงวิธีที่ไม่ได้ใช้ในรหัสเพื่อวัตถุประสงค์ทั่วไป
lirtosiast

กรณีทดสอบสำหรับกราฟที่ไม่ได้เชื่อมต่อกับระนาบหนึ่งและองค์ประกอบที่เชื่อมต่อที่ไม่ใช่ระนาบหนึ่งจะดี
ปีเตอร์เทย์เลอร์

@PeterTaylor แน่นอนฉันจะเพิ่มอีก
isaacg

5
@RenaeLider ขออภัย แต่ฉันไม่เข้าใจ คำถามไม่เกี่ยวกับตัวเลขทศนิยมใด ๆ - มันไม่ได้ใช้ตัวเลขจริงๆเพียงแค่ติดป้าย
isaacg

คำตอบ:


14

Mathematica, 201 ไบต์

f@g_:=EdgeCount@g<9||!(h=g~IsomorphicGraphQ~CompleteGraph@#&)@5&&!h@{3,3}&&And@@(f@EdgeDelete[g,#]&&f@EdgeContract[g,#]&/@EdgeList@g);And@@(f@Subgraph[g,#]&/@ConnectedComponents[g=Graph[#<->#2&@@@#]])&

สิ่งนี้ประเมินว่าเป็นฟังก์ชันที่ไม่มีชื่อซึ่งใช้รายการขอบเช่น

{{0, 3}, {0, 4}, {0, 5}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}}

นี่เป็นวิธีแบบเรียกซ้ำที่ไม่มีประสิทธิภาพอย่างน่ากลัวตามทฤษฎีบทของ Wagner :

กราฟ จำกัด เป็นระนาบหากว่าไม่มีK 5หรือK 3,3เป็นกราฟย่อย

ที่นี่K 5เป็นกราฟสมบูรณ์ที่มี 5 จุดยอดและK 3,3เป็นกราฟสองส่วนที่สมบูรณ์พร้อม 3 จุดยอดในแต่ละกลุ่ม กราฟเป็นเล็ก ๆ น้อย ๆของกราฟBถ้ามันสามารถจะได้รับจากBโดยลำดับของการลบขอบและการหดตัวของขอบ

ดังนั้นรหัสนี้จะตรวจสอบว่ากราฟ isomorphic เป็นK 5หรือK 3,3หรือไม่ถ้าไม่ใช่ก็จะเรียกซ้ำอีกครั้งเพื่อลบหรือหดตัวทุกครั้ง

การจับคือการลบหรือทำสัญญากับขอบในองค์ประกอบหนึ่งของกราฟที่ไม่เชื่อมโยงกันจะไม่กำจัดจุดยอดทั้งหมดที่นั่นดังนั้นเราจะไม่พบความผิดปกติที่ต้องการ ดังนั้นเราจึงใช้การค้นหานี้กับส่วนประกอบที่เชื่อมต่อของกราฟอินพุตแยกกัน

วิธีนี้ใช้งานได้เร็วมากสำหรับอินพุตที่กำหนด แต่ถ้าคุณเพิ่มขอบอีกสองสามอันมันจะใช้เวลานานมากในการทำลายอย่างรวดเร็ว (และใช้หน่วยความจำจำนวนมากเช่นกัน)

นี่คือเวอร์ชันที่เยื้องของf(ฟังก์ชันที่ไม่มีชื่อหลังจากเพิ่งสร้างวัตถุกราฟจากอินพุต:

f@g_ := 
  EdgeCount@g < 9 || 
  ! (h = g~IsomorphicGraphQ~CompleteGraph@# &)@5 && 
  ! h@{3, 3} &&
  And @@ (f@EdgeDelete[g, #] && f@EdgeContract[g, #] & /@ EdgeList@g)

และนี่คือฟังก์ชั่นที่ไม่มีชื่อซึ่งจะแปลงอินพุตเป็นกราฟและเรียกใช้fสำหรับแต่ละองค์ประกอบที่เชื่อมต่อ:

And @@ (
  f @ Subgraph[g, #] & /@ ConnectedComponents[
    g=Graph[# <-> #2 & @@@ #]
  ]
)&

ฉันสามารถบันทึกสองสามไบต์โดยการเปลี่ยนเงื่อนไขการเลิกจากEdgeCount@g<9เป็นg==Graph@{}แต่จะทำให้รันไทม์อย่างมีนัยสำคัญ จากนั้นกรณีทดสอบครั้งที่สองจะใช้เวลา 30 วินาทีและกรณีสุดท้ายยังไม่เสร็จ


คุณสามารถลองและลบฟังก์ชั่นที่มีชื่อโดยใช้#0ซึ่งอ้างถึงฟังก์ชั่นที่บริสุทธิ์ที่สุด
LegionMammal978

@ LegionMammal978 ฉันรู้ แต่มันก็ไม่ได้ช่วยอะไรเลยเพราะฉันต้องใช้วงเล็บและต้องกำหนด#ให้ตัวแปรgด้วยตนเอง
Martin Ender
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.