Inconsistent output - Solution cost changes based on shipment id values

Hello,
I am getting inconsistent output from Jsprit. Please refer attached implementation. Only difference between input files(shipment1.txt and shipment2.txt) is that shipment ids are different. First file has shipment ids(column 3) in ascending order while other file has it in descending order.

Please help.

Regards,
Amit

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import com.graphhopper.jsprit.analysis.toolbox.GraphStreamViewer;
import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm;
import com.graphhopper.jsprit.core.algorithm.box.Jsprit;
import com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.FleetSize;
import com.graphhopper.jsprit.core.problem.job.Shipment;
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleType;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleTypeImpl;
import com.graphhopper.jsprit.core.reporting.SolutionPrinter;
import com.graphhopper.jsprit.core.util.Coordinate;
import com.graphhopper.jsprit.core.util.FastVehicleRoutingTransportCostsMatrix;
import com.graphhopper.jsprit.core.util.Solutions;

public class ValidateOutputConsistency {
private static final int EARTH_RADIUS = 6373;
private List locations = new ArrayList();
private String[] shipmentInfo = null;

private Date startDate = Date.from(Instant.parse("2019-11-20T05:30:00.00Z"));
private Date endDate = Date.from(Instant.parse("2019-11-20T13:30:00.00Z"));

public String getLocationIndex(String location) {
	if (!locations.contains(location)) {
		locations.add(location);
	}

	return Integer.toString(locations.indexOf(location));
}

public void addShipments(VehicleRoutingProblem.Builder vrpBuilder, String filename) {

	try {
		BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));

		String line;
		boolean firstLine = true;
		while ((line = reader.readLine()) != null) {
			if (firstLine) {
				firstLine = false;
				continue;
			}

			String[] lineTokens = line.split("\\|");
			shipmentInfo = lineTokens;

			vrpBuilder.addJob(
					Shipment.Builder.newInstance(lineTokens[2]).addSizeDimension(1, Integer.parseInt(lineTokens[4]))
							.setPickupLocation(setupLocationData(getLocationIndex(lineTokens[1]), lineTokens[1]))
							.setDeliveryLocation(setupLocationData(getLocationIndex(lineTokens[3]), lineTokens[3]))
							.setName(lineTokens[2]).setDeliveryServiceTime(1200000L).setPickupServiceTime(600000L)
							.setPickupTimeWindow(new TimeWindow(startDate.getTime(), endDate.getTime()))
							.setDeliveryTimeWindow(new TimeWindow(startDate.getTime(), endDate.getTime())).build());

		}
		reader.close();

	} catch (NumberFormatException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

public void simulte(String fileName) {
	VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();

	addShipments(vrpBuilder, fileName);

	vrpBuilder.setRoutingCost(generateDistanceMatrix());

	List<VehicleImpl> vehicleList = getVehicleList(vrpBuilder, shipmentInfo[1]);
	int noOfVehicles = vehicleList.size();

	vrpBuilder.setFleetSize(FleetSize.FINITE);

	for (int i = 0; i < noOfVehicles; i++) {
		vrpBuilder.addVehicle(vehicleList.get(i));
	}

	// build problem
	VehicleRoutingProblem vrp = vrpBuilder.build();

	VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);

	Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();

	VehicleRoutingProblemSolution best = Solutions.bestOf(solutions);

	SolutionPrinter.print(vrp, best, SolutionPrinter.Print.VERBOSE);

	new GraphStreamViewer(vrp, best).setRenderDelay(100).display();

}

