Example #1
0
 /** @return closest valid runtime node (not to be used while building world) */
 private Vector2 getClosestNode(float x, float y) {
   if (movementGraph.containsVertex(new Vector2(x, y))) return new Vector2(x, y);
   for (float dst = 1; dst < 100; dst++)
     for (float angle = 0; angle < Math.PI * 2; angle += Math.PI / 12) {
       int xtmp = (int) (x + Math.cos(angle) * dst);
       int ytmp = (int) (y + Math.sin(angle) * dst);
       if (movementGraph.containsVertex(new Vector2(xtmp, ytmp))) return new Vector2(xtmp, ytmp);
     }
   return new Vector2(x, y);
 }
Example #2
0
  // select a node according to degrees
  public Integer SelectNode_PA() throws IOException {
    HashMap<Integer, Double> node_degree = new HashMap<Integer, Double>();
    for (int n : G.vertexSet()) {
      node_degree.put(n, (double) G.degreeOf(n));
    }

    RandomProb rp = new RandomProb<Integer>();
    Integer selected_node = (Integer) (rp.randomPro(node_degree));

    return selected_node;
  }
 /** Generate vertices for the graph representing the floor plan */
 private void generateVertices() {
   for (int row = 0; row < rowCount; ++row) {
     for (int col = 0; col < colCount; ++col) {
       cellContainer[row][col] = new Cell(row, col, this);
       g.addVertex(cellContainer[row][col]);
     }
   }
 }
Example #4
0
 public AIWorld(World gameWorld) {
   synchronized (gameWorld) {
     movementGraph = GraphGenerator.generateGraph(gameWorld);
   }
   logger.info(
       "Initialized graph with "
           + movementGraph.edgeSet().size()
           + " edges and "
           + movementGraph.vertexSet().size()
           + " vertices");
   world = new World(new Vector2(), true);
   PhysicsHelper.createLoaderBodies(
       world, Gdx.files.internal("data/world/world.json"), "strategicPoints");
   strategicPoints = GraphGenerator.generateStrategicPoints(world);
   logger.info("Loaded ai world and found " + strategicPoints.size() + " strategic points");
   createGraphVisible();
   EventManager.addListener(EventEnum.PARSER_AI_GRAPH_VISIBLE, this);
 }
  /** @return the largest connected component of the graph. */
  public ArrayList<Cell> getLargestConnectedComponent() {
    ArrayList<ArrayList<Cell>> components = new ArrayList<>();
    boolean visited[][] = new boolean[rowCount][colCount];
    for (int row = 0; row < rowCount; ++row)
      for (int col = 0; col < colCount; ++col) visited[row][col] = false;

    Queue<Cell> q;
    Cell t = null, u = null;
    for (Cell c : g.vertexSet()) {
      if (!visited[c.getRow()][c.getCol()]) {
        q = new LinkedList<Cell>();
        ArrayList<Cell> component = new ArrayList<>();
        visited[c.getRow()][c.getCol()] = true;

        // Find all connected nodes
        q.add(c);
        component.add(c);
        while (!q.isEmpty()) {
          t = q.remove();
          for (WeightedEdge e : g.edgesOf(t)) {
            u = t.equals(g.getEdgeSource(e)) ? g.getEdgeTarget(e) : g.getEdgeSource(e);
            if (!visited[u.getRow()][u.getCol()]) {
              visited[u.getRow()][u.getCol()] = true;
              q.add(u);
              component.add(u);
            }
          }
        }

        components.add(component);
      }
    }

    int largestSize = 0, largestIndex = 0;
    for (int i = 0; i < components.size(); ++i) {
      if (components.get(i).size() > largestSize) {
        largestSize = components.get(i).size();
        largestIndex = i;
      }
    }

    filterGraph(components.get(largestIndex));
    return components.get(largestIndex);
  }
 /**
  * Remove all edges connecting dead cells with others Call this after loading this entity from db
  * OR after config is changed. (i.e., after ratio or actualW or actualH is changed)
  */
 public void updateGraph() {
   cellContainer = new Cell[rowCount][colCount];
   initGraph();
   int row, col;
   for (DeadPoint dp : deadPoints) {
     col = getCorrespondingCol(dp.getX());
     row = getCorrespondingRow(dp.getY());
     if (valid(row, col)) g.removeVertex(cellContainer[row][col]);
   }
 }
  private int outputInterestingStuff(
      Vertex v1,
      Vertex v2,
      SimpleWeightedGraph<Vertex, DefaultWeightedComparableEdge> probabilityGraph) {

    for (DefaultWeightedComparableEdge e : probabilityGraph.edgesOf(v1)) {
      System.err.print(probabilityGraph.getEdgeWeight(e) + "\t");
    }

    System.err.println();
    for (DefaultWeightedComparableEdge e : probabilityGraph.edgesOf(v2)) {
      System.err.print(probabilityGraph.getEdgeWeight(e) + "\t");
    }
    System.err.println();

    JFrame frame = new JFrame("Continue?");
    frame.pack();
    frame.setVisible(false);
    return JOptionPane.showConfirmDialog(frame, "hey", "there", 2);
  }
Example #8
0
 public Queue<Vector2> getPathToPoint(Vector2 origin, Vector2 destination) {
   LinkedList<Vector2> steps = new LinkedList<Vector2>();
   Vector2 originRounded = getClosestNode(Math.round(origin.x), Math.round(origin.y));
   Vector2 destinationRounded =
       getClosestNode(Math.round(destination.x), Math.round(destination.y));
   try {
     List<DefaultWeightedEdge> list =
         DijkstraShortestPath.findPathBetween(movementGraph, originRounded, destinationRounded);
     for (DefaultWeightedEdge edge : list) steps.add(movementGraph.getEdgeSource(edge));
     steps.add(movementGraph.getEdgeTarget(list.get(list.size() - 1)));
   } catch (Exception e) {
     logger.warning(
         "Error pathfinding for origin="
             + originRounded
             + " destination="
             + destinationRounded
             + " with message: "
             + e.getMessage());
   }
   return steps;
 }
