Immutable graph-like structures in Scala

时间秒杀一切 提交于 2019-12-22 09:56:10

问题


Good day! I'm trying to construct immutable graph in Scala 2.9.1. It's given to me with Seq[BO], where BO can represent one node in graph, and BO.attr_bo: Seq[String] who represents edges to other nodes, given by string name. And I need to construct "resolved" graph, represented by BO with ResolvedBO You can see possible realization here:

trait BO {
  def name: String
  def attr_bo: Seq[String]
}

trait ResolvedBO {
  x: BO =>
  val uni: Universe
  lazy val r_attr_bo: Seq[BO with ResolvedBO] = attr_bo map (uni.m_list_r(_))
}

class S_BO(val name: String, val attr_bo: Seq[String]) extends BO

class Universe(list: Seq[BO]) {
  val m_list: Map[String, BO] = list.map(x => (x.name, x))(collection.breakOut)
  val m_list_r: Map[String, BO with ResolvedBO] = ...???
}

val x: Uni = new Uni(Seq(new S_BO("a", Seq("b", "c")), new S_BO("b", Seq("a", "c")), new S_BO("c", Seq("a", "b"))))

where class Universe represents graph at all (it can also be disconnected one) Also, if it's important, I can restrict graph to be without cycles.

So my main questions:

  1. Since nodes (trait BO) can be quite complex objects and can be realized with several subtypes, what is the best way to implement "resolved nodes" - i.e. nodes with direct links to other nodes? (BO with ResolvedBO).
  2. If resolving nodes by themselves is the best way (lazy val r_attr_bo: Seq[BO with ResolvedBO] = attr_bo map (uni.m_list_r(_)) in trait ResolvedBO), how can I initialize graph's reference (val uni: Universe) in trait ResolvedBO?
  3. At all, what's the best way to work with graph-like structures in Scala?

thank you


回答1:


For point 3, it depends on your definition of what "best" means. I would recommend not implementing a lib yourself and use scala-graph which seems to be suited to your needs (immutable graphs).

If you really insist to write your own graph library (it's a good way to improve your knowledge in Scala), try avoiding a graph of objects (using references to represent the connections). Rather go for a Graph class with generic operations like: myGraph.neighborsOf( myVertex ).

A nice representation (easy to implement but slow for huge graphs) is to represent the graph as a set of edges. To add a new edge, you just add a new object to the set. To get the set of all vertices, you just flatten the set of edges. To get the neighbors of a vertex, you iterate on every edges, etc.

A faster solution is to use a more complex representation, like a Map where the keys are vertices and the values the set of neighbors.

Have a look at scala-graph source code for inspiration.



来源:https://stackoverflow.com/questions/9891522/immutable-graph-like-structures-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!