-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#2] Merge branch 'issue-2' into develop
- Loading branch information
Showing
9 changed files
with
664 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
...cala/br/ufc/insightlab/linkedgraphast/query/MinimalPaths/MinimalFinder/MinimalPaths.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package br.ufc.insightlab.linkedgraphast.query.MinimalPaths.MinimalFinder | ||
|
||
import br.ufc.insightlab.graphast.model.{Edge, Graph} | ||
import br.ufc.insightlab.linkedgraphast.query.MinimalPaths.utils.Path | ||
/** | ||
* trait to make the method extensible | ||
* | ||
* | ||
* @author Joao Castelo Branco | ||
* @version 0.1 | ||
*/ | ||
|
||
trait MinimalPaths { | ||
def apply(G: Graph , source: Long , target: Long) :List[Path] | ||
} |
216 changes: 216 additions & 0 deletions
216
...r/ufc/insightlab/linkedgraphast/query/MinimalPaths/MinimalFinder/MinimalPathsFinder.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
package br.ufc.insightlab.linkedgraphast.query.MinimalPaths.MinimalFinder | ||
|
||
import scala.collection.JavaConverters._ | ||
import br.ufc.insightlab.graphast.model.{Edge, Graph, Node} | ||
import br.ufc.insightlab.graphast.query.shortestpath.DijkstraStrategy | ||
import br.ufc.insightlab.linkedgraphast.model.link.{Attribute, Relation} | ||
import br.ufc.insightlab.linkedgraphast.parser.NTripleParser | ||
import br.ufc.insightlab.linkedgraphast.query.MinimalPaths.utils | ||
import br.ufc.insightlab.linkedgraphast.query.MinimalPaths.utils.{Path, PathEdge, PathMultipleEdge, PathSingleEdge} | ||
import scala.collection.mutable.Queue | ||
|
||
|
||
/** | ||
* A singleton class to calculate multiple minimum paths | ||
* | ||
* @see Graph | ||
* @see Node | ||
* @see Edge | ||
* @author Joao Castelo Branco | ||
* @version 0.2 | ||
*/ | ||
|
||
object MinimalPathsFinder extends MinimalPaths { | ||
|
||
/** | ||
* Function to mount the path represented by nodes | ||
* | ||
* @param source the node that starts the path | ||
* @param target the node ending the path | ||
* @param parents the dictionary containing minimal parents of nodes | ||
* @return a list of lists for each variation of paths, it is represented by nodes | ||
*/ | ||
|
||
private def buildPathNodes(source: Long, target: Long, parents: Map[Long, Set[Long]]): List[List[Long]] = { | ||
|
||
//base case, when the source was hit, the path ended | ||
if (source == target) { | ||
|
||
List(List(source)) | ||
|
||
} else { | ||
|
||
//the recursion consists of assembling the list to each branch of the path | ||
parents(target).toList.flatMap { dad => | ||
|
||
val paths: List[List[Long]] = buildPathNodes(source, dad, parents) | ||
|
||
paths.map((path: List[Long]) => path :+ target) | ||
|
||
} | ||
} | ||
} | ||
|
||
/** | ||
* Function to mount the edge path from the list of nodes that make up the minimum path | ||
* | ||
* @param pathNodes a list of lists for each variation of paths, it is represented by nodes | ||
* @param G the graph where the query was made | ||
* @see Graph | ||
* @see Edge | ||
* @return a list of lists for each variation of paths, it is represented by edges | ||
*/ | ||
|
||
private def buildPathEdges(pathNodes : List[List[Long]] , G : Graph) : List[Path] = { | ||
|
||
var pathEdges : List[Path]= List() | ||
|
||
for(path <- pathNodes){ | ||
|
||
var track : List[PathEdge] = List() | ||
|
||
for(node <- 0 to path.length-2){ | ||
|
||
val fromNode : Int = node + 1 | ||
|
||
//collection of all edges that leave the node and is destined fromNode | ||
var candidates: List[Edge] = List() | ||
|
||
var candidate : List[Edge] = G.getOutEdges(path(node)).asScala.toList | ||
|
||
for(i <- candidate){ | ||
|
||
if(i.getToNodeId == path(fromNode) || i.getFromNodeId == path(fromNode) ){ | ||
|
||
candidates = candidates ::: List(i) | ||
|
||
} | ||
} | ||
|
||
//selecting the lesser edges between them | ||
val widget :Double = candidates.minBy(_.getWeight).getWeight | ||
candidates = candidates.filter(_.getWeight == widget) | ||
|
||
//if the resulting list size is greater than 1, this excerpt presents redundancy and must be represented by PathMultipleEdge | ||
if(candidates.length >1){ | ||
|
||
track = track ::: List( PathMultipleEdge(candidates) ) | ||
|
||
}else{ | ||
|
||
//otherwise, it must be represented by PathSingleEdge | ||
track = track ::: List( PathSingleEdge(candidates.head)) | ||
|
||
} | ||
} | ||
|
||
pathEdges = pathEdges :+ utils.Path( track ) | ||
} | ||
|
||
pathEdges | ||
} | ||
|
||
/** | ||
* Breadth-first search modified to find all the minimal paths between source and target | ||
* | ||
* @param G the graph where the query will be made | ||
* @param source the node that starts the path | ||
* @param target the node ending the path | ||
* @see Graph | ||
* @see Edge | ||
* @see Node | ||
* @return a list of lists for each variation of paths, it is represented by edges | ||
*/ | ||
|
||
def apply(G: Graph, source: Long, target: Long): List[Path] = { | ||
|
||
|
||
var parents: Map[Long, Set[Long]] = Map() | ||
val nodes: Iterable[Node] = G.getNodes.asScala | ||
var colors: Map[Long, Boolean] = Map() | ||
var distances: Map[Long, Double] = Map() | ||
|
||
|
||
//initializing the search variables | ||
for (u <- nodes) { | ||
colors += (u.getId -> false) | ||
distances += (u.getId -> Double.PositiveInfinity) | ||
parents += (u.getId -> Set()) | ||
} | ||
|
||
colors += source -> true | ||
distances += (source -> 0) | ||
|
||
val NextNodesId: Queue[Long] = Queue(source) | ||
|
||
|
||
while (NextNodesId.nonEmpty) { | ||
|
||
val dad: Long = NextNodesId.dequeue | ||
|
||
|
||
//iteration over the edges that leave the node | ||
for { | ||
|
||
edge <- G.getOutEdges(dad).asScala | ||
|
||
}{ | ||
|
||
var fromNodeId: Long = 0l | ||
|
||
if(edge.isBidirectional){ | ||
|
||
if(edge.getToNodeId == dad){ | ||
|
||
fromNodeId = edge.getFromNodeId | ||
|
||
}else{ | ||
|
||
fromNodeId = edge.getToNodeId | ||
|
||
} | ||
} | ||
|
||
//iteration over the edges that leave the node | ||
if (!colors(fromNodeId)) { | ||
|
||
val widget: Double = distances(dad) + edge.getWeight | ||
|
||
//if the weight found is less than equal to the lowest already listed | ||
if (widget <= distances(fromNodeId)) { | ||
|
||
//security check to prevent the target being a part of some way minimum path | ||
if (fromNodeId != target) { | ||
|
||
NextNodesId.enqueue(fromNodeId) | ||
|
||
} | ||
|
||
//if the distance found was equal to less cataloged, one should register the minimal father of this node | ||
if(distances(fromNodeId) == widget){ | ||
|
||
parents += fromNodeId -> (parents(fromNodeId)+dad) | ||
|
||
//otherwise, we have a better minimal parent and the others should be discarded | ||
}else{ | ||
|
||
parents += fromNodeId -> Set(dad) | ||
|
||
distances += fromNodeId -> widget | ||
} | ||
} | ||
} | ||
} | ||
|
||
//marking the node as visited | ||
colors += dad -> true | ||
|
||
} | ||
|
||
//mounting the edge path | ||
buildPathEdges(buildPathNodes(source, target, parents) , G) | ||
|
||
} | ||
|
||
} | ||
|
20 changes: 20 additions & 0 deletions
20
src/main/scala/br/ufc/insightlab/linkedgraphast/query/MinimalPaths/utils/Path.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package br.ufc.insightlab.linkedgraphast.query.MinimalPaths.utils | ||
|
||
/** | ||
* A class to assist the representation of paths in the graph | ||
* | ||
* | ||
* @author Joao Castelo Branco | ||
* @version 0.2 | ||
*/ | ||
|
||
case class Path(edges: List[PathEdge]) { | ||
override def toString: String = { | ||
edges.mkString("("," -> ",")") | ||
} | ||
|
||
def cost: Double = edges.foldLeft(0.0){ | ||
case (c: Double, PathSingleEdge(e)) => c + e.getWeight | ||
case (c: Double, PathMultipleEdge(es)) => c + es.head.getWeight | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/scala/br/ufc/insightlab/linkedgraphast/query/MinimalPaths/utils/PathEdge.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package br.ufc.insightlab.linkedgraphast.query.MinimalPaths.utils | ||
|
||
/** | ||
* auxiliary class to mark passages with or without redundancy | ||
* | ||
* | ||
* @author Joao Castelo Branco | ||
* @version 0.1 | ||
*/ | ||
|
||
trait PathEdge {} |
19 changes: 19 additions & 0 deletions
19
...in/scala/br/ufc/insightlab/linkedgraphast/query/MinimalPaths/utils/PathMultipleEdge.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package br.ufc.insightlab.linkedgraphast.query.MinimalPaths.utils | ||
|
||
import br.ufc.insightlab.graphast.model.Edge | ||
|
||
/** | ||
*Class to mark a redundancy | ||
*There is a collection of the edges that are part of this redundancy | ||
* | ||
* @author Joao Castelo Branco | ||
* @see Edge | ||
* @version 0.1 | ||
*/ | ||
|
||
case class PathMultipleEdge(edges: List[Edge]) extends PathEdge { | ||
|
||
|
||
override def toString: String = edges.mkString("{ "," , "," }") | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
...main/scala/br/ufc/insightlab/linkedgraphast/query/MinimalPaths/utils/PathSingleEdge.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package br.ufc.insightlab.linkedgraphast.query.MinimalPaths.utils | ||
|
||
import br.ufc.insightlab.graphast.model.Edge | ||
|
||
/** | ||
*Auxiliary class to demarcate the section without redundancy | ||
* | ||
* @author Joao Castelo Branco | ||
* @see Edge | ||
* @version 0.1 | ||
*/ | ||
|
||
case class PathSingleEdge(edge: Edge) extends PathEdge { | ||
|
||
override def toString: String = edge.toString | ||
|
||
|
||
} |
Oops, something went wrong.