private double percentCorrect(Map<String, String> policy, boolean weighted) {
    int numTested = 0;
    int numCorrect = 0;
    for (String key : groundTruth.vertexSet()) {
      if (key.equals("0")) continue;

      if (groundTruth.getOutgoing(key).size() == 0) continue;

      String guess = policy.get(key);
      int weight = weighted ? countMap.get(key) : 1;
      if (groundTruth.getOutgoing(key).contains(guess)) {
        numCorrect += weight;
      }
      numTested += weight;
    }
    System.out.println("(" + numTested + ")");
    return 100.0 * numCorrect / numTested;
  }
  private void run() {
    FileSystem.setAssnId(MAIN_ASSN_ID);
    DirectedGraph<String> p1 = GraphLoader.loadPolicy("nodeRank.txt");
    DirectedGraph<String> p2 = GraphLoader.loadPolicy("nodeRank6.txt");

    Set<String> verticies = new HashSet<String>();
    verticies.addAll(p1.vertexSet());
    verticies.addAll(p2.vertexSet());
    ArrayList<Integer> idSet = new ArrayList<Integer>();
    for (String s : verticies) {
      int id = Integer.parseInt(s);
      idSet.add(id);
    }
    Collections.sort(idSet);
    List<String> sortedList = new ArrayList<String>();
    for (int s : idSet) {
      sortedList.add("" + s);
    }

    for (String v : sortedList) {
      if (Integer.parseInt(v) > 100) continue;

      if (!p1.containsVertex(v)) {
        System.out.println("p1 missing: " + v);
      }
      if (!p2.containsVertex(v)) {
        System.out.println("p2 missing: " + v);
      }

      String n1 = getNext(p1, v);
      String n2 = getNext(p2, v);

      if (!n1.equals(n2)) {
        System.out.println("diff " + v + ":\t" + n1 + "\t" + n2);
      }
    }
  }
  public void run() {
    System.out.println("markov 0");
    // Get the number of students who visit each node.
    List<Trajectory> trajectories = TrajectoryLoader.load(TRAJECTORY_DIR);
    System.out.println("next");
    Map<String, Integer> nodeCount = new HashMap<String, Integer>();
    for (Trajectory t : trajectories) {
      List<String> visited = t.getProgramIds();
      List<String> noCycle = new ArrayList<String>();
      for (int i = 0; i < visited.size(); i++) {
        String state = visited.get(i);
        noCycle.add(state);
        int lastIndex = visited.lastIndexOf(state);
        i = lastIndex;
      }

      for (String v : noCycle) {
        if (!nodeCount.containsKey(v)) {
          nodeCount.put(v, 0);
        }
        int newCount = nodeCount.get(v) + t.getCount();
        nodeCount.put(v, newCount);
      }
    }
    double sumCount = 0.0;
    for (String s : nodeCount.keySet()) {
      sumCount += nodeCount.get(s);
    }
    roadMap = GraphLoader.loadRoadMap();
    groundTruth = GraphLoader.loadGroundTruth();

    // Make a graph where each edge has cost = coherence of the next node
    System.out.println("make coherenceCost");
    DirectedGraph<String> coherenceCost = new DirectedGraph<String>();
    for (String node : roadMap.vertexSet()) {
      double count = EPSILON;
      if (nodeCount.containsKey(node)) {
        count = nodeCount.get(node);
      }

      for (String previous : roadMap.getIncoming(node)) {

        double cost = -Math.log(count / sumCount);

        coherenceCost.addEdge(previous, node, cost);
      }
    }

    // Turn it all into a prediction
    System.out.println("predict");
    DirectedGraph<String> bestNext = new DirectedGraph<String>();
    String soln = "0";

    for (String node : groundTruth.vertexSet()) {
      if (node.equals(soln)) continue;
      if (groundTruth.getOutgoing(node).size() == 0) continue;

      List<Edge<String>> path = coherenceCost.getShortestPath(node, soln);
      if (path != null) {

        Edge<String> firstEdge = path.get(0);
        String next = firstEdge.getTarget();
        bestNext.addEdge(node, next);
      }
    }

    System.out.println("connected: " + roadMap.getInConnected("0").size());
    System.out.println("node count size: " + nodeCount.size());
    System.out.println("best next size: " + bestNext.vertexSet().size());

    DirectedGraph<String> toSave = new DirectedGraph<String>();

    for (int i = 0; i < 1000; i++) {
      String node = "" + i;
      if (!bestNext.containsVertex(node)) continue;
      String next = null;
      for (String s : bestNext.getOutgoing(node)) {
        next = s;
        break;
      }
      if (next != null) {
        toSave.addEdge(node, next);
      }
    }

    GraphLoader.savePolicy(toSave, OUTPUT_FILE);

    System.out.println("done");
  }
 private String getNext(DirectedGraph<String> p, String v) {
   if (p.getOutgoing(v).isEmpty()) return "null";
   return p.getOutgoing(v).iterator().next();
 }