Example #9
0
  public void randomwalk(int v) {
    // weighted random walk
    RandomWalk rw = new RandomWalk(p_w);
    int status = rw.stay_move();
    ArrayList<Integer> walkpath = new ArrayList<Integer>();
    Integer u = v;
    walkpath.add(v);
    while (status == 1) // keep moving until status = 0
    {
      u = rw.move(G, u);
      if (u == null) // no neighbors
      break;
      if (!walkpath.contains(u)) walkpath.add(u);
      status = rw.stay_move();
    }
    //		System.out.println("walking length: "+ Integer.toString(walkpath.size()));

    for (int i = 0; i < walkpath.size(); i++)
      for (int j = i + 1; j < walkpath.size(); j++) {
        int m = walkpath.get(i);
        int n = walkpath.get(j);
        if (!G.containsEdge(m, n)) {
          double distance = Math.abs(socialposition.get(m) - socialposition.get(n));
          double prob = linkprob(distance, (j - i));
          if (random.nextDouble() < prob) {
            G.setEdgeWeight((DefaultWeightedEdge) G.addEdge(m, n), 1);
          }
        } else {
          DefaultWeightedEdge edge = G.getEdge(m, n);
          G.setEdgeWeight(edge, G.getEdgeWeight(edge) + 1);
        }
      }
    return;
  }
Example #10
0
  /**
   * Links all the spots in the selection, in time-forward order.
   *
   * @param model the model to modify.
   * @param selectionModel the selection that contains the spots to link.
   */
  public static void linkSpots(final Model model, final SelectionModel selectionModel) {

    /*
     * Configure tracker
     */

    final TrackableObjectCollection<Spot> spots =
        new DefaultTOCollection<Spot>(selectionModel.getSpotSelection());
    final Map<String, Object> settings = new HashMap<String, Object>(1);
    settings.put(KEY_LINKING_MAX_DISTANCE, Double.POSITIVE_INFINITY);
    final NearestNeighborTracker<Spot> tracker = new NearestNeighborTracker<Spot>(spots, settings);
    tracker.setNumThreads(1);

    /*
     * Execute tracking
     */

    if (!tracker.checkInput() || !tracker.process()) {
      System.err.println("Problem while computing spot links: " + tracker.getErrorMessage());
      return;
    }
    final SimpleWeightedGraph<Spot, DefaultWeightedEdge> graph = tracker.getResult();

    /*
     * Copy found links in source model
     */

    model.beginUpdate();
    try {
      for (final DefaultWeightedEdge edge : graph.edgeSet()) {
        final Spot source = graph.getEdgeSource(edge);
        final Spot target = graph.getEdgeTarget(edge);
        model.addEdge(source, target, graph.getEdgeWeight(edge));
      }
    } finally {
      model.endUpdate();
    }
  }
  /**
   * Disable the cell containing the given point
   *
   * @param x
   * @param y
   */
  public void disableCell(int x, int y) {
    int col = getCorrespondingCol(x);
    int row = getCorrespondingRow(y);

    // If a cell is already dead, it wouldn't be disabled again; Do this to reduce the number of
    // dead points created
    if (valid(row, col) && !cellContainer[row][col].isDead()) {
      cellContainer[row][col].disableCell();
      deadPoints.add(new DeadPoint(x, y, this));

      // removing this cell from the graph and all of its touching edges
      g.removeVertex(cellContainer[row][col]);
    }
  }
Example #12
0
 private void createGraphVisible() {
   if (graphVisibleBodies == null) graphVisibleBodies = new ArrayList<Body>();
   for (int i = 0; i < graphVisibleBodies.size(); i++)
     world.destroyBody(graphVisibleBodies.get(i));
   graphVisibleBodies.clear();
   if (nodesVisible)
     for (Vector2 node : movementGraph.vertexSet())
       PhysicsHelper.createCircle(world, BodyType.StaticBody, .1f, 1, FactionType.NEUTRAL)
           .setTransform(node, 0);
   if (edgesVisible)
     for (DefaultWeightedEdge edge : movementGraph.edgeSet()) {
       Vector2 source = movementGraph.getEdgeSource(edge),
           target = movementGraph.getEdgeTarget(edge);
       PhysicsHelper.createEdge(
           world,
           BodyType.StaticBody,
           source.x,
           source.y,
           target.x,
           target.y,
           1,
           FactionType.NEUTRAL);
     }
 }
