
org.openmole.spatialsampling.Network.scala Maven / Gradle / Ivy
The newest version!
package org.openmole.spatialsampling
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.util.Random
case class Network(
nodes: Set[Network.Node],
links: Set[Network.Link],
outLinkMap: Map[Network.Node,Vector[Network.Link]],
inLinkMap: Map[Network.Node,Vector[Network.Link]],
directed: Boolean = false,
cachedShortestPaths: Option[Map[(Network.Node,Network.Node),(Seq[Network.Node],Seq[Network.Link],Double)]] = None
){
def percolate(percolationProba: Double,linkFilter: Network.Link=>Boolean= {l =>l.weight==0.0})(implicit rng: Random): Network = {
val emptyLinks = links.toSeq.filter(linkFilter)
val fullLinks = links.toSeq.filter{l => !linkFilter(l)}
val percolated = emptyLinks.map{l => if(rng.nextDouble() (l.e1,l)).groupBy(_._1).map(e => (e._1,e._2.toVector.map(_._2)))
val in = links.map(l => (l.e2,l)).groupBy(_._1).map(e => (e._1,e._2.toVector.map(_._2)))
Network(nodes, links, out, in)
}
def networkToGrid(network: Network,footPrintResolution: Double = 1.0,linkwidth: Double = 1.0): RasterLayerData[Double] = {
val xmin = network.nodes.map{_.x}.min;val xmax = network.nodes.map{_.x}.max
val ymin = network.nodes.map{_.y}.min;val ymax = network.nodes.map{_.y}.max
def xcor(x: Double): Int = math.max(xmin.toDouble,math.min(xmax.toDouble,math.round(x))).toInt
def ycor(y: Double): Int = math.max(ymin.toDouble,math.min(ymax.toDouble,math.round(y))).toInt
val res: Array[Array[Double]] = (BigDecimal(xmin) to xmax by 1.0).toArray.map{ _ => (BigDecimal(ymin) to ymax by 1.0).toArray.map{ _ =>0.0}}
network.links.toSeq.filter{_.weight>0.0}.foreach{ l =>
val i1 = l.e1.x - xmin;val j1 = l.e1.y - ymin
val i2 = l.e2.x - xmin;val j2 = l.e2.y - ymin
val istep = i1 - i2 match {case xx if math.abs(xx) < 1e-10 => 0.0 ;case _ => math.cos(math.atan((j2 - j1)/(i2 - i1)))*footPrintResolution}
val jstep = j1 - j2 match {case xx if math.abs(xx) < 1e-10 => 0.0 ;case _ => math.sin(math.atan((j2 - j1)/(i2 - i1)))*footPrintResolution}
val nsteps = i1 - i2 match {case xx if math.abs(xx) < 1e-10 => (j2 - j1)/jstep;case _ => (i2 - i1)/istep}
var x = l.e1.x;var y = l.e1.y
(BigDecimal(0.0) to nsteps by 1.0).foreach{_ =>
for {
k1 <- - BigDecimal((linkwidth-1)/2) to (linkwidth-1)/2 by 1.0
k2 <- - BigDecimal((linkwidth-1)/2) to (linkwidth-1)/2 by 1.0
} yield {
res(xcor(x+k1.toDouble))(ycor(y+k2.toDouble)) = 1.0
}
x = x + istep;y = y+ jstep
}
}
res
}
def gridToNetwork(world: Array[Array[Double]]): Network = {
val links = new ArrayBuffer[Link]()
var nodeid = 0
for(i <- world.indices; j <- world.indices) {
if(world(i)(j)>0.0){
val currentnode = Node(nodeid,i,j);nodeid=nodeid+1
if(i-1>0){if(world(i-1)(j)>0.0){nodeid=nodeid+1;links.append(Link(currentnode,Node(nodeid,i-1,j)))}}
if(i+10.0){nodeid=nodeid+1;links.append(Link(currentnode,Node(nodeid,i+1,j)))}}
if(j-1>0){if(world(i)(j-1)>0.0){nodeid=nodeid+1;links.append(Link(currentnode,Node(nodeid,i,j-1)))}}
if(j+10.0){nodeid=nodeid+1;links.append(Link(currentnode,Node(nodeid,i,j+1)))}}
}
}
Network(links.map{_.e1}.toSet.union(links.map{_.e2}.toSet),links.toSet)
}
def connectedComponentsTraverse(network: Network): Seq[Network] = {
val nlinks = new mutable.HashMap[Node, Seq[Link]]()
network.links.foreach { l =>
if (nlinks.contains(l.e1)) {
nlinks(l.e1) = nlinks(l.e1) ++ Seq(l)
} else {
nlinks(l.e1) = Seq(l)
}
if (nlinks.contains(l.e2)) {
nlinks(l.e2) = nlinks(l.e2) ++ Seq(l)
} else {
nlinks(l.e2) = Seq(l)
}
}
network.nodes.foreach { n => if (!nlinks.contains(n)) {
nlinks(n) = Seq.empty
}
}
//traverse using the map, using hash consing
val totraverse = new mutable.HashMap[Node, Node]()
network.nodes.foreach { n => totraverse.put(n, n) }
val res = new ArrayBuffer[Network]()
def otherend(n: Node, l: Link): Node = {
if (l.e1 == n) l.e2 else l.e1
}
def traversenode(n: Node): (Seq[Node], Seq[Link]) = {
if (!totraverse.contains(n)) {
return (Seq.empty, nlinks(n))
} // note : a bit redundancy on links here as they are not colored
totraverse.remove(n)
val traversed = nlinks(n).map { l => traversenode(otherend(n, l)) }
(Seq(n) ++ traversed.flatMap(_._1), traversed.flatMap(_._2))
}
while (totraverse.nonEmpty) {
val entry = totraverse.values.head
val currentcomponent = traversenode(entry)
res.append(Network(currentcomponent._1.toSet, currentcomponent._2.toSet))
}
res.toSeq
}
def largestConnectedComponent(network: Network): Network = {
val components = connectedComponentsTraverse(network)
val largestComp = components.sortWith { case (n1, n2) => n1.nodes.size > n2.nodes.size }.head
largestComp
}
def shortestPaths(network: Network,
from: Seq[Node],
to: Seq[Node]
): ShortestPaths = new Math.GraphAlgorithms.DijkstraShortestPaths(network, from, to).getPaths
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy