Package net.wigis.graph.dnv.utilities

Source Code of net.wigis.graph.dnv.utilities.GraphFunctions

/******************************************************************************************************
* Copyright (c) 2010, University of California, Santa Barbara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*    * Redistributions of source code must retain the above copyright notice, this list of
*      conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright notice, this list of
*      conditions and the following disclaimer in the documentation and/or other materials
*      provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************************************/

package net.wigis.graph.dnv.utilities;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.wigis.graph.GraphsPathFilter;
import net.wigis.graph.dnv.DNVEdge;
import net.wigis.graph.dnv.DNVEntity;
import net.wigis.graph.dnv.DNVGraph;
import net.wigis.graph.dnv.DNVNode;
import net.wigis.graph.dnv.EdgeNodeAndValue;
import net.wigis.graph.dnv.EdgeQueue;
import net.wigis.graph.dnv.geometry.Circle;
import net.wigis.graph.dnv.geometry.Geometric;
import net.wigis.graph.dnv.geometry.Line;
import net.wigis.graph.dnv.geometry.Rectangle;
import net.wigis.graph.dnv.geometry.Text;
import net.wigis.graph.jgrapht.JGraphTEdge;
import net.wigis.graph.jgrapht.converter.JGraphTConverter;
import net.wigis.settings.Settings;

import org.jgrapht.GraphPath;
import org.jgrapht.UndirectedGraph;
import org.jgrapht.alg.BronKerboschCliqueFinder;
import org.jgrapht.alg.ConnectivityInspector;
import org.jgrapht.alg.KShortestPaths;

// TODO: Auto-generated Javadoc
/**
* A class containing some useful static functions.
*
* @author Brynjar Gretarsson
*/
public final class GraphFunctions
{
  // private static RandomGraphGenerator generator;

  /** The Constant DNV_NODE. */
  public static final String DNV_NODE = "DNV Node";

  /** The Constant DNV_EDGE. */
  public static final String DNV_EDGE = "DNV Edge";

  // private static VertexFactory factory;

  // private static List<DNVNode> allNeighbors = new ArrayList<DNVNode>();

  /** The Constant numberOfNeighborLevels. */
  public static final int numberOfNeighborLevels = 3;

  /** The Constant colorEntity. */
  public static final Vector3D colorEntity = new Vector3D( 1.0f, 1.0f, 0.3f );

  /** The Constant colorDocument. */
  public static final Vector3D colorDocument = new Vector3D( 0.7f, 0.7f, 0.9f );

  /** The Constant colorContainer. */
  public static final Vector3D colorContainer = new Vector3D( 1.0f, 0.3f, 0.3f );

  /** The selected nodes. */
  public static Map<String, DNVNode> selectedNodes = new HashMap<String, DNVNode>();

  /**
   * Logger.
   *
   * @param node1
   *            the node1
   * @param node2
   *            the node2
   * @param display
   *            the display
   * @return the distance
   */
  // // private static Log logger = LogFactory.getLog( GraphFunctions.class );

  /*
   * public static float fitness( DNVGraph graph, Integer level ) { float
   * fitness = 0;
   *
   * List<DNVNode> allNodes = graph.getNodes( level ); Iterator<DNVNode> i =
   * allNodes.iterator(); Iterator<DNVNode> j; float numberOfNodes =
   * graph.getGraphSize( level ); float numberOfEdges = graph.getEdges( level
   * ).size(); float sumOfDistances = 0; float tempDistance = 0; float
   * sumOfRestingErrors = 0; DNVNode iNode; DNVNode jNode; while( i.hasNext()
   * ) { iNode = i.next(); j = allNodes.iterator(); while( j.hasNext() ) {
   * jNode = j.next(); if( jNode != iNode ) { tempDistance = getDistance(
   * iNode, jNode ); if( iNode.isNeighbor( jNode ) ) { sumOfRestingErrors +=
   * Math.abs( tempDistance - iNode.getEdgeToNeighbor( jNode.getId()
   * ).getRestingDistance() ); } else { sumOfDistances += tempDistance; } } }
   * }
   *
   * sumOfDistances = sumOfDistances / numberOfNodes / numberOfNodes;
   * sumOfRestingErrors = sumOfRestingErrors / numberOfEdges / numberOfEdges;
   * fitness = sumOfDistances - sumOfRestingErrors;
   *
   * return fitness; }
   */

  // private static float angle( DNVNode node1, DNVNode node2 )
  // {
  // Vector2D point1 = new Vector2D( node1.getPosition() );
  // point1.normalize();
  // Vector2D point2 = new Vector2D( node2.getPosition() );
  // point2.normalize();
  //
  // return point1.angle( point2 );
  // }

  /**
   * @param node1
   * @param node2
   * @return The distance between node1 and node2.
   */
  public static float getDistance( DNVNode node1, DNVNode node2, boolean display )
  {
    return getDistance( node1.getPosition( display ), node2.getPosition( display ) );
  }