Example #13
0
 // global attachment -- with prob 1
 public void globalattach(int v) throws IOException {
   Integer u = random.nextInt(N);
   while (u == v) u = random.nextInt(N);
   if (!G.containsEdge(v, u)) {
     G.setEdgeWeight((DefaultWeightedEdge) G.addEdge(v, u), 1);
   } else {
     DefaultWeightedEdge edge = G.getEdge(v, u);
     G.setEdgeWeight(edge, G.getEdgeWeight(edge) + 1);
   }
 }
  /**
   * Compute the log-probability that each observation arises for each ant. This is represented by a
   * simple weighted graph, where the absence of an edge represents zero probability that the given
   * observation was caused by the given ant. Currently the log-prob is set to be a truncated iid
   * Gaussian around an ant location.
   *
   * @param probabilityGraph The probability graph being constructed.
   * @param edgeMap A sorted map of the edges in probabilityGraph.
   * @param thisObservedPosMap Observed points along with index.
   * @param thisParticlePosMap Current particle locations.
   * @param obsSums
   * @param antSums
   * @return Sum of edge weights
   */
  private double computeLogProbabilityGraph(
      SimpleWeightedGraph<Vertex, DefaultWeightedComparableEdge> probabilityGraph,
      ValueSortedMap<DefaultWeightedComparableEdge, Double> edgeMap,
      HashMap<Vertex, Point> thisObservedPosMap,
      HashMap<Vertex, AntPath> thisParticlePathMap) {
    /** Initialize vertices. */
    edgeMap.clear();

    probabilityGraph.addVertex(falseNegative);
    probabilityGraph.addVertex(falsePositive);

    for (Vertex v : thisObservedPosMap.keySet()) {
      probabilityGraph.addVertex(v);
      DefaultWeightedComparableEdge edge = probabilityGraph.addEdge(v, falsePositive);
      probabilityGraph.setEdgeWeight(edge, falsePositiveLogProb);
      edgeMap.put(edge, falsePositiveLogProb);
    }
    for (Vertex v : thisParticlePathMap.keySet()) {
      probabilityGraph.addVertex(v);
      DefaultWeightedComparableEdge edge = probabilityGraph.addEdge(v, falseNegative);
      probabilityGraph.setEdgeWeight(edge, falseNegativeLogProb);
      edgeMap.put(edge, falseNegativeLogProb);
    }

    /** Compute probability of each observation given each ant path */
    for (Entry<Vertex, Point> obsEntry : thisObservedPosMap.entrySet()) {
      for (Entry<Vertex, AntPath> parEntry : thisParticlePathMap.entrySet()) {
        double logprob = observationLogProbGivenAntPath(obsEntry.getValue(), parEntry.getValue());
        if (logprob > logProbThreshold) {
          DefaultWeightedComparableEdge edge =
              probabilityGraph.addEdge(obsEntry.getKey(), parEntry.getKey());
          probabilityGraph.setEdgeWeight(edge, logprob);
          edgeMap.put(edge, logprob);
        }
      }
    }

    /** Adjust probabilities according to log-probability of an AntPath existing. */
    for (Entry<Vertex, AntPath> antEntry : thisParticlePathMap.entrySet()) {
      Set<DefaultWeightedComparableEdge> edge = probabilityGraph.edgesOf(antEntry.getKey());
      double antProb = antEntry.getValue().getCurrentLogProb();
      for (DefaultWeightedComparableEdge e : edge) {
        double ew = probabilityGraph.getEdgeWeight(e);
        probabilityGraph.setEdgeWeight(e, ew + antProb);
        // edgeMap.remove(edge);
        edgeMap.put(e, ew + antProb);
      }
    }

    /**
     * ANG -- to do Interaction effects: -- probability of false negative higher when multiple ants
     * in same area. however, there is a high probability that there will be SOME observation in the
     * area. -- probability of a false positive higher when there is one ant in a region. this is
     * because sometimes one ant is split into two.
     */

    /** compute vertex sums */
    // Utils.computeVertexSums(probabilityGraph);
    double totalLogProb = Utils.maxstar(edgeMap);

    return totalLogProb;
  }
 /**
  * Remove all nodes which are NOT in cells from graph g
  *
  * @param cells
  */
 private void filterGraph(ArrayList<Cell> cells) {
   for (int row = 0; row < rowCount; ++row)
     for (int col = 0; col < colCount; ++col)
       if (!cells.contains(cellContainer[row][col])) g.removeVertex(cellContainer[row][col]);
 }
  /**
   * Add edges connecting this cell and its 8 (or less) neighbors
   *
   * @param row
   * @param col
   */
  private void addEdges(int row, int col) {
    System.out.println("Adding (" + row + ", " + col + ")");
    // Add weighted edge
    // North
    if (row > 0 && g.containsVertex(cellContainer[row][col])) {
      g.addEdge(cellContainer[row][col], cellContainer[row - 1][col]);
      g.setEdgeWeight(g.getEdge(cellContainer[row][col], cellContainer[row - 1][col]), 1);
      // NE
      if (col < colCount - 1 && g.containsVertex(cellContainer[row - 1][col + 1])) {
        g.addEdge(cellContainer[row][col], cellContainer[row - 1][col + 1]);
        g.setEdgeWeight(
            g.getEdge(cellContainer[row][col], cellContainer[row - 1][col + 1]), Math.sqrt(2.0));
      }
    }

    // East
    if (col < colCount - 1 && g.containsVertex(cellContainer[row][col + 1])) {
      g.addEdge(cellContainer[row][col], cellContainer[row][col + 1]);
      g.setEdgeWeight(g.getEdge(cellContainer[row][col], cellContainer[row][col + 1]), 1);

      // SE
      if (row < rowCount - 1 && g.containsVertex(cellContainer[row + 1][col + 1])) {
        g.addEdge(cellContainer[row][col], cellContainer[row + 1][col + 1]);
        g.setEdgeWeight(
            g.getEdge(cellContainer[row][col], cellContainer[row + 1][col + 1]), Math.sqrt(2.0));
      }
    }

    // South
    if (row < rowCount - 1 && g.containsVertex(cellContainer[row + 1][col])) {
      g.addEdge(cellContainer[row][col], cellContainer[row + 1][col]);
      g.setEdgeWeight(g.getEdge(cellContainer[row][col], cellContainer[row + 1][col]), 1);

      // SW
      if (col > 0 && g.containsVertex(cellContainer[row + 1][col - 1])) {
        g.addEdge(cellContainer[row][col], cellContainer[row + 1][col - 1]);
        g.setEdgeWeight(
            g.getEdge(cellContainer[row][col], cellContainer[row + 1][col - 1]), Math.sqrt(2.0));
      }
    }

    // West
    if (col > 0 && g.containsVertex(cellContainer[row][col - 1])) {
      g.addEdge(cellContainer[row][col], cellContainer[row][col - 1]);
      g.setEdgeWeight(g.getEdge(cellContainer[row][col], cellContainer[row][col - 1]), 1);

      // NW
      if (row > 0 && g.containsVertex(cellContainer[row - 1][col - 1])) {
        g.addEdge(cellContainer[row][col], cellContainer[row - 1][col - 1]);
        g.setEdgeWeight(
            g.getEdge(cellContainer[row][col], cellContainer[row - 1][col - 1]), Math.sqrt(2.0));
      }
    }
  }
