All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mgo.tools.network.Network.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2015 Guillaume Chérel
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */

package mgo.tools.network

import collection.JavaConverters._

/**
 * N = Node data type
 * E = Edge data type
 */
trait Network[N, E] {
  def node(u: Int): N = nodes(u)
  def iternodes: Iterator[(Int, N)] = nodes.indices.iterator zip nodes.iterator

  def nodes: Vector[N]
  def edge(u: Int, v: Int): Option[E]
  def iteredges: Iterator[(Int, Int, E)]

  /** Either digraph or graph */
  def dotGraphType: String

  // def toDot(
  //   graphId: String,
  //   nodeAttr: N => Seq[(String, String)],
  //   edgeAttr: E => Seq[(String, String)],
  //   additionalStatements: String): String =
  //   s"""$dotGraphType $graphId {
  //      |${additionalStatements.lines.map { "  " ++ _ }.iterator().asScala.mkString { "\n" }}
  //      |${toDotNodes(nodeAttr).lines.map { "  " ++ _ }.iterator().asScala.mkString { "\n" }}
  //      |${toDotEdges(edgeAttr).lines.map { "  " ++ _ }.iterator().asScala.mkString { "\n" }}
  //      |}""".stripMargin

  def toDotNodes(nodeAttr: N => Seq[(String, String)]): String =
    iternodes.map {
      case (i, n) => s"""$i [ ${
        nodeAttr(n).map {
          case (k, v) => s"$k = $v"
        }.mkString(", ")
      } ]"""
    }.mkString("\n")

  /** Either -> or -- */
  def dotEdgeOperator: String

  def toDotEdges(edgeAttr: E => Seq[(String, String)]): String =
    iteredges.map {
      case (u, v, e) => s"""$u $dotEdgeOperator $v [ ${
        edgeAttr(e).map {
          case (k, v) => s"$k = $v"
        }.mkString(", ")
      } ]"""
    }.mkString("\n")

  //  def toJSONNodeLink: String =
  //    s"""{
  //  "nodes":${toJSONNodes.lines.map { "  " ++ _ }.iterator().asScala.mkString { "\n" }},
  //  "links":${toJSONLinks.lines.map { "  " ++ _ }.iterator().asScala.mkString { "\n" }}
  //}"""

  def toJSONNodes: String =
    "[\n" ++
      iternodes.map { case (i, n) => s"""  {"id":$i, "data":"$n"}""" }.mkString(",\n") ++
      "\n]"

  def toJSONLinks: String =
    "[\n" ++
      iteredges.map { case (u, v, e) => s"""  {"source":$u, "target": $v, "data": $e}""" }.mkString(",\n") ++
      "\n]"

}

object Network {
  def directedSparse[N, E](
    _nodes: IndexedSeq[N],
    _edges: Traversable[(Int, Int, E)]): Network[N, E] with DirectedEdges[E] with SparseTopology[E] =
    new Network[N, E] with DirectedEdges[E] with SparseTopology[E] {
      val nodes = _nodes.toVector
      val mapin = SparseTopology.mapinFrom(_edges)
      val mapout = SparseTopology.mapoutFrom(_edges)
    }

  def directedSparse[E](
    nbOfNodes: Int,
    _edges: Traversable[(Int, Int, E)]): Network[Unit, E] with DirectedEdges[E] with SparseTopology[E] =
    new Network[Unit, E] with DirectedEdges[E] with SparseTopology[E] {
      val nodes: Vector[Unit] = Vector.fill(nbOfNodes)((): Unit)
      val mapin = SparseTopology.mapinFrom(_edges)
      val mapout = SparseTopology.mapoutFrom(_edges)
    }

  def directedDense[N, E](
    _nodes: IndexedSeq[N],
    _edges: Vector[Vector[E]]): Network[N, E] with DirectedEdges[E] with DenseTopology[E] =
    new Network[N, E] with DirectedEdges[E] with DenseTopology[E] {
      val nodes = _nodes.toVector
      val matrix = _edges
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy