我收集了下面显示的列表。
List(4, 0, 1, 2, 4)
List(4, 0, 1, 3, 4)
List(4, 0, 2, 3, 4)
List(4, 3, 2, 3, 4)
List(4, 3, 4, 3, 4)
List(0, 1, 2, 4, 0)
List(0, 1, 3, 4, 0)
List(0, 2, 3, 4, 0)
List(1, 2, 4, 0, 1)
List(1, 3, 4, 0, 1)
List(3, 4, 0, 1, 3)
List(3, 4, 0, 2, 3)
List(3, 2, 3, 2, 3)
List(3, 4, 3, 2, 3)
List(3, 2, 3, 4, 3)
List(3, 4, 3, 4, 3)
List(2, 3, 4, 0, 2)
List(2, 4, 0, 1, 2)
List(2, 3, 2, 3, 2)
List(2, 3, 4, 3, 2)
这些列表是有向图中循环长度为4的各个循环。我想从给定列表中过滤出唯一路径的数量,这些列表之间没有任何更小的路径。例如-List(4,0,1,2,4)和List(0,1,2,4,0)形成相同的循环。另一个示例-List(2,3,2,3,2)仅对2和3进行迭代,并且不形成循环长度4。
从这个集合中我们可以说List(0,1,2,4,0)List(0,1,3,4,0)List(0,2,3,4,0)是唯一路径总数为3 List(0,1,2,4,4,0)和List(4,0,1,2,4)是同一周期,因此我们选择其中之一。
我尝试使用过滤器,但找不到任何逻辑来执行此操作。
答案 0 :(得分:3)
以下应该有效:
val input = List(List(4, 0, 1, 2, 4),List(4, 0, 1, 3, 4) ,List(4, 0, 2, 3, 4) ,List(4, 3, 2, 3, 4) ,List(4, 3, 4, 3, 4) ,
List(0, 1, 2, 4, 0) ,List(0, 1, 3, 4, 0) ,List(0, 2, 3, 4, 0) ,List(1, 2, 4, 0, 1) ,List(1, 3, 4, 0, 1) ,List(3, 4, 0, 1, 3) ,
List(3, 4, 0, 2, 3) ,List(3, 2, 3, 2, 3) ,List(3, 4, 3, 2, 3) ,List(3, 2, 3, 4, 3) ,List(3, 4, 3, 4, 3) ,
List(2, 3, 4, 0, 2) ,List(2, 4, 0, 1, 2) ,List(2, 3, 2, 3, 2), List(2, 3, 4, 3, 2))
var uniquePaths: mutable.Set[List[Int]] = collection.mutable.Set[List[Int]]()
var indexes: ListBuffer[Int] = mutable.ListBuffer[Int]()
input.zipWithIndex.foreach{x =>
val (list, index) = (x._1, x._2)
if(list.head==list.last) {
val list1 = rotateArray(list.tail)
if (list1.toSet.size == 4) {
if(!uniquePaths.contains(list1))
indexes.append(index)
uniquePaths.add(list1)
}
}
}
indexes foreach{x => println(input(x))}
def rotateArray(xs: List[Int]): List[Int] =
xs.splitAt(xs.indexOf(xs.min)) match {case (x, y) => List(y, x).flatten}
答案 1 :(得分:1)
...手绘红色循环进行救援。
在相同的四个顶点上有两个不同循环 ,这表明排序不足:
该草图假定所有点都是完全连接的图的顶点(省略了边),并且假定循环[0, 1, 2, 3, 0]
和[0, 2, 1, 3, 0]
不相同,尽管事实是如果对集合进行排序,则在两种情况下都将获得[0, 1, 2, 3]
。
以下是替代方法:
这是实现的样子:
def canonicalize(cycle: List[Int]) = {
val t = cycle.tail
val (b, a) = t.splitAt(t.zipWithIndex.minBy(_._1)._2)
val ab = (a ++ b)
ab :+ (ab.head)
}
val cycles = List(
List(4, 0, 1, 2, 4),
List(4, 0, 1, 3, 4),
List(4, 0, 2, 3, 4),
List(4, 3, 2, 3, 4),
List(4, 3, 4, 3, 4),
List(0, 1, 2, 4, 0),
List(0, 1, 3, 4, 0),
List(0, 2, 3, 4, 0),
List(1, 2, 4, 0, 1),
List(1, 3, 4, 0, 1),
List(3, 4, 0, 1, 3),
List(3, 4, 0, 2, 3),
List(3, 2, 3, 2, 3),
List(3, 4, 3, 2, 3),
List(3, 2, 3, 4, 3),
List(3, 4, 3, 4, 3),
List(2, 3, 4, 0, 2),
List(2, 4, 0, 1, 2),
List(2, 3, 2, 3, 2),
List(2, 3, 4, 3, 2)
)
val unique = cycles.filter(_.toSet.size == 4).map(canonicalize).toSet
unique foreach println
输出:
List(0, 1, 2, 4, 0)
List(0, 1, 3, 4, 0)
List(0, 2, 3, 4, 0)
canonicalize
的逐行示例:
tail
删除重复的顶点:[2, 1, 0, 4, 2] -> [1, 0, 4, 2]
splitAt
找到最小顶点并切割列表:[1, 0, 4, 2] -> ([1], [0, 4, 2])
a ++ b
重建轮换列表:[0, 4, 2, 1]
:+
将最小顶点附加到末尾:[0, 4, 2, 1, 0]
答案 2 :(得分:0)