Stefano Sandonà Stefano Sandonà - 25 days ago 6
Scala Question

How to use the GraphStream library for Scala

I tried to use the GraphStream library to find the shortest path between 2 nodes in a graph. At the end I'm able to print the edges of the path (

it.foreach(println)
) but I can't access one element at the time. This is the code:

import org.graphstream.algorithm.Dijkstra;
import org.graphstream.graph.Edge;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.graph.Path;
import org.graphstream.graph.implementations.SingleGraph;
import scala.collection.JavaConverters._


object MainApp extends App{


def exampleGraph():Graph={
val g:Graph = new SingleGraph("example");
g.addNode("N1_S1");
g.addNode("N1_J1");
g.addNode("N1_H1");
g.addNode("N1_J2");
g.addNode("N1_H2");
g.addNode("N1_W1");
var e:Edge=g.addEdge("N1_S1-N1_J1", "N1_S1", "N1_J1")
e.addAttribute("length",Int.box(6))
e=g.addEdge("N1_J1-N1_H1", "N1_J1", "N1_H1")
e.addAttribute("length",Int.box(8))
e=g.addEdge("N1_J1-N1_J2", "N1_J1", "N1_J2")
e.addAttribute("length",Int.box(8))
e=g.addEdge("N1_J2-N1_H2", "N1_J2", "N1_H2")
e.addAttribute("length",Int.box(4))
e=g.addEdge("N1_J2-N1_W1", "N1_J2", "N1_W1")
e.addAttribute("length",Int.box(10))

return g
}

val g:Graph = exampleGraph();
g.display(false);

val dijkstra:Dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "length");

dijkstra.init(g);

dijkstra.setSource(g.getNode("N1_S1"));

println(dijkstra.getPath(g.getNode("N1_W1")));
val myPath:Path=dijkstra.getPath(g.getNode("N1_W1"))
val it=(myPath.getEachEdge).asScala
println("edges")
it.foreach(println)
}


The problem is that the prototype of
getEachEdge
is
getEachEdge[T <: Edge](): Iterable[_ <: T]
and
asScala
returns a
Iterable[_ <: Nothing]
. So the final question is "How can I access each element of the shortest path?"

Answer

I'm not sure why, but you have to explicitly annotate the type.

myPath.getEachEdge[Edge].asScala

You could get runtime cast exceptions if you specify the wrong subtype.

The following throws a ClassCastException:

@ trait OtherEdge extends Edge
defined trait OtherEdge
@ myPath.getEachEdge[OtherEdge].asScala.head
java.lang.ClassCastException: org.graphstream.graph.implementations.AbstractEdge cannot be cast to $sess.cmd17$OtherEdge
  $sess.cmd18$.<init>(cmd18.sc:1)
  $sess.cmd18$.<clinit>(cmd18.sc:-1)