  /**
   * Gets the distance.
   *
   * @param x1
   *            the x1
   * @param y1
   *            the y1
   * @param point2
   *            the point2
   * @return the distance
   */
  public static float getDistance( float x1, float y1, Vector2D point2 )
  {
    float x2 = point2.getX();
    float y2 = point2.getY();

    return getDistance( x1, y1, x2, y2 );
  }

  /**
   * Gets the distance.
   *
   * @param point1
   *            the point1
   * @param point2
   *            the point2
   * @return The distance between point1 and point2.
   */
  public static float getDistance( Vector2D point1, Vector2D point2 )
  {
    float x1 = point1.getX();
    float y1 = point1.getY();
    float x2 = point2.getX();
    float y2 = point2.getY();

    return getDistance( x1, y1, x2, y2 );
  }

  /**
   * Gets the distance.
   *
   * @param x1
   *            the x1
   * @param y1
   *            the y1
   * @param x2
   *            the x2
   * @param y2
   *            the y2
   * @return The distance between the two points (x1,y1,z2) and (x2,y2,z2)
   */
  public static float getDistance( float x1, float y1, float x2, float y2 )
  {

    return (float)Math.sqrt( Math.pow( x1 - x2, 2 ) + Math.pow( y1 - y2, 2 ) );
  }

  /**
   * Sets the selected node.
   *
   * @param graph
   *            the graph
   * @param selectedNode
   *            the selected node
   */
  public static void setSelectedNode( DNVGraph graph, DNVNode selectedNode )
  {
    if( selectedNode == null )
      selectedNodes.remove( graph.toString() );
    else
      selectedNodes.put( graph.toString(), selectedNode );
  }

  /**
   * Gets the graph width.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param display
   *            the display
   * @return the graph width
   */
  public static float getGraphWidth( DNVGraph graph, Integer level, boolean display )
  {
    return getGraphWidth( graph.getNodes( level ), display );
  }

  /**
   * Gets the graph width.
   *
   * @param nodes
   *            the nodes
   * @param display
   *            the display
   * @return the graph width
   */
  public static float getGraphWidth( Collection<DNVNode> nodes, boolean display )
  {
    return getMaxXPosition( nodes, display ) - getMinXPosition( nodes, display );
  }

  /**
   * Gets the graph height.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param display
   *            the display
   * @return the graph height
   */
  public static float getGraphHeight( DNVGraph graph, Integer level, boolean display )
  {
    return getGraphHeight( graph.getNodes( level ), display );
  }

  /**
   * Gets the graph height.
   *
   * @param nodes
   *            the nodes
   * @param display
   *            the display
   * @return the graph height
   */
  public static float getGraphHeight( Collection<DNVNode> nodes, boolean display )
  {
    return getMaxYPosition( nodes, display ) - getMinYPosition( nodes, display );
  }

  /**
   * Gets the max x position.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param display
   *            the display
   * @return the max x position
   */
  public static float getMaxXPosition( DNVGraph graph, Integer level, boolean display )
  {
    return getMaxXPosition( graph.getNodes( level ), display );
  }

  /**
   * Gets the max x position.
   *
   * @param nodeList
   *            the node list
   * @param display
   *            the display
   * @return the max x position
   */
  public static float getMaxXPosition( Collection<DNVNode> nodeList, boolean display )
  {
    if( nodeList != null )
    {
      Iterator<DNVNode> nodes = nodeList.iterator();
      DNVNode tempNode = null;
      float max = Float.NEGATIVE_INFINITY;
      float temp;
      while( nodes.hasNext() )
      {
        tempNode = nodes.next();
        temp = tempNode.getPosition( display ).getX();
        if( temp > max )
          max = temp;
      }

      return max;
    }

    return 0;
  }

  /**
   * Gets the max y position.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param display
   *            the display
   * @return the max y position
   */
  public static float getMaxYPosition( DNVGraph graph, Integer level, boolean display )
  {
    return getMaxYPosition( graph.getNodes( level ), display );
  }

  /**
   * Gets the max y position.
   *
   * @param nodeList
   *            the node list
   * @param display
   *            the display
   * @return the max y position
   */
  public static float getMaxYPosition( Collection<DNVNode> nodeList, boolean display )
  {
    if( nodeList != null )
    {
      Iterator<DNVNode> nodes = nodeList.iterator();
      DNVNode tempNode = null;
      float max = Float.NEGATIVE_INFINITY;
      float temp;
      while( nodes.hasNext() )
      {
        tempNode = nodes.next();
        temp = tempNode.getPosition( display ).getY();
        if( temp > max )
          max = temp;
      }

      return max;
    }

    return 0;
  }

  /**
   * Gets the min x position.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param display
   *            the display
   * @return the min x position
   */
  public static float getMinXPosition( DNVGraph graph, Integer level, boolean display )
  {
    return getMinXPosition( graph.getNodes( level ), display );
  }

