-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d390a65
commit 4fdb4f5
Showing
6 changed files
with
331 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
java-hello-world/src/main/java/com/nextmv/example/Main.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.nextmv.example; | ||
|
||
import com.google.gson.Gson; | ||
import java.io.FileReader; | ||
import java.io.IOException; | ||
import com.google.gson.JsonObject; | ||
|
||
public class Main { | ||
public static void main(String[] args) { | ||
Gson gson = new Gson(); | ||
|
||
|
||
try (FileReader reader = new FileReader("input.json")) { | ||
// Read from stdin. | ||
Input input = gson.fromJson(reader, Input.class); | ||
|
||
// ##### Insert model here | ||
|
||
// Print logs that render in the run view in Nextmv Console | ||
System.err.println("Hello, " + input.name); | ||
|
||
// Write output and statistics. | ||
Output output = new Output(input.name); | ||
Output.write(output); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
||
|
||
class Input { | ||
String name; | ||
} | ||
|
||
|
||
class Output { | ||
JsonObject options = new JsonObject(); | ||
Solution solution; | ||
Statistics statistics; | ||
|
||
public Output(String name) { | ||
this.solution = new Solution(); | ||
this.statistics = new Statistics("Hello, " + name); | ||
} | ||
|
||
public static void write(Output output) { | ||
Gson gson = new Gson(); | ||
System.out.println(gson.toJson(output)); | ||
} | ||
} | ||
|
||
class Solution {} | ||
|
||
class Statistics { | ||
String message; | ||
|
||
public Statistics(String message) { | ||
this.message = message; | ||
} | ||
} | ||
|
||
|
66 changes: 66 additions & 0 deletions
66
java-ortools-routing/src/main/java/com/nextmv/example/Input.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.nextmv.example; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.InputStreamReader; | ||
import java.util.stream.Collectors; | ||
|
||
import com.google.gson.Gson; | ||
import com.google.gson.annotations.SerializedName; | ||
|
||
public class Input { | ||
@SerializedName(value = "distance_matrix") | ||
public final long[][] distanceMatrix; | ||
@SerializedName(value = "num_vehicles") | ||
public final int vehicleNumber; | ||
public final int depot; | ||
|
||
public Input(int vehicleNumber, int depot, long[][] distanceMatrix) { | ||
this.distanceMatrix = new long[vehicleNumber+1][vehicleNumber+1]; | ||
this.vehicleNumber = vehicleNumber; | ||
this.depot = depot; | ||
for (int i = 0; i < vehicleNumber+1; i++) { | ||
for (int j = 0; j < vehicleNumber+1; j++) { | ||
this.distanceMatrix[i][j] = distanceMatrix[i][j]; | ||
} | ||
} | ||
} | ||
|
||
public long[][] getDistanceMatrix() { | ||
return this.distanceMatrix; | ||
} | ||
|
||
public int getVehicleNumber() { | ||
return this.vehicleNumber; | ||
} | ||
|
||
public int getDepot() { | ||
return this.depot; | ||
} | ||
|
||
public static Input fromString(String path) { | ||
Gson gson = new Gson(); | ||
// Read stdin if no path is provided. | ||
if (path.isEmpty()) { | ||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { | ||
return gson.fromJson( | ||
reader.lines().collect(Collectors.joining("\n")), Input.class | ||
); | ||
} catch (java.io.IOException e) { | ||
System.err.println("Error reading stdin: " + e.getMessage()); | ||
System.exit(1); | ||
return null; | ||
} | ||
} | ||
// Read the path otherwise. | ||
try { | ||
return gson.fromJson( | ||
java.nio.file.Files.readString(java.nio.file.Paths.get(path)), | ||
Input.class | ||
); | ||
} catch (java.io.IOException e) { | ||
System.err.println("Error reading '" + path + "': " + e.getMessage()); | ||
System.exit(1); | ||
} | ||
return null; | ||
} | ||
} |
109 changes: 109 additions & 0 deletions
109
java-ortools-routing/src/main/java/com/nextmv/example/Main.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package com.nextmv.example; | ||
|
||
import com.google.ortools.Loader; | ||
import com.google.ortools.constraintsolver.Assignment; | ||
import com.google.ortools.constraintsolver.FirstSolutionStrategy; | ||
import com.google.ortools.constraintsolver.RoutingIndexManager; | ||
import com.google.ortools.constraintsolver.RoutingModel; | ||
import com.google.ortools.constraintsolver.RoutingSearchParameters; | ||
|
||
import com.google.ortools.constraintsolver.main; | ||
import com.google.protobuf.Duration; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public final class Main { | ||
public static void main(String[] args) { | ||
// Record start time of the program. | ||
long startTime = System.currentTimeMillis(); | ||
// Parse arguments. Exit on error. | ||
Options options = Options.fromArguments(args); | ||
|
||
// Load input. Exit on error. | ||
Input input = Input.fromString(options.getInputPath()); | ||
|
||
Loader.loadNativeLibraries(); | ||
|
||
// Create Routing Index Manager. | ||
RoutingIndexManager manager = new RoutingIndexManager(input.distanceMatrix.length, input.vehicleNumber, | ||
input.depot); | ||
|
||
// Create Routing Model. | ||
RoutingModel routing = new RoutingModel(manager); | ||
|
||
// Create and register a transit callback. | ||
final int transitCallbackIndex = routing.registerTransitCallback((long fromIndex, long toIndex) -> { | ||
// Convert from routing variable Index to user NodeIndex. | ||
int fromNode = manager.indexToNode(fromIndex); | ||
int toNode = manager.indexToNode(toIndex); | ||
return input.distanceMatrix[fromNode][toNode]; | ||
}); | ||
|
||
// Define cost of each arc. | ||
routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex); | ||
|
||
// Set the duration of the search. | ||
Duration duration = Duration.newBuilder().setSeconds(options.getDuration()).build(); | ||
|
||
// Setting first solution heuristic. | ||
RoutingSearchParameters searchParameters = main.defaultRoutingSearchParameters() | ||
.toBuilder() | ||
.setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC) | ||
.setTimeLimit(duration) | ||
.build(); | ||
|
||
// Solve the problem. | ||
// Record solve start time | ||
long solveStartTime = System.currentTimeMillis(); | ||
Assignment solution = routing.solveWithParameters(searchParameters); | ||
|
||
Output output = getOutput(startTime, input, routing, manager, solution, solveStartTime); | ||
|
||
// Write output. Exit on error. | ||
Output.write(options.getOutputPath(), output); | ||
} | ||
|
||
static Output getOutput( | ||
long startTime, | ||
Input input, | ||
RoutingModel routing, | ||
RoutingIndexManager manager, | ||
Assignment solution, long solveStartTime) { | ||
long maxRouteDistance = 0; | ||
List<Vehicle> vehicles = new ArrayList<Vehicle>(); | ||
for (int i = 0; i < input.vehicleNumber; ++i) { | ||
List<Integer> stops = new ArrayList<Integer>(); | ||
long index = routing.start(i); | ||
long routeDistance = 0; | ||
while (!routing.isEnd(index)) { | ||
stops.add(manager.indexToNode(index)); | ||
long previousIndex = index; | ||
index = solution.value(routing.nextVar(index)); | ||
routeDistance += routing.getArcCostForVehicle(previousIndex, index, i); | ||
} | ||
stops.add(manager.indexToNode(index)); | ||
Vehicle vehicle = new Vehicle(i, routeDistance, stops); | ||
vehicles.add(vehicle); | ||
maxRouteDistance = Math.max(routeDistance, maxRouteDistance); | ||
} | ||
|
||
// Compute solve duration. | ||
long endTime = System.currentTimeMillis(); | ||
double duration = endTime - solveStartTime; | ||
// Convert duration to seconds. | ||
duration = duration / 1000.0; | ||
|
||
// Compute total duration. | ||
endTime = System.currentTimeMillis(); | ||
double runDuration = endTime - startTime; | ||
// Convert duration to seconds. | ||
runDuration = runDuration / 1000.0; | ||
|
||
// Create output. | ||
return new Output( | ||
vehicles, | ||
duration, | ||
runDuration); | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
java-ortools-routing/src/main/java/com/nextmv/example/Options.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.nextmv.example; | ||
|
||
public class Options { | ||
private final String inputPath; | ||
private final String outputPath; | ||
private final int duration; | ||
|
||
public Options(String inputPath, String outputPath, int duration) { | ||
this.inputPath = inputPath; | ||
this.outputPath = outputPath; | ||
this.duration = duration; | ||
} | ||
|
||
public String getInputPath() { | ||
return this.inputPath; | ||
} | ||
|
||
public String getOutputPath() { | ||
return this.outputPath; | ||
} | ||
|
||
public int getDuration() { | ||
return this.duration; | ||
} | ||
|
||
public static Options fromArguments(String[] args) { | ||
String inputPath = ""; | ||
String outputPath = ""; | ||
int duration = 30; | ||
|
||
for (int i = 0; i < args.length; ++i) { | ||
switch (args[i]) { | ||
case "-i": | ||
case "--input": | ||
inputPath = args[++i]; | ||
break; | ||
case "-o": | ||
case "--output": | ||
outputPath = args[++i]; | ||
break; | ||
case "-d": | ||
case "--duration": | ||
duration = Integer.parseInt(args[++i]); | ||
break; | ||
case "-h": | ||
case "--help": | ||
System.out.println("Usage: java -jar basic_example.jar [OPTIONS]"); | ||
System.out.println("Solve a simple linear program."); | ||
System.out.println(); | ||
System.out.println("Supported options:"); | ||
System.out.println(" -i, --input: path to the input file"); | ||
System.out.println(" -o, --output: path to the output file"); | ||
System.out.println(" -d, --duration: duration of the search in seconds"); | ||
System.out.println(" -h, --help: print the help"); | ||
System.exit(0); | ||
break; | ||
default: | ||
System.err.println("Unknown argument: '" + args[i] + "'"); | ||
System.exit(1); | ||
} | ||
} | ||
|
||
return new Options(inputPath, outputPath, duration); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
java-ortools-routing/src/main/java/com/nextmv/example/Vehicle.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.nextmv.example; | ||
|
||
import java.util.List; | ||
|
||
public class Vehicle { | ||
public final int vehicle; | ||
public final double distance; | ||
public final List<Integer> stops; | ||
|
||
public Vehicle(int vehicle, double distance, List<Integer> stops) { | ||
this.vehicle = vehicle; | ||
this.distance = distance; | ||
this.stops = stops; | ||
} | ||
|
||
public int getVehicle() { | ||
return this.vehicle; | ||
} | ||
|
||
public double getDistance() { | ||
return this.distance; | ||
} | ||
|
||
public List<Integer> getStops() { | ||
return this.stops; | ||
} | ||
|
||
} |