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:
- 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
). - 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(_))
intrait ResolvedBO
), how can I initialize graph's reference (val uni: Universe
) intrait ResolvedBO
? - At all, what's the best way to work with graph-like structures in Scala?
thank you
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.