  /**
   * Gets the min x position.
   *
   * @param nodeList
   *            the node list
   * @param display
   *            the display
   * @return the min x position
   */
  public static float getMinXPosition( Collection<DNVNode> nodeList, boolean display )
  {
    float min = Float.POSITIVE_INFINITY;
    if( nodeList != null )
    {
      Iterator<DNVNode> nodes = nodeList.iterator();
      DNVNode tempNode = null;
      float temp;
      while( nodes.hasNext() )
      {
        tempNode = nodes.next();
        temp = tempNode.getPosition( display ).getX();
        if( temp < min )
          min = temp;
      }

      return min;
    }

    return 0;
  }

  /**
   * Gets the min y position.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param display
   *            the display
   * @return the min y position
   */
  public static float getMinYPosition( DNVGraph graph, Integer level, boolean display )
  {
    return getMinYPosition( graph.getNodes( level ), display );
  }

  /**
   * Gets the min y position.
   *
   * @param nodeList
   *            the node list
   * @param display
   *            the display
   * @return the min y position
   */
  public static float getMinYPosition( Collection<DNVNode> nodeList, boolean display )
  {
    if( nodeList != null )
    {
      Iterator<DNVNode> nodes = nodeList.iterator();
      DNVNode tempNode = null;
      float min = Float.POSITIVE_INFINITY;
      float temp;
      while( nodes.hasNext() )
      {
        tempNode = nodes.next();
        temp = tempNode.getPosition( display ).getY();
        if( temp < min )
          min = temp;
      }

      return min;
    }

    return 0;
  }

  /** The center. */
  private static Vector2D center = new Vector2D();

  /**
   * Gets the center of gravity.
   *
   * @param i
   *            the i
   * @return the center of gravity
   */
  public static Vector2D getCenterOfGravity( Iterator<DNVNode> i )
  {
    DNVNode tempNode = null;
    float totalX = 0;
    float totalY = 0;
    float number = 0;
    Vector2D position;
    Object temp;
    while( i.hasNext() )
    {
      temp = i.next();
      if( temp instanceof DNVNode )
        tempNode = (DNVNode)temp;
      if( tempNode != null )
      {
        position = tempNode.getPosition();
        totalX += position.getX();
        totalY += position.getY();
        number++;
      }
    }

    center.setX( totalX / number );
    center.setY( totalY / number );

    return center;
  }

  /**
   * Gets the average x position.
   *
   * @param i
   *            the i
   * @return the average x position
   */
  public static float getAverageXPosition( Iterator<DNVNode> i )
  {
    DNVNode tempNode = null;
    float total = 0;
    float number = 0;
    Object temp;
    float subnodes = 0;
    while( i.hasNext() )
    {
      temp = i.next();
      if( temp instanceof DNVNode )
        tempNode = (DNVNode)temp;
      subnodes = tempNode.getTotalNumberOfSubNodes();
      total += tempNode.getPosition().getX() * subnodes;
      number += subnodes;
    }

    return total / number;

  }

  /**
   * Gets the average y position.
   *
   * @param i
   *            the i
   * @return the average y position
   */
  public static float getAverageYPosition( Iterator<DNVNode> i )
  {
    DNVNode tempNode = null;
    float total = 0;
    float number = 0;
    Object temp;
    float subnodes = 0;
    while( i.hasNext() )
    {
      temp = i.next();
      if( temp instanceof DNVNode )
        tempNode = (DNVNode)temp;
      subnodes = tempNode.getTotalNumberOfSubNodes();
      total += tempNode.getPosition().getY() * subnodes;
      number += subnodes;
    }

    return total / number;

  }

  /** The processed edges. */
  private static Map<Integer, Float> processedEdges = new HashMap<Integer, Float>();

  /**
   * Initialize positions.
   *
   * @param graph
   *            the graph
   */
  public static void initializePositions( DNVGraph graph )
  {
    if( graph != null )
    {
      int maxLevel = graph.getMaxLevel();
      for( int i = 0; i <= maxLevel; i++ )
      {
        initializeLevel( i, graph );
      }
    }
  }

