图5着色


14

老实说,我不敢相信这还没有被问到,但这是

背景

给定一个简单的无向平面(该图可以在没有相交的平面上绘制)图,这是一个证明定理,即该图是4色的,这是我们稍后将要探讨的术语。但是,对图形进行5色绘制要容易得多,这就是我们今天要重点解决的问题。

图的有效k着色是对具有以下属性的图的节点分配“颜色”

  1. 如果两个节点通过一条边连接,则这些节点将使用不同的颜色进行着色。
  2. 在整个图形中,最多有5种颜色。

鉴于此,我将向您展示一个非常基本的算法,以对任何简单的无向平面图进行5种颜色着色。该算法需要以下定义

可达性:如果节点1可从节点2到达,则意味着存在一系列节点,每个节点通过一条边连接到下一个节点,因此第一个节点是节点2,最后一个节点是节点1。请注意,由于无向图是对称的,如果节点1可从节点2到达,则节点2可从节点1到达。

子图:给定节点集的图的子图N是其中子图的节点全部在N中的图,并且当且仅当两个节点都通过边连接时,原始图的边才在子图中在北

假设Color(N)是为带有5种颜色的N个节点的平面图着色的函数。我们在下面定义函数

  1. 查找连接的节点数最少的节点。该节点最多连接5个节点。
  2. 从图中删除该节点。
  3. 在此新图形上调用Color(N-1)对其进行着色。
  4. 将已删除的节点添加回图。
  5. 如果可能,请为添加的节点上色,使其所连接的节点都没有该颜色。
  6. 如果不可能,则添加节点的所有5个相邻节点都有5种不同的颜色,因此我们必须尝试以下过程。
  7. 编号添加节点n1 ... n5周围的节点
  8. 考虑原始图中所有节点的子图,其颜色与n1或n3颜色相同。
  9. 如果在此子图中,无法从n1到达n3,则在从n1(包括n1)可到达的节点集中,将所有出现的n1颜色替换为n3,反之亦然。现在为添加的节点n1的原始颜色上色。
  10. 如果在此新图中从n1可以到达n3,请在节点n2和n4而不是n1和n3上从步骤9开始执行过程。

挑战

给定边列表的输入(代表图形),通过为每个节点分配一个值来为图形着色。

输入:图形中边的列表(即[('a','b'),('b','c')...]

请注意,输入边列表将使得如果(a,b)在列表中,而(b,a)不在列表中。

输出:包含对值,其中每对的第一个元素是一个节点的一个目标,并且所述第二颜色,即[('a',1),('b',2)...]{'a':1,'b':2,...}

您可以使用任何东西来代表颜色,从数字到字符,再到其他。

输入和输出非常灵活,只要它很清楚输入和输出是什么即可。

规则

  • 这是一个挑战
  • 您不必使用我上面描述的算法。它只是那里供参考。
  • 对于任何图形,通常有许多有效的着色方法。只要算法产生的着色有效,就可以接受。
  • 请记住,图表必须是5色。

测试用例

使用以下代码测试着色结果的有效性。由于每个图形有许多有效的图形着色,因此该算法仅检查着色的有效性。请参阅文档字符串以了解如何使用代码。

一些随机(相当愚蠢)的测试用例

测试案例2:Krakckhardt风筝图 [(0, 1), (0, 2), (0, 3), (0, 5), (1, 3), (1, 4), (1, 6), (2, 3), (2, 5), (3, 4), (3, 5), (3, 6), (4, 6), (5, 6), (5, 7), (6, 7), (7, 8), (8, 9)]

有效输出: {0: 4, 1: 3, 2: 3, 3: 2, 4: 4, 5: 1, 6: 0, 7: 4, 8: 3, 9: 4}

注意:这些测试用例太小,无法测试着色算法更细微的行为,因此构造自己的图形可能是对工作有效性的良好测试。

注意2:我将添加另一段代码,以很快显示您的着色解决方案。

注3:我没有预见到已经提出的随机着色算法,这对PPCG来说真是太酷了!但是,如果有人可以使用一种更具确定性的算法,那也将非常酷。


3
Petersen和Chvatal图不是平面图吗?
Kroppeb

1
@NicHartley众所周知,基于邻接矩阵的操作可以有效地使图形着色。我会在找到论文后附上论文。
Don Thousand

1
我认为您最好将解决方案限制为多项式时间,或者要求大型测试用例成功运行,以迫使解决方案使用您似乎想像的图形算法。
xnor

2
@xnor我似乎已经吸取了教训。没关系!开箱即用的思维应该得到奖励,而不是受到惩罚。
Don Thousand

1
是的,我知道,但是必须设计一种四色问题,以使人们不能只是回答这个问题,而是更改54,然后重新提交。
彼得·泰勒

Answers:


6

Python 2,96个字节

i=0
g=input()
while 1:i+=1;c={k:i/4**k%4for k in sum(g,())};all(c[s]^c[t]for s,t in g)>0<exit(c)

在线尝试!

G一世CCC

输入是平面的,因此总是可以找到4色。

(因此:这在某种意义上找到了词典上最早的着色,而且效率很低。)

ķ一世4ķ4ķ一世


尽力而为,但是我相信您缺少一个组件。如果一个节点被5种不同的颜色包围,情况又如何呢?
Don Thousand

我将尝试建立一个测试用例来打破这一点
Don Thousand

假设图中的一个给定节点被其他5个节点包围,您已经为这5个颜色上了色。
Don Thousand

1
我的代码随机生成图形着色并检查它们,直到生成正确的图形着色,然后在退出时打印。在您描述的情况下,它将重新开始,并希望不要为这5个节点着色所有5种可用颜色。
林恩

2
现在,它按照字典顺序检查所有着色:),因此它是确定性的,且为O(5 ^ n),但对于大多数输入而言,速度要慢得多。
林恩

