package vroom.common.heuristics.vrp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import vroom.common.heuristics.vrp.constraints.CapacityConstraint;
import vroom.common.modeling.dataModel.ListRoute.ArrayListRoute;
import vroom.common.modeling.dataModel.Depot;
import vroom.common.modeling.dataModel.Fleet;
import vroom.common.modeling.dataModel.INodeVisit;
import vroom.common.modeling.dataModel.IRoute;
import vroom.common.modeling.dataModel.Node;
import vroom.common.modeling.dataModel.NodeVisit;
import vroom.common.modeling.dataModel.Request;
import vroom.common.modeling.dataModel.Solution;
import vroom.common.modeling.dataModel.StaticInstance;
import vroom.common.modeling.dataModel.Vehicle;
import vroom.common.modeling.dataModel.attributes.DeterministicDemand;
import vroom.common.modeling.dataModel.attributes.PointLocation;
import vroom.common.modeling.dataModel.attributes.RequestAttributeKey;
import vroom.common.modeling.util.CostCalculationDelegate;
import vroom.common.modeling.util.EuclidianDistance;
import vroom.common.utilities.logging.LoggerHelper;
import vroom.common.utilities.logging.Logging;
public class TwoOptNeigbhorhoodTest {
static int numNodes = 10;
static int radius = 10;
/** Swapped nodes indexes */
static int numSwaps = 10;
ArrayListRoute route1, route2;
Solution<IRoute<INodeVisit>> solution;
CostCalculationDelegate costHelper;
List<Node> nodes1, nodes2;
Depot depot;
int id = 1;
@Before
public void setUp() throws Exception {
depot = new Depot(0, new PointLocation(radius, 0));
Vehicle v = new Vehicle(0, "TestTruc", numNodes);
costHelper = new EuclidianDistance();
solution = new Solution<IRoute<INodeVisit>>(new StaticInstance(
"TestInstance", 0, Fleet.newHomogenousFleet(1, v),
Collections.singletonList(depot), null, costHelper));
route1 = new ArrayListRoute(solution, v);
nodes1 = new ArrayList<Node>(numNodes + 2);
generateRoute(route1, nodes1, radius, v);
route2 = new ArrayListRoute(solution, v);
nodes2 = new ArrayList<Node>(numNodes + 2);
generateRoute(route2, nodes2, 2 * radius, v);
solution.addRoute(route1);
solution.addRoute(route2);
System.out.println("Node sequences:");
System.out.println(nodes1);
System.out.println(nodes2);
System.out.println("Routes:");
System.out.println(route1);
System.out.println(route2);
System.out.println("Solution:");
System.out.println(solution);
}
/**
* Generate a route
*
* @param r
* @param nodes
* @param rte
* @return
*/
protected void generateRoute(ArrayListRoute rte, List<Node> nodes, int r,
Vehicle v) {
nodes.add(depot);
rte.appendNode(new NodeVisit(depot));
for (int n = 1; n <= numNodes; n++) {
double x = r * Math.cos(2 * Math.PI * n / (numNodes + 1));
double y = r * Math.sin(2 * Math.PI * n / (numNodes + 1));
Node node = new Node(id, new PointLocation(x, y));
nodes.add(node);
for (NodeVisit nv : NodeVisit
.createNodeVisits(new Request(id, node))) {
nv.getParentRequest().setAttribute(RequestAttributeKey.DEMAND,
new DeterministicDemand(1));
rte.appendNode(nv);
}
id++;
}
nodes.add(depot);
rte.appendNode(new NodeVisit(depot));
}
protected Solution<IRoute<INodeVisit>> scrambleSolution(
Solution<IRoute<INodeVisit>> solution) {
Solution<IRoute<INodeVisit>> scrambledSolution = solution.clone();
Random r = new Random(0);
for (int i = 0; i < numSwaps; i++) {
int r1 = r.nextInt(solution.getRouteCount());
int r2 = r.nextInt(solution.getRouteCount());
int k = r.nextInt(solution.getRoute(r1).length() - 2) + 1;
int l = r.nextInt(solution.getRoute(r2).length() - 2) + 1;
INodeVisit n1 = scrambledSolution.getRoute(r1).extractNode(k);
INodeVisit n2 = scrambledSolution.getRoute(r2).extractNode(l);
scrambledSolution.getRoute(r2).insertNode(l, n1);
scrambledSolution.getRoute(r1).insertNode(k, n2);
}
return scrambledSolution;
}
protected ArrayListRoute scrambleRoute(ArrayListRoute route) {
ArrayListRoute scrambledRoute = route.clone();
Random r = new Random(0);
for (int i = 0; i < numSwaps; i++) {
int k = r.nextInt(route.length() - 2) + 1;
int l = r.nextInt(route.length() - 2) + 1;
scrambledRoute.swapNodes(k, l);
}
return scrambledRoute;
}
@Test
public void testExploreNeighborhood() {
System.out.println("---------------------------------");
System.out.println("ExploreNeighborhood test");
System.out.println("---------------------------------");
TwoOptNeighborhood<Solution<IRoute<INodeVisit>>> neighborhood = new TwoOptNeighborhood<Solution<IRoute<INodeVisit>>>();
System.out.println("Thorough exploration");
System.out.println("- - - - - - - - - - - - - - - - -");
Solution<IRoute<INodeVisit>> scrambledSol = scrambleSolution(solution);
System.out.println("Scrambled mSolution:");
System.out.println(scrambledSol);
neighborhood.localSearch(scrambledSol, new VRPParameters(
Long.MAX_VALUE, Integer.MAX_VALUE, false, false, null));
System.out.println("Resulting mSolution:");
System.out.println(scrambledSol);
TwoOptMove move = neighborhood.exploreNeighborhood(scrambledSol,
new VRPParameters(Long.MAX_VALUE, Integer.MAX_VALUE, false,
false, null));
System.out.printf("Improving move: %s\n", move);
System.out.println();
System.out.println("####################################");
System.out.println(" Capacity constraints");
System.out.println("####################################");
System.out.println("Thorough exploration");
System.out.println("- - - - - - - - - - - - - - - - -");
scrambledSol = scrambleSolution(solution);
System.out.println("Scrambled mSolution:");
System.out.println(scrambledSol);
neighborhood.getConstraintHandler().addConstraint(
new CapacityConstraint<Solution<IRoute<INodeVisit>>>());
neighborhood.localSearch(scrambledSol, new VRPParameters(
Long.MAX_VALUE, Integer.MAX_VALUE, false, false, null));
System.out.println("Resulting mSolution:");
System.out.println(scrambledSol);
move = neighborhood.exploreNeighborhood(scrambledSol,
new VRPParameters(Long.MAX_VALUE, Integer.MAX_VALUE, false,
false, null));
System.out.printf("Improving move: %s\n", move);
// boolean
// reversed=!scrambledRoute.getNodeAt(1).equals(route1.getNodeAt(1));
// for(int nodeI=0; nodeI< route1.length(); nodeI++){
// assertEquals(
// reversed?route1.getNodeAt(route1.length()-1-nodeI):route1.getNodeAt(nodeI),
// scrambledRoute.getNodeAt(nodeI));
// }
// assertEquals("Cost", optimalCost,scrambledRoute.getCost(),0.001);
// System.out.println();
// System.out.println("First improvement");
// System.out.println("- - - - - - - - - - - - - - - - -");
// scrambledRoute= route1.cloneObject();
// scrambledRoute.swapNodes(1, 2);
// scrambledRoute.swapNodes(5, 8);
// System.out.println("Scrambled route:");
// System.out.println(scrambledRoute);
// neighborhood.localSearch(scrambledRoute,
// new VRPParameters(Long.MAX_VALUE, Integer.MAX_VALUE, true, false,
// costHelper));
// System.out.println("Resulting route:");
// System.out.println(scrambledRoute);
// for(int nodeI=0; nodeI< route1.length(); nodeI++){
// if(nodeI!=5 && nodeI!=8)
// assertEquals(
// route1.getNodeAt(nodeI),
// scrambledRoute.getNodeAt(nodeI));
// }
// assertEquals(
// route1.getNodeAt(5),
// scrambledRoute.getNodeAt(8));
// assertEquals(
// route1.getNodeAt(8),
// scrambledRoute.getNodeAt(5));
// System.out.println();
// System.out.println("Thorough exploration with started route");
// ArrayListRoute routeCopy = route1.cloneObject();
// routeCopy.extractSubroute(0, 5);
// routeCopy.calculateCost(true);
// double cost= routeCopy.getCost();
// System.out.println("Started Route:");
// System.out.println(routeCopy);
// System.out.println("- - - - - - - - - - - - - - - - -");
//
// scrambledRoute=scrambleRoute(routeCopy);
// System.out.println("Scrambled route:");
// System.out.println(scrambledRoute);
// neighborhood.localSearch(scrambledRoute,
// new VRPParameters(Long.MAX_VALUE, Integer.MAX_VALUE, false, false,
// costHelper));
// System.out.println("Resulting route:");
// System.out.println(scrambledRoute);
//
// reversed=!scrambledRoute.getNodeAt(1).equals(routeCopy.getNodeAt(1));
// for(int nodeI=0; nodeI< routeCopy.length(); nodeI++){
// assertEquals(
// reversed?routeCopy.getNodeAt(route1.length()-1-nodeI):routeCopy.getNodeAt(nodeI),
// scrambledRoute.getNodeAt(nodeI));
// }
// assertEquals("Cost", cost,scrambledRoute.getCost(),0.001);
}
public static void main(String[] args) {
Logging.setupRootLogger(LoggerHelper.LEVEL_DEBUG,
LoggerHelper.LEVEL_DEBUG, true);
TwoOptNeigbhorhoodTest test = new TwoOptNeigbhorhoodTest();
try {
test.setUp();
} catch (Exception e) {
e.printStackTrace();
}
numSwaps = 20;
test.testExploreNeighborhood();
}
}