  /**
   * Initialize level.
   *
   * @param level
   *            the level
   * @param graph
   *            the graph
   */
  private static void initializeLevel( int level, DNVGraph graph )
  {
    processedEdges.clear();
    Iterator<DNVNode> nodes;
    Vector2D center = Vector2D.ZERO;
    System.out.println( "Processing level " + level );
    if( level > 0 )
    {
      System.out.println( "     Updating edge lengths and masses" );
      nodes = graph.getNodes( level ).iterator();
      while( nodes.hasNext() )
        nodes.next().updateEdgelengthsAndMass( processedEdges, false );
    }

    nodes = graph.getNodes( level ).iterator();
    int size = graph.getGraphSize( level );
    DNVNode tempNode;
    DNVNode parentNode;
    int siblings = 0;
    int i = 0;
    System.out.println( "     Setting the positions for " + size + " nodes." );
    float distance;
    Timer distanceTimer = new Timer( Timer.NANOSECONDS );
    Timer placingTimer = new Timer( Timer.NANOSECONDS );
    while( nodes.hasNext() )
    {
      tempNode = nodes.next();
      parentNode = tempNode.getParentNode();
      if( parentNode != null )
      {
        center = parentNode.getPosition();
        siblings = parentNode.getNumberOfSubNodes();
      }
      else
      {
        center = new Vector2D( (float)Math.random(), (float)Math.random() );
        siblings = 1;
      }

      distanceTimer.setStart();
      distance = getDistanceFromFirstSibling( tempNode );
      distanceTimer.setEnd();
      if( distanceTimer.getLastSegment( Timer.SECONDS ) > 1 )
      {
        System.out.println( "Getting distance from " + tempNode.getId() + " to " + tempNode.getFirstSibling().getId() + " took "
            + distanceTimer.getLastSegment( Timer.SECONDS ) + " seconds. Distance is " + distance );
      }
      placingTimer.setStart();
      tempNode.placeNode( i, siblings, distance, center, true, graph.getMaxLevel() );
      placingTimer.setEnd();
      // System.out.println( "Placing node took " +
      // placingTimer.getLastSegment( Timer.SECONDS ) + " seconds." );
      i++;
    }

    System.out.println( "Average time for getting distance " + distanceTimer.getAverageTime( Timer.SECONDS ) + " seconds." );
    System.out.println( "Average time for placing node     " + placingTimer.getAverageTime( Timer.SECONDS ) + " seconds." );

  }

  /**
   * Gets the distance from first sibling.
   *
   * @param node
   *            the node
   * @return the distance from first sibling
   */
  public static float getDistanceFromFirstSibling( DNVNode node )
  {
    float distance = 0;

    DNVNode otherNode = node.getFirstSibling();
    if( otherNode != null )
    {
      if( otherNode == node )
        return 0;

      distance = findShortestPathDistance( node, otherNode );
      if( distance == Float.POSITIVE_INFINITY )
        System.out.println( "Unable to find path between nodes " + node.getId() + " and " + otherNode.getId() );
    }

    return distance;
  }

  /**
   * Find shortest path distance.
   *
   * @param startNode
   *            the start node
   * @param goalNode
   *            the goal node
   * @return the float
   */
  public static float findShortestPathDistance( DNVNode startNode, DNVNode goalNode )
  {
    Map<Integer, Float> visitedNodes = new HashMap<Integer, Float>();
    EdgeQueue edgeQueue = new EdgeQueue();
    addTimer.reset();
    float value = findShortestPathDistance( edgeQueue, visitedNodes, 0, Float.POSITIVE_INFINITY, startNode, goalNode, true, false );

    return value;
  }

  /**
   * Find shortest path distance in number of hops.
   *
   * @param startNode
   *            the start node
   * @param goalNode
   *            the goal node
   * @return the float
   */
  public static float findShortestPathDistanceInNumberOfHops( DNVNode startNode, DNVNode goalNode )
  {
    Map<Integer, Float> visitedNodes = new HashMap<Integer, Float>();
    EdgeQueue edgeQueue = new EdgeQueue();
    addTimer.reset();
    float value = findShortestPathDistance( edgeQueue, visitedNodes, 0, Float.POSITIVE_INFINITY, startNode, goalNode, false, false );

    return value;
  }

  /** The add timer. */
  private static Timer addTimer = new Timer( Timer.NANOSECONDS );

  // private static Timer processTimer = new Timer( Timer.NANOSECONDS );
  /**
   * Find shortest path distance.
   *
   * @param edgeQueue
   *            the edge queue
   * @param visitedNodes
   *            the visited nodes
   * @param distance
   *            the distance
   * @param bestDistance
   *            the best distance
   * @param startNode
   *            the start node
   * @param goalNode
   *            the goal node
   * @param useActualEdgeLengths
   *            the use actual edge lengths
   * @return the float
   */
  private static float findShortestPathDistance( EdgeQueue edgeQueue, Map<Integer, Float> visitedNodes, float distance, float bestDistance,
      DNVNode startNode, DNVNode goalNode, boolean useActualEdgeLengths, boolean visibleOnly )
  {
    // Stopping condition
    if( startNode == goalNode )
    {
      return distance;
    }
    if( distance > bestDistance )
      return Float.POSITIVE_INFINITY;

    addTimer.setStart();
    edgeQueue.addAll( visitedNodes, startNode, startNode.getFromEdges(visibleOnly), distance, useActualEdgeLengths );
    edgeQueue.addAll( visitedNodes, startNode, startNode.getToEdges(visibleOnly), distance, useActualEdgeLengths );
    addTimer.setEnd();

    EdgeNodeAndValue enav;
    float newDistance = 0;
    Float previousDistance = 0.0f;
    while( !edgeQueue.isEmpty() )
    {
      enav = edgeQueue.pop();
      visitedNodes = enav.getPath();
      previousDistance = visitedNodes.get( enav.getNode().getId() );
      if( previousDistance == null )
      {
        visitedNodes.put( enav.getNode().getId(), enav.getValue() );
        newDistance = findShortestPathDistance( edgeQueue, visitedNodes, enav.getValue(), bestDistance, enav.getOtherNode(), goalNode,
            useActualEdgeLengths, visibleOnly );
        if( newDistance < bestDistance )
        {
          bestDistance = newDistance;
        }
      }
    }

    return bestDistance;
  }

