【发布时间】:2019-08-11 16:43:53
【问题描述】:
我正在编写一个代码来确定一个可着色的图表。我正在使用不可变地图来确定回溯时的顶点颜色。
在 flatMap 循环的第二次交互中,我的 Map 丢失了一个元素。我无法编写一个更简洁的示例来呈现相同的错误,那么这是我的整个代码:
import scala.collection.immutable
import scala.collection.mutable
class GraphUndirected[Vertex](vertices: Set[Vertex], edges: Set[(Vertex, Vertex)]) {
private val adjacencyList: Map[Vertex, Set[Vertex]] =
(
edges.flatMap{ case (a, b) => {Seq( (a, Set(b)), (b, Set(a)))}}
++ vertices.map((_, Set()))
)
.groupBy(_._1)
.mapValues(
_.map(_._2)
.reduce(_ ++ _)
.toSet
)
override def toString(): String = adjacencyList.toString
def kColorable[C](colors: Set[C]): Option[Map[Vertex, C]] = {
vertices.toSeq.view.flatMap( v => {
val colorsMap = immutable.Map[Vertex,C]()
kColorable[C](colors, v, colorsMap)
}).headOption
}
def kColorable[C](colors: Set[C], v: Vertex, colorMap: Map[Vertex, C]): Option[Map[Vertex, C]] = {
println(v, colorMap)
colors.toSeq.view.flatMap( c => {
if (kColorableIsSafe[C](c, v, colorMap)) {
val newColorMap = colorMap + (v -> c)
println("\tnewColorMap", newColorMap)
if (newColorMap.size == vertices.size) {
Some(newColorMap)
} else {
adjacencyList(v).toSeq.view.flatMap( u => {
println("\t\tnewColorMap", newColorMap)
if (newColorMap.contains(u)) {
None
} else {
kColorable[C](colors, u, newColorMap)
}
}).headOption
}
} else {
None
}
}).headOption
}
def kColorableIsSafe[C](c: C, v: Vertex, colorMap: Map[Vertex, C]): Boolean = {
adjacencyList(v).forall( u => {
(!colorMap.contains(u)) ||
(colorMap(u) != c)
})
}
}
val myGraph1 = new GraphUndirected[Int](
Set(1,2,3,4,5,6,7,8,9),
Set(
(1,2),
(3,2), (3,4),
(5,7), (5,9),
(6,4),
(8,2), (8,9)
)
)
println(myGraph1.kColorable[String](Set("BLACK", "WHITE")))
运行这段代码会产生:
(5,Map())
( newColorMap,Map(5 -> BLACK))
( newColorMap,Map(5 -> BLACK))
(7,Map(5 -> BLACK))
( newColorMap,Map(5 -> BLACK, 7 -> WHITE))
( newColorMap,Map(5 -> BLACK, 7 -> WHITE))
( newColorMap,Map(5 -> BLACK))
(9,Map(5 -> BLACK))
这对我来说没有意义。在第一次交互中,它打印newColorMap,Map(5 -> BLACK, 7 -> WHITE),但在第二次交互中,“7->WHITE”消失了newColorMap,Map(5 -> BLACK)。
newColorMap 不应该是不可变的,不改变它的值?
我的 Scala 版本:
$ scala -version
Scala code runner version 2.12.2 -- Copyright 2002-2017, LAMP/EPFL and Lightbend, Inc.
【问题讨论】:
-
小心
mapValues,因为每次从Map读取值时,都会调用您提供的函数。如果您要多次访问这些值,最好使用普通的map。
标签: scala immutability