public List<VehicleImpl> getVehicleList(VehicleRoutingProblem.Builder vrpBuilder, String vehicleLocation) {
	List<VehicleImpl> vehicles = new ArrayList<VehicleImpl>();

	VehicleType type1 = VehicleTypeImpl.Builder.newInstance("6").addCapacityDimension(1, 8500)
			.setCostPerDistance(15.4).setMaxVelocity((18 * 1000 / 3600)).setFixedCost(1900).build();
	VehicleImpl vehicle1_1 = VehicleImpl.Builder.newInstance("KA04AB0001")
			.setStartLocation(setupLocationData(getLocationIndex(vehicleLocation), vehicleLocation)).setType(type1)
			.setEarliestStart(startDate.getTime()).setLatestArrival(endDate.getTime()).setReturnToDepot(true)
			.build();
	VehicleImpl vehicle1_2 = VehicleImpl.Builder.newInstance("KA04AB0002")
			.setStartLocation(setupLocationData(getLocationIndex(vehicleLocation), vehicleLocation)).setType(type1)
			.setEarliestStart(startDate.getTime()).setLatestArrival(endDate.getTime()).setReturnToDepot(true)
			.build();

	VehicleType type2 = VehicleTypeImpl.Builder.newInstance("5").addCapacityDimension(1, 6600)
			.setCostPerDistance(12.6).setMaxVelocity((18 * 1000 / 3600)).setFixedCost(1500).build();
	VehicleImpl vehicle2_1 = VehicleImpl.Builder.newInstance("KA04AB0003")
			.setStartLocation(setupLocationData(getLocationIndex(vehicleLocation), vehicleLocation)).setType(type2)
			.setEarliestStart(startDate.getTime()).setLatestArrival(endDate.getTime()).setReturnToDepot(true)
			.build();

	VehicleType type3 = VehicleTypeImpl.Builder.newInstance("4").addCapacityDimension(1, 4600)
			.setCostPerDistance(9.8).setMaxVelocity((20 * 1000 / 3600)).setFixedCost(1100).build();
	VehicleImpl vehicle3_1 = VehicleImpl.Builder.newInstance("KA04AB0004")
			.setStartLocation(setupLocationData(getLocationIndex(vehicleLocation), vehicleLocation)).setType(type3)
			.setEarliestStart(startDate.getTime()).setLatestArrival(endDate.getTime()).setReturnToDepot(true)
			.build();

	VehicleType type4 = VehicleTypeImpl.Builder.newInstance("11").addCapacityDimension(1, 5100)
			.setCostPerDistance(10.2).setMaxVelocity((20 * 1000 / 3600)).setFixedCost(1300).build();
	VehicleImpl vehicle4_1 = VehicleImpl.Builder.newInstance("KA04AB0005")
			.setStartLocation(setupLocationData(getLocationIndex(vehicleLocation), vehicleLocation)).setType(type4)
			.setEarliestStart(startDate.getTime()).setLatestArrival(endDate.getTime()).setReturnToDepot(true)
			.build();

	VehicleType type5 = VehicleTypeImpl.Builder.newInstance("10").addCapacityDimension(1, 10700)
			.setCostPerDistance(18.2).setMaxVelocity((18 * 1000 / 3600)).setFixedCost(2100).build();
	VehicleImpl vehicle5_1 = VehicleImpl.Builder.newInstance("KA04AB0006")
			.setStartLocation(setupLocationData(getLocationIndex(vehicleLocation), vehicleLocation)).setType(type5)
			.setEarliestStart(startDate.getTime()).setLatestArrival(endDate.getTime()).setReturnToDepot(true)
			.build();

	vehicles.add(vehicle1_1);
	vehicles.add(vehicle1_2);
	vehicles.add(vehicle2_1);
	vehicles.add(vehicle3_1);
	vehicles.add(vehicle4_1);
	vehicles.add(vehicle5_1);

	return vehicles;
}

private Location setupLocationData(String id, String latLong) {
	String[] array = latLong.split(",");
	Double lattitude = Double.parseDouble(array[0]);
	Double Longitude = Double.parseDouble(array[1]);

	Location.Builder locBuilder = Location.Builder.newInstance();
	Coordinate coordinate = Coordinate.newInstance(lattitude, Longitude);
	locBuilder.setIndex(Integer.parseInt(id)).setCoordinate(coordinate);
	return locBuilder.build();

}

public FastVehicleRoutingTransportCostsMatrix generateDistanceMatrix() {
	FastVehicleRoutingTransportCostsMatrix.Builder fastCostMatrix = FastVehicleRoutingTransportCostsMatrix.Builder
			.newInstance(locations.size(), true);
	double travelDistance, travelTimeInMilliSeconds;

	String[] sourceLocation, destinationLocation;

	for (int i = 0; i < locations.size(); i++) {
		sourceLocation = locations.get(i).split(",");
		for (int j = 0; j < locations.size(); j++) {
			destinationLocation = locations.get(j).split(",");

			travelDistance = getDistance(Double.parseDouble(sourceLocation[0]),
					Double.parseDouble(sourceLocation[1]), Double.parseDouble(destinationLocation[0]),
					Double.parseDouble(destinationLocation[1]));

			travelTimeInMilliSeconds = (travelDistance / 18) * 3600000;

			fastCostMatrix.addTransportTimeAndDistance(i, j, travelTimeInMilliSeconds, travelDistance);
		}
	}

	FastVehicleRoutingTransportCostsMatrix fastRoutingCostMatrix = fastCostMatrix.build();

	return fastRoutingCostMatrix;
}

private double getDistance(double startLat, double startLong, double endLat, double endLong) {
	double dLat = Math.toRadians((endLat - startLat));
	double dLong = Math.toRadians((endLong - startLong));

	startLat = Math.toRadians(startLat);
	endLat = Math.toRadians(endLat);

	double a = haversin(dLat) + Math.cos(startLat) * Math.cos(endLat) * haversin(dLong);
	double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

	return EARTH_RADIUS * c;
}

private double haversin(double val) {
	return Math.pow(Math.sin(val / 2), 2);
}

public static void main(String[] args) {
	ValidateOutputConsistency validateOutputConsistency = new ValidateOutputConsistency();

	validateOutputConsistency.simulte("input/shipments1.txt");

	validateOutputConsistency.simulte("input/shipments2.txt");

}

}

