public void calculateTspCycle() {
    AllShortestPaths shortestPaths = new AllShortestPaths(this.graph);
    shortestPaths.compute();

    Graph augmentedGraph = shortestPaths.toDistancesGraph();

    MinimumSpanningTree minTree = new MinimumSpanningTree(augmentedGraph);

    minTree.compute();

    Graph tree = minTree.getMinimumTree();

    int oddNodes = 0;
    for (int node = 0; node < tree.getNumNodes(); node++) {
      if (tree.getOutEdges(node).size() % 2 == 1) {
        oddNodes++;
      }
    }

    System.out.println("Nodes with odd degree: " + oddNodes);

    // formar um subgrafo so com os nos ímpares
    Graph oddGraph = null;

    // emparelhar nos impares
    // OBS: nao é esse algoritmo
    // ver: http://en.wikipedia.org/wiki/Edmonds%27s_matching_algorithm
    MaximumBipartiteMatching matchingAlgorithm = new MaximumBipartiteMatching(oddGraph);

    matchingAlgorithm.compute();

    List<Edge> newEdges = matchingAlgorithm.getMatching();

    for (Edge edge : newEdges) {
      tree.addUndirectedEdge(edge.getSource(), edge.getTarget(), edge.getLength());
    }

    // formar o caminho euleriano...
    // Hierholzer's algorithm
    Path cycle = null;

    // criar os atalhos

    // trocar as arestas por caminhos do grafo original
    tspCycle = cycle.expandShortestPaths(shortestPaths);
  }