【问题标题】:scala: adjacency matrix graphsscala:邻接矩阵图
【发布时间】:2015-05-17 15:10:42
【问题描述】:

我正在尝试了解如何在 Scala 中构建图表,直到现在我才知道:

import scala.collection.mutable.ArrayBuffer

object TestGraph {

  class Graph(vertices: Array[String], edges: ArrayBuffer[(Int, Int)]) {
    def size: Int = vertices.length
    def vertex(index: Int): String = vertices(index)
    def index(vertex: String): Int = vertices.indexOf(vertex)
    def printEdges(): Unit = { 
      for(v <- vertices) {
        print("vertex " + index(v) + ": ")
        for(e <- edges if(e._1 == index(v))) {
            print(e + " ")
        }
        println()
      }
    }
    def createAdjacencyMatrix() = {
      val adjacencyMatrix = Array.ofDim[Int](size, size)

    }
    def printAdjacencyMatrix(): Unit = {

    }
  }

   def main(args: Array[String]) {
    def vertices: Array[String] = Array("Seattle", "San Francisco", "Los Angeles",
        "Denver", "Kansas City", "Chicago", "Boston", "New York", 
        "Atlanta", "Miami", "Dallas", "Houston")

    def edges: ArrayBuffer[(Int, Int)] = ArrayBuffer(
        (0, 1), (0, 3), (0, 5), 
        (1, 0), (1, 2), (1, 3), 
        (2, 1), (2, 3), (2, 4), (2, 10), 
        (3, 0), (3, 1), (3, 2), (3, 4), (3, 5), 
        (4, 2), (4, 3), (4, 5), (4, 7), (4, 8), (4, 10), 
        (5, 0), (5, 3), (5, 4), (5, 6), (5, 7), 
        (6, 5), (6, 7), 
        (7, 4), (7, 5), (7, 6), (7, 8), 
        (8, 4), (8, 7), (8, 9), (8, 10), (8, 11), 
        (9, 8), (9, 11), 
        (10, 2), (10, 4), (10, 8), (10, 11), 
        (11, 8), (11, 9), (11, 10)
        )
        val graph = new Graph(vertices, edges)
        println("number of vertices in graph: " + graph.size)
        println("the vertex with index 1 is: " + graph.vertex(1))
        println("the index for Miami is: " + graph.index("Miami"))
        println("the edges for graph: "); graph.printEdges
        println("adjacency matric for graph: ");    
   }
}

我想创建一个邻接矩阵,然后为给定的图形打印它。这是填充二维数组的更好方法吗 - 就像我对 printEdges() 所做的那样?

【问题讨论】:

    标签: arrays scala graph adjacency-matrix


    【解决方案1】:

    我允许自己稍微重构一下您的代码:

    class Graph(val vertex: IndexedSeq[String], edges: Seq[(Int, Int)]) {
        def size: Int = vertex.length
        val index: Map[String, Int] = vertex.zipWithIndex.toMap
        val adjacent = edges groupBy (_._1) mapValues (_ map (_._2))
        def adjacencyMatrix = adjacent mapValues (_.toSet) mapValues (0 to size map _)
        def printEdges: String = {
          for(idx <- 0 until size)
            yield f"vertex $idx: ${adjacent(idx) mkString " "}"
        } mkString "\n"
        def printAdjacencyList: String = adjacent mapValues (_ mkString ", ") mkString "\n"
        def printAdjacencyMatrix: String = adjacencyMatrix mapValues(_ mkString ", ") mkString "\n"
      }
    

    def main:

    println("number of vertices in graph: " + graph.size)
    println("the vertex with index 1 is: " + graph.vertex(1))
    println("the index for Miami is: " + graph.index("Miami"))
    println("the edges for graph: ")
    println(graph.printEdges)
    println("adjacency list for graph: ")
    println(graph.printAdjacencyList)
    println("adjacency matrix for graph: ")
    println(graph.printAdjacencyMatrix)
    

    【讨论】:

    • okii,你只是推动我阅读和使用更多的 Scala 集合:D 很好,thnxx 很多。我不明白为什么这些值在获得groupBy 这里val adjacent = edges groupBy (_._1) mapValues (_ map (_._2)) 时是无序的?
    • @Valerin 它们包含在HashMap 中——在groupBy 内部adjacent 定义中使用的默认实现。所以他们奇怪地根据哈希排序
    • 如果我想动态添加节点并扩展图形效率不高(可能),而 IndexedSeq 是不可变的。我应该使用List 而不是IndexedSeqArrays
    • @Valerin immutable 并不意味着inefficient 您可以通过:+ 创建新的IndexedSeq 添加新节点,并通过+: 在新的边缘添加新的Seq。如果我们谈论默认实现,即对应的VectorList,这些操作将非常有效。
    • @Valerin 这正是我所说的性能。看看docs.scala-lang.org/overviews/collections/…。当您附加到Vector 时,不会复制整个集合,由于树状结构,大多数部分保持不变。当您添加到 List 之前,不会复制任何内容,只会创建单个 Cons
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多