Package graphmatcher.graph

Source Code of graphmatcher.graph.Graph

package graphmatcher.graph;

import graphmatcher.helper.AngleHelper;
import graphmatcher.helper.DistanceHelper;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import java.io.File;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class Graph implements Cloneable {
  private static Logger logger = Logger.getLogger(Graph.class);
  public static double maxAngleDiff = 25;

  private Vertex[] vertices;
  private Edge[] edges;
  private int numberOfVertices;
  private int numberOfEdges;

  /**
   * alle Kanten, die sich aus Kombinationen von original Kanten (sind hier
   * auch enthalten) erzeugen lassen
   */
  private Edge[] virtualEdges;
  private Edge[][] virtualConnectedComponents;
  private int[][] virtualConnectedComponentsEdgeIDs;

  private Vector<Integer>[] adjacentVirtualEdges;

  private Vector<Integer>[] iAdjacencyGraph;

  private Vector<Integer>[] connectivity;

  private String name = "graph";

  private Point center;
  private double shortestDistanceInGraph = -1;
  private double averageDistanceToCenterInGraph = -1;
  private double maximumDistanceToCenter = -1;
  private double lengthOfLongestEdge = -1;
  private double lenghtOfAllEdges = -1;

  private double[][] shortestPath;
  private boolean[][] visibility;

  /**
   * FIXME
   *
   * @deprecated entfernen?
   */
  private Rectangle rectangle;

  static {
    logger.setLevel(Level.OFF);
  }

  public Graph(File f) throws NumberFormatException, java.io.IOException {
    java.io.FileReader r = new java.io.FileReader(f);
    StreamTokenizer tok = new StreamTokenizer(r);
    tok.parseNumbers();

    int nV = nextNumber(tok);
    int nE = nextNumber(tok);

    numberOfVertices = nV;
    numberOfEdges = nE;
    vertices = new Vertex[numberOfVertices];
    edges = new Edge[numberOfEdges];
    iAdjacencyGraph = new Vector[numberOfVertices];

    for (int i = 0; i < numberOfVertices; ++i) {
      int x = nextNumber(tok);
      int y = nextNumber(tok);
      nextNumber(tok);
      vertices[i] = new Vertex(x, y);
    }
    for (int i = 0; i < numberOfEdges; ++i) {
      int p = nextNumber(tok);
      int q = nextNumber(tok);
      edges[i] = new Edge(p, q);
    }
    for (int i = 0; i < numberOfVertices; i++) {
      iAdjacencyGraph[i] = new Vector<Integer>();
    }
    for (int i = 0; i < numberOfEdges; i++) {
      Edge e = edges[i];

      iAdjacencyGraph[e.vertex1].add(new Integer(e.vertex2));
      iAdjacencyGraph[e.vertex2].add(new Integer(e.vertex1));

    }

    name = f.getName();
    name = name.substring(0, name.indexOf('.'));

    initialize();
  }

  public Graph(Vertex[] vertices, Edge[] edges) {
    this.vertices = vertices;
    this.edges = edges;
    numberOfVertices = vertices.length;
    numberOfEdges = edges.length;

    iAdjacencyGraph = new Vector[numberOfVertices];
    for (int i = 0; i < numberOfVertices; i++) {
      iAdjacencyGraph[i] = new Vector<Integer>();
    }
    for (int i = 0; i < numberOfEdges; i++) {
      Edge e = edges()[i];
      iAdjacencyGraph[e.vertex1].add(new Integer(e.vertex2));
      iAdjacencyGraph[e.vertex2].add(new Integer(e.vertex1));
    }
    initialize();
  }

  private void initialize() {
    computeShortestPaths();
    computeVisibility();
    computeConnectivity();
    computeVirtualEdges();
    computeVirtualConnectedComponents();
  }

  private static int nextNumber(StreamTokenizer tok) throws NumberFormatException, java.io.IOException {
    if (tok.nextToken() != StreamTokenizer.TT_NUMBER)
      throw new NumberFormatException();
    return (int) tok.nval;
  }

  /**
   * @deprecated
   */
  public Graph clone() {
    Vertex[] vClones = new Vertex[vertices().length];
    for (int i = 0; i < vClones.length; i++) {
      vClones[i] = vertices()[i].clone();
    }
    Edge[] vEdges = new Edge[edges().length];
    for (int i = 0; i < vEdges.length; i++) {
      vEdges[i] = edges()[i].clone();
    }
    Graph clone = new Graph(vClones, vEdges);
    clone.name = this.name + ("(clone)");
    return clone;
  }

  public int getNumberOfVertices() {
    return numberOfVertices;
  }

  public int getNumberOfEdges() {
    return numberOfEdges;
  }

  public String getName() {
    return name;
  }

  public String getShortName() {
    return name.substring(0, 5);
  }

  public void setName(String name) {
    this.name = name;
  }

  public Vertex[] vertices() {
    return vertices;
  }

  public Vector<Integer> getAdjacentVirtualEdges(int vertexID) {
    return adjacentVirtualEdges[vertexID];
  }

  public Edge[] edges() {
    return edges;
  }

  public Edge[] virtualEdges() {
    return virtualEdges;
  }

  public Edge[][] getVirtualConnectedComponents() {
    return virtualConnectedComponents;
  }

  public int[][] getVirtualConnectedComponentsEdgeIDs() {
    return virtualConnectedComponentsEdgeIDs;
  }

  public int getEdgeID(int vertex1, int vertex2) {
    Edge testEdge = new Edge(vertex1, vertex2);
    for (int i = 0; i < virtualEdges.length; i++) {
      Edge virtualEdge = virtualEdges[i];
      if (testEdge.equals(virtualEdge)) {
        return i;
      }
    }
    return -1;
  }

  public Vector<Integer>[] adjacency() {
    return iAdjacencyGraph;
  }

  public Point getCenter() {
    return getCenterOfWeightedEdges();
  }

  private Point getCenterOfWeightedEdges() {
    if (center != null) {
      return center;
    }
    double sumOfEdgeLenghts = 0;
    for (int i = 0; i < edges.length; i++) {
      Edge edge = edges[i];
      Vertex vertex1 = vertices[edge.vertex1];
      Vertex vertex2 = vertices[edge.vertex2];
      sumOfEdgeLenghts += DistanceHelper.getDistance(vertex1, vertex2);
    }
    double x = 0, y = 0;
    for (int i = 0; i < edges.length; i++) {
      Edge edge = edges[i];
      Vertex vertex1 = vertices[edge.vertex1];
      Vertex vertex2 = vertices[edge.vertex2];
      double edgeLength = DistanceHelper.getDistance(vertex1, vertex2);
      double weight = edgeLength / sumOfEdgeLenghts;
      x += weight * vertex1.x / 2;
      x += weight * vertex2.x / 2;
      y += weight * vertex1.y / 2;
      y += weight * vertex2.y / 2;
    }
    center = new Point((int) x, (int) y);
    return center;
  }

  @Deprecated
  private Point getCenterOfVertices() {
    double x = 0;
    double y = 0;
    for (int v = 0; v < vertices.length; v++) {
      x += vertices[v].x;
      y += vertices[v].y;
    }
    x = x / vertices.length;
    y = y / vertices.length;

    return new Point((int) Math.ceil(x), (int) Math.ceil(y));
  }

  @Deprecated
  private Point getCenterOfRectangle() {
    Rectangle rectangle = getRectangle();
    int centerX = (int) rectangle.getCenterX();
    int centerY = (int) rectangle.getCenterY();

    return new Point(centerX, centerY);
  }

  @Deprecated
  public double getAverageDistanceToCenterInGraph() {
    return getMaximumVertexDistanceToCenter();
    // if (averageDistanceToCenterInGraph > -1) {
    // return averageDistanceToCenterInGraph;
    // }
    // double result = 0;
    // Point centerOfMass = getCenter();
    // for (Vertex vertex : vertices()) {
    // result += DistanceHelper.getDistance(centerOfMass, vertex.toPoint());
    // }
    // averageDistanceToCenterInGraph = (int) (result / vertices().length);
    // return averageDistanceToCenterInGraph;
  }

  public double getMaximumVertexDistanceToCenter() {
    if (maximumDistanceToCenter > -1) {
      return maximumDistanceToCenter;
    }
    for (Vertex vertex : vertices) {
      double distance = DistanceHelper.getDistance(vertex.toPoint(), getCenter());
      if (distance > maximumDistanceToCenter) {
        maximumDistanceToCenter = distance;
      }
    }
    return maximumDistanceToCenter;
  }

  public double getLengthOfLongestEdge() {
    if (lengthOfLongestEdge > -1) {
      return lengthOfLongestEdge;
    }
    double maxLength = Double.MIN_VALUE;
    for (Edge edge : virtualEdges) {
      Vertex v1 = vertices[edge.vertex1];
      Vertex v2 = vertices[edge.vertex2];
      double length = DistanceHelper.getDistance(v1, v2);
      if (length > maxLength) {
        maxLength = length;
      }
    }
    lengthOfLongestEdge = maxLength;
    return lengthOfLongestEdge;
  }

  @Deprecated
  public double getLengthOfMedianEdge() {
    double[] edgeLengths = new double[edges.length];
    for (int i = 0; i < edges.length; i++) {
      Edge edge = edges[i];
      Vertex v1 = vertices[edge.vertex1];
      Vertex v2 = vertices[edge.vertex2];
      double length = DistanceHelper.getDistance(v1, v2);
      edgeLengths[i] = length;
    }
    Arrays.sort(edgeLengths);
    return edgeLengths[edgeLengths.length / 3];
  }

  @Deprecated
  public double getLengthOfShortestEdge() {
    double minLength = Double.MAX_VALUE;
    for (Edge edge : edges) {
      Vertex v1 = vertices[edge.vertex1];
      Vertex v2 = vertices[edge.vertex2];
      double length = DistanceHelper.getDistance(v1, v2);
      if (length < minLength) {
        minLength = length;
      }
    }
    return minLength;
  }

  public double getLengthOfAllEdges() {
    if (lenghtOfAllEdges > -1) {
      return lenghtOfAllEdges;
    }
    double result = 0;
    for (Edge edge : edges) {
      Vertex vertex1 = vertices[edge.vertex1];
      Vertex vertex2 = vertices[edge.vertex2];
      result += DistanceHelper.getDistance(vertex1, vertex2);
    }
    lenghtOfAllEdges = result;
    return lenghtOfAllEdges;
  }

  public double getLengthOfSpanningSubGraph(Collection<Integer> matchedEdges) {
    double result = 0;
    HashSet<Edge> allSubEdges = new HashSet<Edge>();
    Iterator<Integer> edgeIDIterator = matchedEdges.iterator();
    while (edgeIDIterator.hasNext()) {
      int edgeID = edgeIDIterator.next();
      Edge edge = virtualEdges[edgeID];
      addSubEdgesToSet(allSubEdges, edge);
      // if (edge.subEdges.isEmpty()) {
      // allSubEdges.add(edge);
      // } else {
      // // FIXME
      // allSubEdges.addAll(edge.subEdges);
      // }
    }
    for (int i = 0; i < edges.length; i++) {
      Edge edge = edges[i];
      if (allSubEdges.contains(edge)) {
        result += DistanceHelper.getLength(edge, this);
      } else {
        logger.debug(edge + "nicht enthalten - L�nge: " + DistanceHelper.getLength(edge, this));
      }
    }
    return result;
  }

  private void addSubEdgesToSet(HashSet<Edge> set, Edge edge) {
    if (edge.subEdges.isEmpty()) {
      set.add(edge);
    } else {
      for (Edge subEdge : edge.subEdges) {
        addSubEdgesToSet(set, subEdge);
      }
    }
  }

  public double getPercentageOfSpanningSubGraph(Collection<Integer> matchedEdges) {
    double l1 = getLengthOfSpanningSubGraph(matchedEdges);
    double l2 = getLengthOfAllEdges();
    double result = l1 / l2;
    logger.debug("Anteil des Teilgraphen: " + result + " (=" + l1 + "/" + l2 + ")");
    return result;
  }

  /**
   * Return a string representation of this graph.
   *
   * @return a string representation of this graph.
   */
  public String toString() {
    return name + ", " + vertices.length + ", " + edges.length;
  }

  public boolean isConnected(int vertex1, int vertex2) {
    if (iAdjacencyGraph[vertex1].contains(new Integer(vertex2))) {
      return true;
    }
    return false;
  }

  public boolean isVisible(int vertex1, int vertex2) {
    return visibility[vertex1][vertex2];
  }

  public int getNumberOfVisibleNeighbours(int vertex) {
    int result = 0;
    for (int i = 0; i < numberOfVertices; i++) {
      if (visibility[vertex][i]) {
        result++;
      }
    }
    return result - 1; // Knoten selbst nicht mitz�hlen
  }

  public Vector<Integer> getConnectedComponente(int vertex) {
    return connectivity[vertex];
  }

  public double getEdgeValue(int from, int to) {

    // is there a direct edge?
    // time saving shortcut
    if (iAdjacencyGraph[from].contains(new Integer(to)))
      return 1;

    // Bellman-Ford
    double pathLength = getPathLength(from, to);

    if (pathLength == Double.POSITIVE_INFINITY)
      return 0;

    return getDistance(from, to) / pathLength;
  }

  public double getPathLength(int from, int to) {

    // Bellman-Ford
    double[] distance = new double[numberOfVertices];

    for (int i = 0; i < numberOfVertices; i++)
      distance[i] = Double.POSITIVE_INFINITY;

    distance[from] = 0;

    for (int j = 0; j < numberOfVertices - 1; j++)
      for (int i = 0; i < numberOfEdges; i++) {
        if (distance[edges[i].vertex2] > distance[edges[i].vertex1]
            + getDistance(edges[i].vertex1, edges[i].vertex2)) {
          distance[edges[i].vertex2] = distance[edges[i].vertex1]
              + getDistance(edges[i].vertex1, edges[i].vertex2);
        }

        if (distance[edges[i].vertex1] > distance[edges[i].vertex2]
            + getDistance(edges[i].vertex2, edges[i].vertex1)) {
          distance[edges[i].vertex1] = distance[edges[i].vertex2]
              + getDistance(edges[i].vertex2, edges[i].vertex1);
        }
      }

    return distance[to];
  }

  public double getDistance(int from, int to) {
    double dX = vertices[from].x - vertices[to].x;
    double dY = vertices[from].y - vertices[to].y;

    return Math.sqrt(dX * dX + dY * dY);
  }

  public double getShortestDistanceInGraph() {
    if (shortestDistanceInGraph > -1) {
      return shortestDistanceInGraph;
    }
    double shortestDist = Double.POSITIVE_INFINITY;
    for (int i = 0; i < vertices.length; i++) {
      for (int j = 0; j < vertices.length; j++) {
        double dist = DistanceHelper.getDistance(vertices[i], vertices[j]);
        if (dist > 0 && dist < shortestDist) {
          shortestDist = dist;
        }
      }
    }
    shortestDistanceInGraph = shortestDist;
    return shortestDistanceInGraph;
  }

  public Rectangle getRectangle() {
    if (rectangle != null) {
      return rectangle;
    }
    int minX = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, minY = Integer.MAX_VALUE, maxY = Integer.MIN_VALUE;
    for (Vertex vertex : vertices) {
      int x = vertex.x;
      int y = vertex.y;
      if (x > maxX) {
        maxX = x;
      }
      if (x < minX) {
        minX = x;
      }
      if (y > maxY) {
        maxY = y;
      }
      if (y < minY) {
        minY = y;
      }
    }
    rectangle = new Rectangle(minX, minY, maxX - minX, maxY - minY);
    return rectangle;
  }

  private void computeVisibility() {
    visibility = new boolean[numberOfVertices][numberOfVertices];
    for (int i = 0; i < numberOfVertices; i++) {
      Point vertexI = vertices[i].toPoint();
      for (int j = 0; j < numberOfVertices; j++) {
        visibility[i][j] = true;
        if (i == j) {
          // Punkt sieht sich selbst
          continue;
        }
        if (iAdjacencyGraph[i].contains(j)) {
          continue;
        }
        Point vertexJ = vertices[j].toPoint();
        Line2D.Double line = new Line2D.Double(vertexI, vertexJ);
        for (int k = 0; k < numberOfEdges; k++) {
          Edge edge = edges[k];
          int v1 = edge.vertex1;
          int v2 = edge.vertex2;

          if ((i == v1) || (i == v2) || (j == v1) || (j == v2)) {
            // System.out.println("identische Linie: "+i+" - "+j);
            continue;
          }
          Line2D.Double line2 = new Line2D.Double(vertices[v1].toPoint(), vertices[v2].toPoint());
          boolean intersects = line.intersectsLine(line2);
          if (intersects) {
            visibility[i][j] = false;
            break;
          }
        }
      }
    }
  }

  /**
   * Adjazenzlisten m�ssen vorher erstellt worden sein!
   */
  private void computeConnectivity() {
    connectivity = new Vector[numberOfVertices];

    HashSet<Integer> usedVertices = new HashSet<Integer>();

    for (int i = 0; i < numberOfVertices; i++) {
      if (usedVertices.contains(i)) {
        continue;
      }
      Vector<Integer> connectedComponent = new Vector<Integer>();
      Vector<Integer> queue = new Vector<Integer>();
      queue.add(i);
      usedVertices.add(i);
      while (!queue.isEmpty()) {
        Integer next = queue.remove(0);
        connectedComponent.add(next);
        connectivity[next] = connectedComponent;

        Vector<Integer> adjacent = adjacency()[next];
        for (Integer adjacentVertex : adjacent) {
          if (!usedVertices.contains(adjacentVertex)) {
            queue.add(adjacentVertex);
            usedVertices.add(adjacentVertex);
          }
        }
      }
    }
  }

  private void computeVirtualConnectedComponents() {
    Vector<Vector<Edge>> connectedComponents = new Vector<Vector<Edge>>();
    Vector<Edge> usedEdges = new Vector<Edge>();

    for (int i = 0; i < virtualEdges.length; i++) {
      Edge nextEdge = virtualEdges[i];
      if (!usedEdges.contains(nextEdge)) {
        Vector<Edge> newConnectedComponent = new Vector<Edge>();

        Vector<Edge> queue = new Vector<Edge>();
        queue.add(nextEdge);
        usedEdges.add(nextEdge);
        while (!queue.isEmpty()) {
          Edge currentEdge = queue.remove(0);
          newConnectedComponent.add(currentEdge);

          Vector<Integer> adjacentEdges = new Vector<Integer>();
          adjacentEdges.addAll(getAdjacentVirtualEdges(currentEdge.vertex1));
          adjacentEdges.addAll(getAdjacentVirtualEdges(currentEdge.vertex2));
          for (int j = 0; j < adjacentEdges.size(); j++) {
            Edge adjacentEdge = virtualEdges[adjacentEdges.get(j)];
            if (!usedEdges.contains(adjacentEdge)) {
              queue.add(adjacentEdge);
              usedEdges.add(adjacentEdge);
            }
          }
        }
        connectedComponents.add(newConnectedComponent);
      }
    }

    virtualConnectedComponents = new Edge[connectedComponents.size()][];
    virtualConnectedComponentsEdgeIDs = new int[connectedComponents.size()][];
    for (int i = 0; i < connectedComponents.size(); i++) {
      logger.trace("Zusammenhangskomonente " + i);
      Vector<Edge> connectedComponent = connectedComponents.get(i);
      Edge[] ccArray = connectedComponent.toArray(new Edge[connectedComponent.size()]);
      Arrays.sort(ccArray, new Comparator<Edge>() {
        @Override
        public int compare(Edge o1, Edge o2) {
          double length1 = DistanceHelper.getLength(o1, Graph.this);
          double length2 = DistanceHelper.getLength(o2, Graph.this);
          if (length1 < length2) {
            return 1;
          } else if (length1 > length2) {
            return -1;
          }
          return 0;
        }
      });
      for (int j = 0; j < ccArray.length; j++) {
        Edge edge = ccArray[j];
        logger.trace(" " + edge);
      }
      virtualConnectedComponents[i] = ccArray;
      virtualConnectedComponentsEdgeIDs[i] = new int[ccArray.length];
      for (int j = 0; j < ccArray.length; j++) {
        Edge edge = ccArray[j];
        virtualConnectedComponentsEdgeIDs[i][j] = getEdgeID(edge.vertex1, edge.vertex2);
      }
    }
  }

  private void computeShortestPaths() {
    shortestPath = new double[numberOfVertices][numberOfVertices];
    // init floyd warshall
    for (int i = 0; i < numberOfVertices; i++) {
      Vertex vertex = vertices[i];
      for (int j = 0; j < numberOfVertices; j++) {
        shortestPath[i][j] = Double.POSITIVE_INFINITY;
        if (i == j) {
          shortestPath[i][j] = 0;
        }
      }
      Vector<Integer> adjacentNeighbourID = iAdjacencyGraph[i];
      for (Integer integer : adjacentNeighbourID) {
        Vertex neighbour = vertices[integer.intValue()];
        shortestPath[i][integer.intValue()] = DistanceHelper.getDistance(vertex.toPoint(), neighbour
            .toPoint());
      }
    }
    for (int k = 0; k < numberOfVertices; k++) {
      for (int i = 0; i < numberOfVertices; i++) {
        // Vertex vertexI = iVertices[i];
        for (int j = 0; j < numberOfVertices; j++) {
          // Vertex vertexJ = iVertices[j];

          double oldPath, newPath1, newPath2, newPath = -1;

          oldPath = shortestPath[i][j];
          newPath1 = shortestPath[i][k];
          newPath2 = shortestPath[k][j];
          newPath = newPath1 + newPath2;

          shortestPath[i][j] = Math.min(oldPath, newPath);
        }
      }
    }

    // for (int i = 0; i < numberOfVertices; i++) {
    // for (int j = 0; j < numberOfVertices; j++) {
    // double v = shortestPath[i][j];
    // if (v == Double.POSITIVE_INFINITY) {
    // System.out.print("inf\t");
    // } else {
    // System.out.print((int) shortestPath[i][j] + "\t");
    // }
    // }
    // System.out.println();
    // }
  }

  private void computeVirtualEdges() {
    Vector<Edge> edges = new Vector<Edge>();
    Vector<Edge> newEdgesQueue = new Vector<Edge>();
    for (Edge edge : this.edges) {
      newEdgesQueue.add(edge);
    }
    while (!newEdgesQueue.isEmpty()) {
      Edge edge = newEdgesQueue.remove(0);
      edges.add(edge);
      int edgeVertex1 = edge.vertex1;
      int edgeVertex2 = edge.vertex2;
      for (Edge oldEdge : edges) {
        if (edge.equals(oldEdge)) {
          continue;
        }
        int oldEdgeVertex1 = oldEdge.vertex1;
        int oldEdgeVertex2 = oldEdge.vertex2;

        Edge newEdge = createEdge(edgeVertex1, edgeVertex2, oldEdgeVertex1, oldEdgeVertex2);
        if (newEdge != null) {
          if (!newEdgesQueue.contains(newEdge) && !edges.contains(newEdge)) {
            // newEdge.subEdges.add(edge);
            // newEdge.subEdges.add(oldEdge);
            if (edge.subEdges.size() > 0) {
              newEdge.subEdges.addAll(edge.subEdges);
            } else {
              newEdge.subEdges.add(edge);
            }
            if (oldEdge.subEdges.size() > 0) {
              newEdge.subEdges.addAll(oldEdge.subEdges);
            } else {
              newEdge.subEdges.add(oldEdge);
            }
            newEdgesQueue.add(newEdge);
          } else {
            // Edge originalEdge;
            // int index = newEdgesQueue.indexOf(newEdge);
            // if (index == -1) {
            // index = edges.indexOf(newEdge);
            // originalEdge = edges.get(index);
            // } else {
            // originalEdge = newEdgesQueue.get(index);
            // }
            //
            // if (!edge.subEdges.contains(originalEdge)) {
            // originalEdge.subEdges.add(edge);
            // originalEdge.subEdges.add(oldEdge);
            // }
          }
        }
      }
    }
    virtualEdges = new Edge[edges.size()];
    for (int i = 0; i < edges.size(); i++) {
      Edge edge = edges.get(i);
      virtualEdges[i] = edge;
      // System.out.println(edge);
    }
    adjacentVirtualEdges = new Vector[getNumberOfVertices()];
    for (int i = 0; i < adjacentVirtualEdges.length; i++) {
      adjacentVirtualEdges[i] = new Vector<Integer>();
    }
    for (int i = 0; i < virtualEdges.length; i++) {
      Edge edge = virtualEdges[i];
      adjacentVirtualEdges[edge.vertex1].add(i);
      adjacentVirtualEdges[edge.vertex2].add(i);
    }
    logger.debug("Anzahl urspr�nglicher Kanten: " + edges.size());
    logger.debug("Anzahl virtueller Kanten:     " + virtualEdges.length);
  }

  private Edge createEdge(int e1v1, int e1v2, int e2v1, int e2v2) {
    if (e1v1 == e2v1) {
      return createEdgeWithAngleCheck(e1v2, e1v1, e2v2);
    }
    if (e1v1 == e2v2) {
      return createEdgeWithAngleCheck(e1v2, e1v1, e2v1);
    }
    if (e1v2 == e2v1) {
      return createEdgeWithAngleCheck(e1v1, e1v2, e2v2);
    }
    if (e1v2 == e2v2) {
      return createEdgeWithAngleCheck(e1v1, e1v2, e2v1);
    }
    return null;
  }

  private Edge createEdgeWithAngleCheck(int newVertex1, int middleVertex, int newVertex2) {
    Point newVertex1Point = vertices()[newVertex1].toPoint();
    Point middleVertexPoint = vertices()[middleVertex].toPoint();
    Point newVertex2Point = vertices()[newVertex2].toPoint();
    double angle = AngleHelper.getAngle(middleVertexPoint, newVertex1Point, newVertex2Point);
    if (Double.isNaN(angle)) {
      return new Edge(newVertex1, newVertex2);
    }
    if (angle < 90 || angle > 270) {
      return null;
    }
    if (angle >= 180 - Graph.maxAngleDiff && angle <= 180 + Graph.maxAngleDiff) {
      return new Edge(newVertex1, newVertex2);
    }
    double distv1M = DistanceHelper.getDistance(newVertex1Point, middleVertexPoint);
    double distv2M = DistanceHelper.getDistance(newVertex2Point, middleVertexPoint);
    double sum = distv1M + distv2M;
    double distv1v2 = DistanceHelper.getDistance(newVertex1Point, newVertex2Point);
    if (sum < distv1v2 * 1.05) {
      return new Edge(newVertex1, newVertex2);
    }

    // if (distv1M < getMaximumVertexDistanceToCenter() * 2 / 30) {
    // return new Edge(newVertex1, newVertex2);
    // }
    // if (distv2M < getMaximumVertexDistanceToCenter() * 2 / 30) {
    // return new Edge(newVertex1, newVertex2);
    // }
    return null;
  }

  public double getShorstestPath(int from, int to) {
    return shortestPath[from][to];
  }

  /**
   * Pr�ft, ob beide Graphen dieselbe Bedeutung haben. (Pr�ft nur
   * Graphennamen!)
   *
   * @param graph
   * @return
   */
  public boolean equalMeaning(Graph graph) {
    String name2 = graph.getName();
    // System.out.println(getName().subSequence(0, 4));
    if (getName().substring(0, 4).equals(name2.substring(0, 4))) {
      return true;
    }
    return false;
  }

  /**
   * Setzt die gecachten Werte zur�ck, so dass sie neu berechnet werden
   * m�ssen.
   */
  public void reset() {
    center = null;
    rectangle = null;
  }
}
TOP

Related Classes of graphmatcher.graph.Graph

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.