------------------------- shipments1.txt ----------------------------------
pickupId|pickupLocation|deliveryId|deliveryLocation|deliveryLoad
0|13.116723,77.425265|1|12.963563,77.578063|195
0|13.116723,77.425266|2|13.030188,77.530438|1516
0|13.116723,77.425267|3|12.975313,77.625313|187
0|13.116723,77.425268|4|12.991969,77.507181|227
0|13.116723,77.425269|5|13.042188,77.750688|1381
0|13.116723,77.425270|6|13.031118,77.666935|415
0|13.116723,77.425271|7|12.983813,77.546563|762
0|13.116723,77.425272|8|13.032563,77.608813|852
0|13.116723,77.425273|9|12.965063,77.590688|291
0|13.116723,77.425274|10|12.962994,77.517945|38
0|13.116723,77.425275|11|12.984982,77.553344|109
0|13.116723,77.425276|12|12.964957,77.578995|569
0|13.116723,77.425277|13|13.030438,77.608313|1852
0|13.116723,77.425278|14|12.956093,77.592145|311
0|13.116723,77.425279|15|12.950313,77.546313|1339
0|13.116723,77.425280|16|12.965624,77.578953|30
0|13.116723,77.425281|17|12.965188,77.579313|170
0|13.116723,77.425282|18|13.054188,77.577188|2222
0|13.116723,77.425283|19|12.97035,77.543375|477
0|13.116723,77.425284|20|12.962938,77.592313|373
0|13.116723,77.425285|21|12.960547,77.590941|713
0|13.116723,77.425286|22|12.965171,77.579103|611
0|13.116723,77.425287|23|12.987813,77.475938|1628
0|13.116723,77.425288|24|12.990278,77.579018|2319
0|13.116723,77.425289|25|12.984813,77.484063|3183
0|13.116723,77.425290|26|12.959336,77.588149|501
0|13.116723,77.425291|27|12.958563,77.538563|991
0|13.116723,77.425292|28|13.025188,77.613063|738
0|13.116723,77.425293|29|13.004688,77.560188|887
0|13.116723,77.425294|30|12.965813,77.636563|1667
0|13.116723,77.425295|31|12.953813,77.707688|1495
0|13.116723,77.425296|32|12.991563,77.692063|3289
0|13.116723,77.425297|33|12.956989,77.563733|1963
0|13.116723,77.425298|34|12.988688,77.602563|340
0|13.116723,77.425299|35|12.969313,77.573063|272

------------------------------ shipments2.txt ----------------------------------
pickupId|pickupLocation|deliveryId|deliveryLocation|deliveryLoad
0|13.116723,77.425265|35|12.963563,77.578063|195
0|13.116723,77.425266|34|13.030188,77.530438|1516
0|13.116723,77.425267|33|12.975313,77.625313|187
0|13.116723,77.425268|32|12.991969,77.507181|227
0|13.116723,77.425269|31|13.042188,77.750688|1381
0|13.116723,77.425270|30|13.031118,77.666935|415
0|13.116723,77.425271|29|12.983813,77.546563|762
0|13.116723,77.425272|28|13.032563,77.608813|852
0|13.116723,77.425273|27|12.965063,77.590688|291
0|13.116723,77.425274|26|12.962994,77.517945|38
0|13.116723,77.425275|25|12.984982,77.553344|109
0|13.116723,77.425276|24|12.964957,77.578995|569
0|13.116723,77.425277|23|13.030438,77.608313|1852
0|13.116723,77.425278|22|12.956093,77.592145|311
0|13.116723,77.425279|21|12.950313,77.546313|1339
0|13.116723,77.425280|20|12.965624,77.578953|30
0|13.116723,77.425281|19|12.965188,77.579313|170
0|13.116723,77.425282|18|13.054188,77.577188|2222
0|13.116723,77.425283|17|12.97035,77.543375|477
0|13.116723,77.425284|16|12.962938,77.592313|373
0|13.116723,77.425285|15|12.960547,77.590941|713
0|13.116723,77.425286|14|12.965171,77.579103|611
0|13.116723,77.425287|13|12.987813,77.475938|1628
0|13.116723,77.425288|12|12.990278,77.579018|2319
0|13.116723,77.425289|11|12.984813,77.484063|3183
0|13.116723,77.425290|10|12.959336,77.588149|501
0|13.116723,77.425291|9|12.958563,77.538563|991
0|13.116723,77.425292|8|13.025188,77.613063|738
0|13.116723,77.425293|7|13.004688,77.560188|887
0|13.116723,77.425294|6|12.965813,77.636563|1667
0|13.116723,77.425295|5|12.953813,77.707688|1495
0|13.116723,77.425296|4|12.991563,77.692063|3289
0|13.116723,77.425297|3|12.956989,77.563733|1963
0|13.116723,77.425298|2|12.988688,77.602563|340
0|13.116723,77.425299|1|12.969313,77.573063|272

@stefan,@grantm009,@jie31best Can you please let me know your thoughts on this ?

Regards,
Amit