  /**
   * Removes the isolated nodes.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   */
  public static void removeIsolatedNodes( DNVGraph graph, Integer level )
  {
    List<DNVNode> nodes = graph.getNodes( level );
    DNVNode tempNode;
    for( int i = 0; i < nodes.size(); i++ )
    {
      tempNode = nodes.get( i );
      if( tempNode.getNeighbors().size() == 0 )
      {
        graph.removeNode( level, tempNode );
      }
    }
  }

  /**
   * Clear higher levels.
   *
   * @param level
   *            the level
   * @param graph
   *            the graph
   */
  public static void clearHigherLevels( int level, DNVGraph graph )
  {
    for( int i = level + 1; i <= graph.getMaxLevel(); i++ )
    {
      graph.clearLevel( i );
    }
  }

  /*
   * public static List<DNVNode> convertCollectionToList( Collection<DNVNode>
   * collection ) { if( collection instanceof List )
   * return(List<DNVNode>)collection;
   *
   * return new ArrayList<DNVNode>(collection); }
   */
  /**
   * Convert collection to list.
   *
   * @param collection
   *            the collection
   * @return the list
   */
  public static List<DNVEntity> convertCollectionToList( Collection<DNVEntity> collection )
  {
    if( collection instanceof List<?> )
      return (List<DNVEntity>)collection;

    return new ArrayList<DNVEntity>( collection );
  }

  /**
   * Gets the maximum pairwise shortest path.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @return the maximum pairwise shortest path
   */
  public static int getMaximumPairwiseShortestPath( DNVGraph graph, int level )
  {
    float max = 0;
    float temp;
    List<DNVNode> nodes = graph.getNodes( level );
    for( int i = 0; i < nodes.size(); i++ )
    {
      for( int j = i + 1; j < nodes.size(); j++ )
      {
        temp = findShortestPathDistanceInNumberOfHops( nodes.get( i ), nodes.get( j ) );
        if( temp != Float.POSITIVE_INFINITY && temp > max )
        {
          max = temp;
        }
      }
    }

    return (int)max;
  }

  /**
   * Gets the edge to node of type.
   *
   * @param graph
   *            the graph
   * @param node
   *            the node
   * @param type
   *            the type
   * @return the edge to node of type
   */
  public static DNVEdge getEdgeToNodeOfType( DNVGraph graph, DNVNode node, String type )
  {
    Iterator<DNVEdge> edges;
    DNVNode neighbor;
    DNVEdge edge;
    try
    {
      edges = node.getFromEdges().iterator();
      while( edges.hasNext() )
      {
        edge = edges.next();
        neighbor = edge.getTo();
        if( neighbor.getType().equals( type ) )
        {
          return edge;
        }
      }
    }
    catch( NullPointerException npe )
    {}

    try
    {
      edges = node.getToEdges().iterator();
      while( edges.hasNext() )
      {
        edge = edges.next();
        neighbor = edge.getFrom();
        if( neighbor.getType().equals( type ) )
        {
          return edge;
        }
      }
    }
    catch( NullPointerException npe )
    {}
    return null;
  }

  /**
   * Gets the k nearest node ids.
   *
   * @param k
   *            the k
   * @param node
   *            the node
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param restingDistance
   *            the resting distance
   * @param type
   *            the type
   * @return the k nearest node ids
   */
  public static List<Integer> getKNearestNodeIds( int k, DNVNode node, DNVGraph graph, int level, boolean restingDistance, String type )
  {
    List<Integer> theIds = new ArrayList<Integer>();

    DNVNode[] theNodes = getKNearestNodes( k, node, graph, level, restingDistance, type );

    String tempStr;
    for( int i = 0; i < k; i++ )
    {
      if( theNodes[i] != null )
      {
        tempStr = theNodes[i].getBbId();
        tempStr = tempStr.replace( "user", "" );
        try
        {
          theIds.add( Integer.parseInt( tempStr ) );
        }
        catch( NumberFormatException nfe )
        {}
      }
    }

    return theIds;
  }

  /**
   * Gets the k nearest nodes.
   *
   * @param k
   *            the k
   * @param node
   *            the node
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param restingDistance
   *            the resting distance
   * @param type
   *            the type
   * @return the k nearest nodes
   */
  public static DNVNode[] getKNearestNodes( int k, DNVNode node, DNVGraph graph, int level, boolean restingDistance, String type )
  {
    DNVNode[] theNodes = new DNVNode[k];
    Vector2D position = node.getPosition();
    Comparator<DNVNode> sort;
    if( restingDistance )
      sort = new RestingDistanceSort();
    else
      sort = new DistanceSort( position );
    Iterator<DNVNode> nodes = graph.getNodes( level ).iterator();
    List<DNVNode> nodesList = new ArrayList<DNVNode>();
    DNVNode tempNode;
    while( nodes.hasNext() )
    {
      tempNode = nodes.next();
      if( tempNode.getType().equals( type ) && !tempNode.equals( node ) )
        nodesList.add( tempNode );
    }

    Collections.sort( nodesList, sort );

    for( int i = 0; i < k && i < nodesList.size(); i++ )
    {
      theNodes[i] = nodesList.get( i );
    }

    return theNodes;
  }