Example #17
0
  /**
   * Reads the geometry and connectivity.
   *
   * @param filename the location of the gjf file
   */
  public GJFfile(String filename) {
    super(filename);

    // read geometry
    String name = "";
    List<Atom> contents = new ArrayList<>();
    SimpleWeightedGraph<Atom, DefaultWeightedEdge> connectivity =
        new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
    int blanks = 0;
    boolean lastBlank = false;
    boolean inGeometryBlock = false;
    for (List<String> line : fileContents) {
      // keep track of how many blanks we have seen
      if (line.size() == 1 && line.get(0).length() == 0) {
        if (lastBlank == false) {
          blanks++;
          lastBlank = true;
        }
        continue;
      } else lastBlank = false;

      // read the metadata
      if (blanks == 1) {
        for (String s : line) {
          String[] fields = s.split("@");
          if (fields.length != 3) continue;
          String identifier = fields[1].toLowerCase();
          String value = fields[2];
          // System.out.println(s);
          // System.out.println(identifier + " : " + value);

          if (identifier.equals("o1")) O1Number = Integer.parseInt(value);
          else if (identifier.equals("o2")) O2Number = Integer.parseInt(value);
          else if (identifier.equals("n3")) N3Number = Integer.parseInt(value);
          else if (identifier.equals("cl1")) Cl1Number = Integer.parseInt(value);
          else if (identifier.equals("su2")) Su2Number = Integer.parseInt(value);
          else if (identifier.equals("ol3")) Ol3Number = Integer.parseInt(value);
          else if (identifier.equals("mem")) mem = Integer.parseInt(value);
          else if (identifier.equals("nprocshared")) nprocshared = Integer.parseInt(value);
          else if (identifier.equals("method")) method = value;
          else if (identifier.equals("basis")) basis = value;
          else System.out.println("unrecognized entry: " + s);
        }

        continue;
      } else if (blanks != 2) continue;

      // deal with the charge and multiplicity card (by ignoring it)
      if (line.size() == 2 && inGeometryBlock == false) {
        inGeometryBlock = true;
        continue;
      }

      if (line.size() != 4 && inGeometryBlock == false)
        throw new IllegalArgumentException(
            "unexpected text in geometry block in " + filename + ":\n" + line.toString());

      // create atom
      // tinker atom types will be nonsense, of course
      Atom newAtom =
          new Atom(
              line.get(0),
              new Vector3D(
                  Double.parseDouble(line.get(1)),
                  Double.parseDouble(line.get(2)),
                  Double.parseDouble(line.get(3))),
              1);
      contents.add(newAtom);
      connectivity.addVertex(newAtom);
    }

    // read connectivity
    blanks = 0;
    lastBlank = false;
    for (List<String> line : fileContents) {
      // read the fourth block of text
      if (line.size() == 1 && line.get(0).length() == 0) {
        if (lastBlank == false) {
          blanks++;
          lastBlank = true;
        }
        continue;
      } else lastBlank = false;

      // only read connectivity lines
      if (blanks != 3) continue;

      Atom fromAtom = contents.get(Integer.parseInt(line.get(0)) - 1);
      for (int i = 1; i < line.size(); i += 2) {
        int toAtomIndex = Integer.parseInt(line.get(i)) - 1;
        Atom toAtom = contents.get(toAtomIndex);
        double bondOrder = Double.parseDouble(line.get(i + 1));
        DefaultWeightedEdge thisEdge = connectivity.addEdge(fromAtom, toAtom);
        connectivity.setEdgeWeight(thisEdge, bondOrder);
      }
    }

    // create the molecule
    molecule = new Molecule(name, contents, connectivity, 0.0);
  }