3

JavaScript(ES7),80 76 74字节

@Neil节省了2个字节

Lynn相同的方法。解决4种颜色,从03编号。

a=>{for(x=0;a.some(a=>a.map(n=>z=c[n]=x>>n*2&3)[0]==z,c={});x++);return c}

在线尝试!


如果允许使用4色,那为什么不x>>n+n&3呢?
尼尔,

@尼尔,是的,谢谢。我对5色的解释分散了注意力,忘记了输入在4中肯定可以解决
。– Arnauld

3

Brachylog,38个字节

cd{∧4>ℕ}ᶻ.g;?z{tT&h⊇ĊzZhpT∧Zt≠}ᵐ∧.tᵐ≜∧

在线尝试!

说明

Example input: [["a","b"],["c","b"]]

cd                                       Concatenate and remove duplicates: ["a","b","c"]
  {∧4>ℕ}ᶻ.                               The output is this list zipped zith integers that
                                           are in [0..4]: [["a",I],["b",J],["c",K]]
         .g;?z                           Zip the output with the input:
                                           [[[["a",I],["b",J],["c",K]],["a","b"]],[["a",I],["b",J],["c",K]],["c","b"]]
              {               }ᵐ∧        Map for each element
               tT                        Call T the couple of nodes denoting an edge
                 &h⊇Ċ                    Take a subset of 2 elements in the head
                     zZ                  Zip and call it Z
                      ZhpT               The nodes in Z are T up to a permutation
                          ∧Zt≠           The integers in Z are all different color
                                 .tᵐ≜∧   Label the integers (i.e. colors) in the output so that
                                           it matches the set constraints

1

Python 2,211字节

def f(g):
 g={k:[(a,b)[a==k]for a,b in g if k in(a,b)]for k in sum(g,())};c={k:0 for k in g}
 for a,b in sorted(g.iteritems(),key=lambda a:len(a[1])):c={k:(c[k],c[k]+1)[c[a]==c[k]and k in b]for k in c}
 return c

在线尝试!

确定性!在更复杂的测试用例上可能会失败,但是我实在太疲倦了,无法找到失败的图形。欢迎更多测试用例和/或批评!


1

干净,139字节

import StdEnv,Data.List
$l#(a,b)=unzip l
#e=nub(a++b)
=hd[zip2 e c\\c<- ?e|all(\(a,b)=c!!a<>c!!b)l]
?[h:t]=[[n:m]\\n<-[0..4],m<- ?t]
?e=[e]

在线尝试!

生成所有颜色并返回第一个有效的颜色。


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.