我的图面是平面吗?


29

您的任务是确定图形是否为平面。

如果图形可以嵌入到平面中,则该图形是平面的;换句话说,如果可以绘制该图形而没有任何交叉边缘。

输入:您将获得以下格式的无向图:

  • 边缘列表,例如 [(0, 1), (0, 2), (0, 3)]

  • 邻接图,例如 {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,命令行参数和函数参数。

输出:您应该为所有平面图返回一个特定的输出,并为所有非平面图返回一个不同的特定输出。

输出的标准选择,包括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)]

非平面:

[(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 2015年

一个具有一个平面和一个非平面连接组件的非连接图的测试用例会很好。
彼得·泰勒

@PeterTaylor当然,我要添加一个。
isaacg

5
@RenaeLider抱歉,但我不明白。这个问题与浮点数无关,实际上它甚至不使用数字,而只是使用标签。
isaacg 2015年

Answers:


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 5K 3,3作为未成年人时,它才是平面的。

在这里,K 5是具有5个顶点的完整图,而K 3,3是在每个组中具有3个顶点的完整二部图。如果可以通过一系列边缘删除和边缘收缩从B获得图A,则图A是图B次要元素。

因此,此代码仅检查图是否与K 5K 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<9g==Graph@{},但将显著炸毁运行。然后,第二个测试用例需要30秒,而最后一个尚未完成。


您可以尝试删除命名的函数#0,该函数引用最里面的纯函数。
LegionMammal978

我知道@ LegionMammal978,但是它并没有真正保存任何内容,因为那时我需要括号,并且还需要手动分配#给变量g
Martin Ender 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.