package edu.kit.pse.ws2013.routekit.precalculation; import java.io.BufferedReader; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.HashSet; import java.util.Set; import edu.kit.pse.ws2013.routekit.map.EdgeBasedGraph; /** * Provides the functionality of partitioning a graph by invoking the external * program METIS. */ public class ExternalPartitionerAdapter implements GraphPartitioner { private EdgeBasedGraph graph; @Override public void partitionGraph(EdgeBasedGraph graph, int numberOfPartitions) throws IOException { this.graph = graph; String fileName = System.getProperty("java.io.tmpdir") + "/graph"; writeGraphFile(fileName); String[] cmd = { "gpmetis", fileName, Integer.toString(numberOfPartitions) }; try { Runtime.getRuntime().exec(cmd).waitFor(); } catch (IOException | InterruptedException e) { cmd[0] = "kmetis"; try { Runtime.getRuntime().exec(cmd).waitFor(); } catch (IOException | InterruptedException f) { e.printStackTrace(); f.printStackTrace(); return; } } readPartitionFile(fileName + ".part." + String.valueOf(numberOfPartitions)); } private void writeGraphFile(String fileName) throws IOException { StringBuilder output = new StringBuilder(); output.append(graph.getNumberOfEdges()).append(' '); int turnNumberPosition = output.length(); output.append(System.lineSeparator()); int numberOfTurns = 0; for (int edge = 0; edge < graph.getNumberOfEdges(); edge++) { // Convert directed to undirected turns (graph edges) Set<Integer> edges = new HashSet<>(); for (int turn : graph.getOutgoingTurns(edge)) { edges.add(graph.getTargetEdge(turn)); } for (int turn : graph.getIncomingTurns(edge)) { edges.add(graph.getStartEdge(turn)); } numberOfTurns += edges.size(); for (int targetEdge : edges) { output.append(targetEdge + 1).append(' '); } if (!edges.isEmpty()) { // Remove trailing space output.deleteCharAt(output.length() - 1); } output.append(System.lineSeparator()); } output.insert(turnNumberPosition, numberOfTurns / 2); FileWriter writer = new FileWriter(fileName); writer.append(output); writer.close(); } private void readPartitionFile(String fileName) throws IOException { int partitions[] = new int[graph.getNumberOfEdges()]; BufferedReader reader = new BufferedReader(new FileReader(fileName)); for (int edge = 0; edge < partitions.length; edge++) { partitions[edge] = Integer.parseInt(reader.readLine()); } reader.close(); graph.setPartitions(partitions); } }