  /**
   * Gets the node by type.
   *
   * @param type
   *            the type
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @return the node by type
   */
  public static DNVNode getNodeByType( String type, DNVGraph graph, Integer level )
  {
    Map<Integer, DNVEntity> nodes = graph.getNodesByType( level, type );
    if( nodes != null && nodes.size() > 0 )
      return (DNVNode)nodes.values().iterator().next();

    return null;
  }

  /**
   * Color k nearest nodes.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param k
   *            the k
   * @param centerType
   *            the center type
   * @param peersType
   *            the peers type
   */
  public static void colorKNearestNodes( DNVGraph graph, int level, int k, String centerType, String peersType )
  {
    for( DNVNode tempNode : graph.getNodes( level ) )
    {
      tempNode.setColor( 1, 1, 1 );
    }

    DNVNode activeNode = GraphFunctions.getNodeByType( centerType, graph, level );
    DNVNode[] peersholder = GraphFunctions.getKNearestNodes( k, activeNode, graph, level, false, peersType );

    for( int i = 0; i < peersholder.length; i++ )
    {
      peersholder[i].setColor( 1f, 0.5f, 0.5f );
    }
  }

  /**
   * Convert color.
   *
   * @param datasourceColor
   *            the datasource color
   * @return the vector3 d
   */
  public static Vector3D convertColor( String datasourceColor )
  {
    Vector3D newColor = new Vector3D();
    float r;
    float g;
    float b;

    if( datasourceColor == null )
    {
      r = 0;
      g = 0;
      b = 0;
      newColor.set( r, g, b );
      return newColor;
    }

    if( datasourceColor.startsWith( "#" ) )
    {
      datasourceColor = datasourceColor.substring( 1 );
    }

    r = Integer.parseInt( datasourceColor.substring( 0, 2 ), 16 ) / 255.0f;
    g = Integer.parseInt( datasourceColor.substring( 2, 4 ), 16 ) / 255.0f;
    b = Integer.parseInt( datasourceColor.substring( 4, 6 ), 16 ) / 255.0f;
    newColor.set( r, g, b );

    return newColor;
  }

  /**
   * Are connected.
   *
   * @param itemNode
   *            the item node
   * @param friendNode
   *            the friend node
   * @return true, if successful
   */
  public static boolean areConnected( DNVNode itemNode, DNVNode friendNode )
  {
    Map<Integer, DNVNode> neighborMap = itemNode.getNeighborMap();
    DNVNode node = neighborMap.get( friendNode.getId() );
    if( node != null )
      return true;

    return false;
  }

  /**
   * Clear hop distance for all nodes.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   */
  public static void clearHopDistanceForAllNodes( DNVGraph graph, int level )
  {
    for( DNVNode node : graph.getNodes( level ) )
    {
      node.removeProperty( "hopDistance" );
    }
  }

  /**
   * Find shortest path to all nodes in number of hops.
   *
   * @param centralNode
   *            the central node
   */
  public static void findShortestPathToAllNodesInNumberOfHops( DNVNode centralNode )
  {
    centralNode.setProperty( "hopDistance", "" + 0.0f );
    Map<Integer, DNVNode> neighbors = centralNode.getNeighborMap();
    handleNodes( 1, neighbors );
  }

  /**
   * Handle nodes.
   *
   * @param distance
   *            the distance
   * @param nodes
   *            the nodes
   */
  private static void handleNodes( float distance, Map<Integer, DNVNode> nodes )
  {
    Map<Integer, DNVNode> neighbors = new HashMap<Integer, DNVNode>();
    float hopDistance;
    for( DNVNode node : nodes.values() )
    {
      hopDistance = getHopDistance( node );
      if( hopDistance > distance )
      {
        node.setProperty( "hopDistance", "" + distance );
        // if( distance > 3 )
        // {
        // node.setRadius( 1 );
        // }
        for( DNVNode tempNode : node.getNeighbors() )
        {
          neighbors.put( tempNode.getId(), tempNode );
        }
      }
    }

    if( neighbors.size() > 0 )
    {
      handleNodes( distance + 1, neighbors );
    }
  }

  /**
   * Gets the hop distance.
   *
   * @param node
   *            the node
   * @return the hop distance
   */
  public static float getHopDistance( DNVNode node )
  {
    String hopDistanceStr = node.getProperty( "hopDistance" );
    if( hopDistanceStr == null )
    {
      return Float.POSITIVE_INFINITY;
    }

    try
    {
      return Float.parseFloat( hopDistanceStr );
    }
    catch( NumberFormatException nfe )
    {
      return Float.POSITIVE_INFINITY;
    }
  }