Example #18
0
  public static void main(String[] args) throws IOException {
    System.out.println("Enter parameters: N p_w p_r steps:");
    try {
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
      String paras[] = reader.readLine().split(" ");
      N = Integer.parseInt(paras[0]);
      p_w = Float.parseFloat(paras[1]);
      p_r = Float.parseFloat(paras[2]);
      steps = Integer.parseInt(paras[3]);
    } catch (IOException e) {
      System.out.println("Error reading from user");
    }

    long start = System.currentTimeMillis();

    int simulations = 1;
    for (int t = 1; t <= simulations; t++) {

      // Initialization, generate an empty network of N nodes
      EIM dynamic = new EIM();
      G = new SimpleWeightedGraph<Integer, DefaultWeightedEdge>(DefaultWeightedEdge.class);
      for (int i = 0; i < N; i++) G.addVertex(i);
      String para = "EIM_" + Integer.toString(t);
      String folder = "files/" + "Networks" + "/";
      File f = new File(folder);
      if (f.exists() == false) {
        f.mkdirs();
      }

      // distribution of social space
      socialposition = dynamic.uniform(N);

      for (int s = 0; s < steps; s++) {
        int v = random.nextInt(N);
        // LA process - weighted random walk + link with social distance
        dynamic.localattach(v);
        // GA process
        // no edges, create one random link
        if (G.edgesOf(v).size() == 0) {
          dynamic.globalattach(v);
        } else {
          float prob = random.nextFloat();
          if (prob < p_r) dynamic.globalattach(v);
        }
        // ND process
        int d = random.nextInt(N);
        if (G.edgesOf(d).size() > 0) {
          float prob = random.nextFloat();
          if (prob < p_d) {
            Set<DefaultWeightedEdge> edges = new HashSet(G.edgesOf(d));
            G.removeAllEdges(edges);
          }
        }
        if (s % 100000 == 0) {
          System.out.print("Steps:" + Integer.toString(s) + "	");
          System.out.print("Edges:");
          System.out.print(G.edgeSet().size() + "	");
          System.out.println(
              "Avg_degree: "
                  + Float.toString((float) G.edgeSet().size() * 2 / G.vertexSet().size()));
        }
      }
      // delete isolate nodes
      ArrayList<Integer> nodelist = new ArrayList<Integer>();
      for (int node : G.vertexSet()) nodelist.add(node);
      for (int node : nodelist) {
        if (G.degreeOf(node) == 0) G.removeVertex(node);
      }
      System.out.print("Nodes:");
      System.out.println(G.vertexSet().size());
      System.out.print("Edges:");
      System.out.println(G.edgeSet().size());

      // get largest connected component
      Statistics stat = new Statistics();
      Graph G_LCC = stat.largestConnectedComponent(G);

      ExportGraph export = new ExportGraph();
      export.exportWPairs((SimpleWeightedGraph<Integer, DefaultWeightedEdge>) G_LCC, para, folder);
      System.out.print("Nodes in LCC:");
      System.out.println(G_LCC.vertexSet().size());
      System.out.print("Edges in LCC:");
      System.out.println(G_LCC.edgeSet().size());
      System.out.println("Avg_degree: " + Double.toString(stat.avg_degree(G_LCC)));
      System.out.println("Avg_clustering: " + Double.toString(stat.avg_clustering(G_LCC)));
      System.out.println(
          "Degree assortativity: " + Double.toString(stat.assortativityCoefficient(G_LCC)));
    }

    long elapsedTimeMillis = System.currentTimeMillis() - start;
    float elapsedTimeHour = elapsedTimeMillis / (60 * 60 * 1000F);
    System.out.print("Elapsed time: ");
    System.out.print(elapsedTimeHour);
    System.out.println(" hours.");
  }
  // Create shortest-path graph for every vertex by depth-first traversal algorithm
  private Multigraph<String, DefaultEdge> DijkstraAlgorithm(
      WeightedMultigraph<String, DefaultWeightedEdge> originalGraph, String thisVertex) {

    // 1. Simplify the multi-graph of the active power flow into a simple graph
    SimpleWeightedGraph<String, DefaultWeightedEdge> originalSimpleGraph =
        new SimpleWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class);
    for (String curVertex : originalGraph.vertexSet()) originalSimpleGraph.addVertex(curVertex);
    for (DefaultWeightedEdge curEdge : originalGraph.edgeSet()) {
      String sourceVertex = originalGraph.getEdgeSource(curEdge);
      String targetVertex = originalGraph.getEdgeTarget(curEdge);
      if (originalSimpleGraph.containsEdge(sourceVertex, targetVertex)) {
        DefaultWeightedEdge modifiedEdge = originalSimpleGraph.getEdge(sourceVertex, targetVertex);
        double newEdgeWeight =
            originalSimpleGraph.getEdgeWeight(modifiedEdge) + originalGraph.getEdgeWeight(curEdge);
        originalSimpleGraph.setEdgeWeight(modifiedEdge, newEdgeWeight);
      } else {
        DefaultWeightedEdge newEdge = new DefaultWeightedEdge();
        originalSimpleGraph.addEdge(sourceVertex, targetVertex, newEdge);
        originalSimpleGraph.setEdgeWeight(newEdge, originalGraph.getEdgeWeight(curEdge));
      }
    }
    // Issue (2010/10/25): Maybe larger amount of active power transfer still means weaker
    // relationship between the two terminal buses of a certain branch,
    // thus originalSimpleGraph other than inverseGraph should be used here.
    // Use the inverse of active power to build a new weighted directed graph (the larger the active
    // power is, the close the two buses will be)
    //		SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> inverseGraph =
    //			new SimpleDirectedWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class);
    //		for (String curVertex : originalSimpleGraph.vertexSet())
    //			inverseGraph.addVertex(curVertex);
    //		for (DefaultWeightedEdge curEdge : originalSimpleGraph.edgeSet()) {
    //			String sourceVertex = originalSimpleGraph.getEdgeSource(curEdge);
    //			String targetVertex = originalSimpleGraph.getEdgeTarget(curEdge);
    //			DefaultWeightedEdge newEdge = new DefaultWeightedEdge();
    //			inverseGraph.addEdge(sourceVertex, targetVertex, newEdge);
    //			inverseGraph.setEdgeWeight(newEdge, 1 / originalSimpleGraph.getEdgeWeight(curEdge));
    //		}
    // 2. Initialize the map of vertices and the corresponding weights (distance from current vertex
    // to the first vertex)
    HashMap<String, Double> mapVertexShortestDistance = new HashMap<String, Double>();
    //		for (String thisOriginalVertex : inverseGraph.vertexSet())
    for (String thisOriginalVertex : originalSimpleGraph.vertexSet())
      mapVertexShortestDistance.put(thisOriginalVertex, 10E10);
    // The weight of the first vertex is zero
    mapVertexShortestDistance.put(thisVertex, 0.0);

    // 3. Depth-first traversing, update the shortest-path values
    Stack<String> bfiVertices =
        new Stack<String>(); // Stack to store passed vertices in a breadth-first traversing
    // The map of a weighted edge and the flag of having been visited
    //		HashMap<DefaultWeightedEdge, Boolean> mapEdgeVisited = new HashMap<DefaultWeightedEdge,
    // Boolean>();
    //		for (DefaultWeightedEdge thisEdge : inverseGraph.edgeSet())
    //			mapEdgeVisited.put(thisEdge, false);
    String currentVertex = thisVertex;
    bfiVertices.push(currentVertex);
    //		System.out.println(bfiVertices.toString());
    while (!bfiVertices.isEmpty()) {
      // Operate the following codes for those edges started with current vertex
      boolean hasNewEdge = false;
      //			for (DefaultWeightedEdge curEdge : inverseGraph.outgoingEdgesOf(currentVertex)) {
      for (DefaultWeightedEdge curEdge : originalSimpleGraph.edgesOf(currentVertex)) {
        //				if (!mapEdgeVisited.get(curEdge)) {	// Used for those edges that have not been treated
        // yet
        // 3.1. Mark current edge as already been visited
        //					mapEdgeVisited.put(curEdge, true);
        //				String nextVertex = inverseGraph.getEdgeTarget(curEdge);
        String nextVertex = originalSimpleGraph.getEdgeTarget(curEdge);
        // 3.2. Update shortest-path values
        double curSD = mapVertexShortestDistance.get(currentVertex);
        //					double edgeWeight = inverseGraph.getEdgeWeight(curEdge);
        double edgeWeight = originalSimpleGraph.getEdgeWeight(curEdge);
        double newSD = curSD + edgeWeight;
        if (mapVertexShortestDistance.get(nextVertex) > newSD) {
          hasNewEdge = true;
          mapVertexShortestDistance.put(nextVertex, newSD);
          // 3.3. Push the target vertex of current edge into the stack
          bfiVertices.push(nextVertex);
          //						System.out.println(bfiVertices.toString());
          break;
          //						System.out.println("New shortest path [" + nextVertex + "]: " + newSD);
        }
        //				}
      }
      if (!hasNewEdge) {
        bfiVertices.pop();
      }
      if (!bfiVertices.isEmpty()) currentVertex = bfiVertices.peek();
    }
    // 4. Create shortest-path digraph of current vertex
    // 4.1. Initialize the shortest-path digraph
    Multigraph<String, DefaultEdge> shortestPathGraph =
        new Multigraph<String, DefaultEdge>(DefaultEdge.class);
    // 4.2. Add all qualified edges
    //		for (DefaultWeightedEdge curEdge : inverseGraph.edgeSet()) {
    for (DefaultWeightedEdge curEdge : originalSimpleGraph.edgeSet()) {
      // 4.2.1. Evaluate if current edge is suitable
      //			String sourceVertex = inverseGraph.getEdgeSource(curEdge);
      //			String targetVertex = inverseGraph.getEdgeTarget(curEdge);
      String sourceVertex = originalSimpleGraph.getEdgeSource(curEdge);
      String targetVertex = originalSimpleGraph.getEdgeTarget(curEdge);
      //			if (Math.abs(inverseGraph.getEdgeWeight(curEdge) -
      if (originalSimpleGraph.getEdgeWeight(curEdge) > 1.0E-5) {
        if (Math.abs(
                originalSimpleGraph.getEdgeWeight(curEdge)
                    - (mapVertexShortestDistance.get(targetVertex)
                        - mapVertexShortestDistance.get(sourceVertex)))
            < 1.0E-5) {
          // 4.2.2. Add suitable edge that found just now
          DefaultEdge newEdge = new DefaultEdge();
          if (!shortestPathGraph.containsVertex(sourceVertex))
            shortestPathGraph.addVertex(sourceVertex);
          if (!shortestPathGraph.containsVertex(targetVertex))
            shortestPathGraph.addVertex(targetVertex);
          shortestPathGraph.addEdge(sourceVertex, targetVertex, newEdge);
        }
      }
    }
    return shortestPathGraph;
  }
  public EdgeBetweennessGraph(WeightedMultigraph<String, DefaultWeightedEdge> originalGraph) {
    super(DefaultWeightedEdge.class); // Constructor inherented from parent class

    // 1. Initialize the edge betweenness digraph
    // 1.1. Add vertices
    for (String thisVertex : originalGraph.vertexSet()) this.addVertex(thisVertex);
    // 1.2. Add edges
    for (DefaultWeightedEdge thisEdge : originalGraph.edgeSet()) {
      DefaultWeightedEdge newEdge = new DefaultWeightedEdge();
      String sendingName = originalGraph.getEdgeSource(thisEdge);
      String receivingName = originalGraph.getEdgeTarget(thisEdge);
      this.addEdge(sendingName, receivingName, newEdge);
      this.setEdgeWeight(newEdge, 0.0);
    }
    // 1.3. Create corresponding unweighted graph
    // 1.3.1. Add vertices
    WeightedMultigraph<String, DefaultWeightedEdge> originalUnweightedGraph =
        new WeightedMultigraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class);
    for (String thisVertex : originalGraph.vertexSet())
      originalUnweightedGraph.addVertex(thisVertex);
    // 1.3.2. Add edges
    for (DefaultWeightedEdge thisEdge : originalGraph.edgeSet()) {
      DefaultWeightedEdge newEdge = new DefaultWeightedEdge();
      String sendingName = originalGraph.getEdgeSource(thisEdge);
      String receivingName = originalGraph.getEdgeTarget(thisEdge);
      originalUnweightedGraph.addEdge(sendingName, receivingName, newEdge);
      originalUnweightedGraph.setEdgeWeight(newEdge, 1.0);
    }

    for (String thisVertex : this.vertexSet()) {
      // 2. Create shortest-path graph for every vertex by Dijkstra algorithm
      Multigraph<String, DefaultEdge> shortestPathDigraph =
          DijkstraAlgorithm(originalUnweightedGraph, thisVertex);

      // 3. Calculate the contribution of current vertex's shortest-path graph to final edge
      // betweenness (Newman algorithm)
      SimpleWeightedGraph<String, DefaultWeightedEdge> edgeBetweennessDigraph =
          NewmanAlgorithm(shortestPathDigraph, thisVertex);

      // 4. Update final edge betweenness digraph with current vertex's shortest-path graph
      if (edgeBetweennessDigraph != null)
        for (DefaultWeightedEdge thisEdge : edgeBetweennessDigraph.edgeSet()) {
          String sourceVertex = edgeBetweennessDigraph.getEdgeSource(thisEdge);
          String targetVertex = edgeBetweennessDigraph.getEdgeTarget(thisEdge);
          double betweennessWeight = edgeBetweennessDigraph.getEdgeWeight(thisEdge);
          DefaultWeightedEdge edgeInWholeGraph = this.getEdge(sourceVertex, targetVertex);
          double newWeight = this.getEdgeWeight(edgeInWholeGraph) + betweennessWeight;
          this.setEdgeWeight(edgeInWholeGraph, newWeight);
        }
    }

    // 5. Revise the edge betweenness digraph with the original active power digraph
    for (DefaultWeightedEdge thisEdge : this.edgeSet()) {
      String sourceVertex = this.getEdgeSource(thisEdge);
      String targetVertex = this.getEdgeTarget(thisEdge);
      double betweennessWeight = this.getEdgeWeight(thisEdge);
      DefaultWeightedEdge edgeInWholeGraph = originalGraph.getEdge(sourceVertex, targetVertex);
      double newWeight = betweennessWeight / originalGraph.getEdgeWeight(edgeInWholeGraph);
      this.setEdgeWeight(thisEdge, newWeight);
      //			System.out.println("Final edge betweenness between " + sourceVertex + " and " +
      // targetVertex + ": " + newWeight);
    }
  }
  // Calculate the contribution of current vertex's shortest-path graph to final edge betweenness
  // (Newman algorithm)
  // M. E. J. Newman and M. Girvan, Finding and evaluating community structure in networks, Physical
  // Review E69, 026113 (2004)
  private SimpleWeightedGraph<String, DefaultWeightedEdge> NewmanAlgorithm(
      Multigraph<String, DefaultEdge> shortestPathGraph, String thisVertex) {

    if (shortestPathGraph.edgeSet().size() == 0) // No outer degree
    return null;

    // 1. Initialize the edge betweenness digraph
    SimpleWeightedGraph<String, DefaultWeightedEdge> edgeBetweennessDigraph =
        new SimpleWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class);
    // Add vertices
    for (String curVertex : shortestPathGraph.vertexSet())
      edgeBetweennessDigraph.addVertex(curVertex);

    // 2. Deal with corresponding edges
    // 2.1. Calculate vertex distance and weight
    // 2.1.1. Initialize related variables
    HashMap<String, Integer> mapVertexDistance = new HashMap<String, Integer>(); // Vertex distance
    for (String curVertex : shortestPathGraph.vertexSet()) mapVertexDistance.put(curVertex, 0);
    HashMap<String, Double> mapVertexWeight = new HashMap<String, Double>(); // Vertex weight
    for (String curVertex : shortestPathGraph.vertexSet()) mapVertexWeight.put(curVertex, 1.0);
    Queue<String> verticesQueue = new LinkedList<String>(); // Store the queue of operated vertices
    // 2.1.2. Traverse the shortest-path digraph, get corresponding vertex distance and weight
    verticesQueue.add(thisVertex);
    String currentVertex = thisVertex;
    while (!verticesQueue.isEmpty()) {
      // 2.1.2.1. Read the bottom vertex in the queue, deal with all adjacent edges
      for (DefaultEdge curEdge : shortestPathGraph.edgesOf(currentVertex)) {
        String targetVertex = shortestPathGraph.getEdgeTarget(curEdge);
        if (mapVertexDistance.get(targetVertex)
            == 0) { // Target vertex value hasn't been evaluated yet
          mapVertexDistance.put(targetVertex, mapVertexDistance.get(currentVertex) + 1);
          mapVertexWeight.put(targetVertex, mapVertexWeight.get(currentVertex));
          verticesQueue.add(targetVertex);
        }
        // Target vertex value has already been set to source vertex distance plus 1
        else if (mapVertexDistance.get(targetVertex) == (mapVertexDistance.get(currentVertex) + 1))
          mapVertexWeight.put(
              targetVertex, mapVertexWeight.get(targetVertex) + mapVertexWeight.get(currentVertex));
      }
      // 2.1.2.2. All adjacent edges have been treated, remove the bottom element
      verticesQueue.remove();
      currentVertex = verticesQueue.peek();
    }

    // 2.2. Calculate the contribution of every edges to the edge betweenness
    // 2.2.1. Sort the vertices descendingly by the distance to the first vertex
    List<Map.Entry<String, Integer>> listVertexDistance =
        new ArrayList<Map.Entry<String, Integer>>(mapVertexDistance.entrySet());
    Collections.sort(
        listVertexDistance,
        new Comparator<Map.Entry<String, Integer>>() { // Sorting the list descendingly

          @Override
          public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
            return (o2.getValue().compareTo(o1.getValue()));
          }
        });
    // 2.2.2. Traverse the shortest-path digraph with the sorted vertices list
    for (Map.Entry<String, Integer> thisVertexDistance : listVertexDistance) {
      currentVertex = thisVertexDistance.getKey();
      for (DefaultEdge curEdge : shortestPathGraph.edgesOf(currentVertex)) {
        // 2.2.2.1. Get the source vertex
        String sourceVertex = shortestPathGraph.getEdgeSource(curEdge);
        String targetVertex = shortestPathGraph.getEdgeTarget(curEdge);
        String anotherVertex = "";
        if (currentVertex.equals(sourceVertex)) anotherVertex = targetVertex;
        else if (currentVertex.equals(targetVertex)) anotherVertex = sourceVertex;
        // 2.2.2.2. Calculate the value of the sum of all adjacent edges plus 1
        double totalSubWeights = 1.0;
        for (DefaultWeightedEdge curSubEdge : edgeBetweennessDigraph.edgesOf(currentVertex))
          totalSubWeights += edgeBetweennessDigraph.getEdgeWeight(curSubEdge);
        // 2.2.2.3. The new edge weight is calculated as totalSubWeights * (the quotient of the
        // weights of the two terminals)
        double wi = mapVertexWeight.get(anotherVertex);
        double wj = mapVertexWeight.get(currentVertex);
        totalSubWeights /= wi / wj;
        // 2.2.2.4. Add new edge with correct weight into the edge betweenness digraph
        DefaultWeightedEdge newEdge = new DefaultWeightedEdge();
        edgeBetweennessDigraph.addEdge(anotherVertex, currentVertex, newEdge);
        edgeBetweennessDigraph.setEdgeWeight(newEdge, totalSubWeights);
      }
    }

    return edgeBetweennessDigraph;
  }
 /**
  * Insert a vertex to the graph whose row and col coordinates are as given.
  *
  * @param row
  * @param col
  */
 private void addVertexAt(int row, int col) {
   g.addVertex(cellContainer[row][col]);
   addEdges(row, col);
 }
  /**
   * Simulate next step for the given particle.
   *
   * @param nextPts
   * @param particleNum
   */
  public void simulateForwardStep(ArrayList<Point> nextPts, Particle thisParticle) {
    HashMap<Vertex, Point> thisObservedPosMap = new HashMap<Vertex, Point>();
    HashMap<Vertex, AntPath> thisAntPathMap = new HashMap<Vertex, AntPath>();

    thisParticle.currentFalsePositives = new ArrayList<Point>();
    for (Point pt : nextPts) {
      Vertex vx = new ObsVertex();
      thisObservedPosMap.put(vx, pt);
    }

    for (AntPath ap : thisParticle.getPaths()) {
      Vertex vx = new PathVertex();
      thisAntPathMap.put(vx, ap);
    }

    /*
     * Compute probability graph for this particle.
     */
    SimpleWeightedGraph<Vertex, DefaultWeightedComparableEdge> probabilityGraph =
        new SimpleWeightedGraph<Vertex, DefaultWeightedComparableEdge>(
            DefaultWeightedComparableEdge.class);
    ValueSortedMap<DefaultWeightedComparableEdge, Double> edgeMap =
        new ValueSortedMap<DefaultWeightedComparableEdge, Double>(true);
    computeLogProbabilityGraph(probabilityGraph, edgeMap, thisObservedPosMap, thisAntPathMap);

    //		displayLogProbabilityGraph(probabilityGraph,thisObservedPosMap,thisAntPathMap,vertexSums);

    /*
     * Generate new ant locations based on probability graph.  We do this by sampling the most likely event,
     * removing this event from the probability graph, updating the prob. graph, then repeating until all
     * observations/causes are accounted for.
     *
     * To do this (relatively) efficiently, we maintain a sorted hash-map of possible observation/cause pairs.
     * To avoid having to rescale the entire hash-map every step, we maintain the current sum of weights.
     *
     * We're also keeping track of the posterior log-probability of the simulated step.
     */

    double logprob = 0;
    int nfp = 0;
    int nfn = 0;

    int doOutput = 0;
    while (edgeMap.size() > 0) {

      /*
       * Sample an event from the probability graph.
       */

      DefaultWeightedComparableEdge event = sampleEdge(probabilityGraph, edgeMap);

      edgeMap.remove(event);
      double edgeWeight = probabilityGraph.getEdgeWeight(event);
      double thisLogProb = edgeWeight;
      logprob = logprob + thisLogProb;

      Vertex v1 = probabilityGraph.getEdgeSource(event);
      Vertex v2 = probabilityGraph.getEdgeTarget(event);

      if (doOutput > 0) {
        System.err.println("edgeWeight: " + edgeWeight);
        doOutput = outputInterestingStuff(v1, v2, probabilityGraph);
      }

      if (v1.getClass().equals(ObsVertex.class)) {
        assert (v2.getClass().equals(PathVertex.class));
        Vertex tv = v1;
        v1 = v2;
        v2 = tv;
      }

      /*
       * Update the probability graph.
       */
      if (!v1.equals(falsePositive)) {
        Set<DefaultWeightedComparableEdge> es = probabilityGraph.edgesOf(v1);
        for (DefaultWeightedComparableEdge ed : es) edgeMap.remove(ed);
        boolean tt = probabilityGraph.removeVertex(v1);
        assert (tt);
      } else {
        nfp += 1;
        thisParticle.currentFalsePositives.add(thisObservedPosMap.get(v2));
      }

      if (!v2.equals(falseNegative)) {
        Set<DefaultWeightedComparableEdge> es = probabilityGraph.edgesOf(v2);
        for (DefaultWeightedComparableEdge ed : es) edgeMap.remove(ed);
        boolean tt = probabilityGraph.removeVertex(v2);
        assert (tt);
      } else nfn += 1;

      // Utils.computeVertexSums(probabilityGraph,vertexSums);

      /*
       * Update AntPath trajectory.
       */

      if (!v1.equals(falsePositive)) {
        AntPath ap = thisAntPathMap.get(v1);
        assert (ap != null);
        Point obs = thisObservedPosMap.get(v2);

        Point newPos = new Point();
        double thislp = sampleConditionalPos(ap, obs, newPos) + thisLogProb;
        ap.updatePosition(newPos, obs, thislp);
      }

      /*
       * Compute likelihoods.
       */
    }
  }