  /**
   * Scale positions.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param newWidth
   *            the new width
   * @param newHeight
   *            the new height
   * @param oldWidth
   *            the old width
   * @param oldHeight
   *            the old height
   */
  public static void scalePositions( DNVGraph graph, int level, double newWidth, double newHeight, double oldWidth, double oldHeight )
  {
    double xRatio = newWidth / oldWidth;
    double yRatio = newHeight / oldHeight;
    for( DNVNode node : graph.getNodes( level ) )
    {
      // System.out.print( "Transforming " + node.getPosition() + " to "
      // );
      node.setPosition( (float)( node.getPosition().getX() * xRatio ), (float)( node.getPosition().getY() * yRatio ) );
      // System.out.println( node.getPosition() );
    }

    if( graph.getGeometricObjects( level ) != null )
    {
      for( Geometric g : graph.getGeometricObjects( level ) )
      {
        if( g instanceof Circle )
        {
          Circle c = (Circle)g;
          c.setCenter( (float)( c.getCenter().getX() * xRatio ), (float)( c.getCenter().getY() * yRatio ) );
        }
        else if( g instanceof Rectangle )
        {
          Rectangle r = (Rectangle)g;
          r.setBottomRight( (float)( r.getBottomRight().getX() * xRatio ), (float)( r.getBottomRight().getY() * yRatio ) );
          r.setTopLeft( (float)( r.getTopLeft().getX() * xRatio ), (float)( r.getTopLeft().getY() * yRatio ) );
        }
        else if( g instanceof Line )
        {
          Line l = (Line)g;
          l.setStart( (float)( l.getStart().getX() * xRatio ), (float)( l.getStart().getY() * yRatio ) );
          l.setEnd( (float)( l.getEnd().getX() * xRatio ), (float)( l.getEnd().getY() * yRatio ) );
        }
        else if( g instanceof Text )
        {
          Text t = (Text)g;
          t.setPosition( (float)( t.getPosition().getX() * xRatio ), (float)( t.getPosition().getY() * yRatio ) );
        }
      }
    }
  }

  public static Collection<Set<DNVNode>> getAllMaximalCliques( DNVGraph graph, int level )
  {
    BronKerboschCliqueFinder<DNVNode, JGraphTEdge<DNVNode>> cliqueFinder = getCliqueFinder( graph, level );
    Collection<Set<DNVNode>> cliques = cliqueFinder.getAllMaximalCliques();

    return cliques;
  }

  /**
   * @param graph
   * @param level
   * @return
   */
  private static BronKerboschCliqueFinder<DNVNode, JGraphTEdge<DNVNode>> getCliqueFinder( DNVGraph graph, int level )
  {
    UndirectedGraph<DNVNode, JGraphTEdge<DNVNode>> g = JGraphTConverter.convertDNVToUndirectedJGraphT( graph, level );
    BronKerboschCliqueFinder<DNVNode, JGraphTEdge<DNVNode>> cliqueFinder = new BronKerboschCliqueFinder<DNVNode, JGraphTEdge<DNVNode>>( g );
    return cliqueFinder;
  }

  public static Collection<Set<DNVNode>> getBiggestMaximalCliques( DNVGraph graph, int level )
  {
    BronKerboschCliqueFinder<DNVNode, JGraphTEdge<DNVNode>> cliqueFinder = getCliqueFinder( graph, level );
    Collection<Set<DNVNode>> cliques = cliqueFinder.getBiggestMaximalCliques();

    return cliques;
  }
 
  public static List<List<DNVNode>> getNodesOnKShortestPaths( DNVGraph graph, int level, DNVNode startNode, DNVNode endNode, int k )
  {
    List<List<DNVNode>> allPaths = new ArrayList<List<DNVNode>>();
   
    UndirectedGraph<DNVNode,JGraphTEdge<DNVNode>> g = JGraphTConverter.convertDNVToUndirectedJGraphT( graph, level );
   
    KShortestPaths<DNVNode,JGraphTEdge<DNVNode>> paths = new KShortestPaths<DNVNode, JGraphTEdge<DNVNode>>( g, startNode, k );
    List<GraphPath<DNVNode,JGraphTEdge<DNVNode>>> thePaths = paths.getPaths( endNode );
    if( thePaths == null )
    {
      return null;
    }

    for( GraphPath<DNVNode,JGraphTEdge<DNVNode>> path : thePaths )
    {
      List<DNVNode> tempPath = new ArrayList<DNVNode>();
      tempPath.add( path.getStartVertex() );
      DNVNode lastNode = path.getStartVertex();
      for( JGraphTEdge<DNVNode> edge : path.getEdgeList() )
      {
        if( edge.getSource() == lastNode )
        {
          tempPath.add( edge.getTarget() );
          lastNode = edge.getTarget();
        }
        else
        {
          tempPath.add( edge.getSource() );
          lastNode = edge.getSource();
        }
      }
      allPaths.add( tempPath );
    }

   
    return allPaths;
  }
 
  public static DNVNode getMostFrequentIntermediateNode( DNVGraph graph, int level, DNVNode startNode, DNVNode endNode, int maxNumberOfPaths )
  {
    int numberOfPaths = 0;
    boolean done = false;
    DNVNode mostFrequentNode = null;
    DNVNode secondMostFrequentNode;
    while( !done )
    {
      numberOfPaths += 100;
//      System.out.println( numberOfPaths );
      List<DNVNode> allNodes = getNodesSortedByFrequencyOnShortestPath( graph, level, startNode, endNode, numberOfPaths );
      if( allNodes == null )
      {
        return null;
      }
      mostFrequentNode = null;
      secondMostFrequentNode = null;
      for( DNVNode node : allNodes )
      {
        if( node != startNode && node != endNode )
        {
          if( mostFrequentNode == null )
          {
            mostFrequentNode = node;
          }
          else
          {
            secondMostFrequentNode = node;
            break;
          }
        }
      }
     
      int count1 = Integer.parseInt( mostFrequentNode.getProperty( "nodeCount" ) );
      int count2 = Integer.parseInt( secondMostFrequentNode.getProperty( "nodeCount" ) );
//      System.out.println( "First candidate:" + mostFrequentNode.getLabel() );
//      System.out.println( "Second candidate:" + secondMostFrequentNode.getLabel() );
//      System.out.println( "diff:" + Math.abs( count1 - count2 ) );
//      System.out.println( "percentage:" + count1 / (double)numberOfPaths );
      if( (count1 / (double)numberOfPaths) > 0.7 /*|| Math.abs( count1 - count2 ) >= numberOfPaths * 0.1*/ || numberOfPaths >= maxNumberOfPaths )
      {
        done = true;
      }

      for( DNVNode node : allNodes )
      {
        if( node == mostFrequentNode && done )
        {
          node.setProperty( "pathFrequency_" + startNode.getId() + "_" + endNode.getId(), node.getProperty( "nodeCount" ) );
        }
        node.removeProperty( "nodeCount" );
      }
    }
   
   
    return mostFrequentNode;
  }

  public static List<DNVNode> getNodesSortedByFrequencyOnShortestPath( DNVGraph graph, int level, DNVNode startNode, DNVNode endNode, int numberOfPaths )
  {
    List<List<DNVNode>> allPaths = GraphFunctions.getNodesOnKShortestPaths( graph, level, startNode, endNode, numberOfPaths );
    if( allPaths == null )
    {
      return null;
    }
//    System.out.println( "Finding paths from " + startNode.getLabel() + " to " + endNode.getLabel() );
    int count = 0;
    for( List<DNVNode> path : allPaths )
    {
//      System.out.println( "Start of path " + count++ + " length = " + path.size() );
      for( DNVNode node : path )
      {
//        System.out.println( "\t" + node.getLabel() );
        Integer nodeCount = 0;
        if( node.hasProperty( "nodeCount" ) )
        {
          nodeCount = Integer.parseInt( node.getProperty( "nodeCount" ) );
        }
        nodeCount++;
        node.setProperty( "nodeCount", "" + nodeCount );
      }
    }
   
    List<DNVNode> allNodes = graph.getNodes( level );
    SortByFloatProperty sbfp = new SortByFloatProperty( "nodeCount", true );
    Collections.sort( allNodes, sbfp );
    return allNodes;
  }
 
  public static boolean doesPathExist( DNVGraph graph, int level, DNVNode startNode, DNVNode endNode )
  {
    UndirectedGraph<DNVNode, JGraphTEdge<DNVNode>> g = JGraphTConverter.convertDNVToUndirectedJGraphT( graph, level );
    ConnectivityInspector<DNVNode, JGraphTEdge<DNVNode>> inspector = new ConnectivityInspector<DNVNode, JGraphTEdge<DNVNode>>( g );

    return inspector.pathExists( startNode, endNode );
  }

  public static void main( String args[] )
  {
    GraphsPathFilter.init();
    DNVGraph graph = new DNVGraph( Settings.GRAPHS_PATH + "UserStudy/testGraphs/graph1small.dnv" );
    DNVNode startNode = graph.getNodes().get( (int)(Math.random()*graph.getNodes().size()) );
    DNVNode endNode = graph.getNodes().get( (int)(Math.random()*graph.getNodes().size()) );
    DNVNode frequent = getMostFrequentIntermediateNode( graph, 0, startNode, endNode, 1000 );
   
    System.out.println( "Most frequent node " + frequent.getLabel() + " with " + frequent.getProperty( "pathFrequency_" + startNode.getId() + "_" + endNode.getId() ) + " occurrances." );
    
  }
}
TOP

Related Classes of net.wigis.graph.dnv.utilities.GraphFunctions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.