/**
*
*/
package vroom.common.heuristics.vrp;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import vroom.common.heuristics.ConstraintHandler;
import vroom.common.heuristics.vrp.constraints.CapacityConstraint;
import vroom.common.modeling.dataModel.ListRoute.ArrayListRoute;
import vroom.common.modeling.dataModel.Fleet;
import vroom.common.modeling.dataModel.INodeVisit;
import vroom.common.modeling.dataModel.IVRPInstance;
import vroom.common.modeling.dataModel.Node;
import vroom.common.modeling.dataModel.Solution;
import vroom.common.modeling.dataModel.Vehicle;
import vroom.common.modeling.util.CircularInstanceGenerator;
import vroom.common.modeling.util.SolutionChecker;
import vroom.common.utilities.dataModel.ObjectWithIdComparator;
/**
* <code>StringExchangeNeighborhoodTest</code> is a generic implementation of
* the string-exchange neighborhood.
* <p>
* Creation date: Jul 8, 2010 - 5:24:10 PM
*
* @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los
* Andes</a>-<a href="http://copa.uniandes.edu.co">Copa</a> <a
* href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a
* href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a>
* @version 1.0
*/
public class StringExchangeNeighborhoodTest {
static int sNumNodes = 10;
private Solution<ArrayListRoute> solution;
private IVRPInstance instance;
private StringExchangeNeighborhood<Solution<ArrayListRoute>> neighborhood;
@Before
public void setUp() throws Exception {
System.out.println("--------------------------------");
System.out.println(" SETUP");
List<Node> nodes = new LinkedList<Node>();
instance = CircularInstanceGenerator.newCircularInstance(sNumNodes,
nodes, 10);
instance.setFleet(Fleet.newHomogenousFleet(2, new Vehicle(0, "V",
sNumNodes / 2 + 1)));
solution = new Solution<ArrayListRoute>(instance);
ArrayListRoute route1 = new ArrayListRoute(solution, instance
.getFleet().getVehicle());
ArrayListRoute route2 = new ArrayListRoute(solution, instance
.getFleet().getVehicle());
solution.addRoute(route1);
solution.addRoute(route2);
route1.appendNode(instance.getDepotsVisits().iterator().next());
route2.appendNode(instance.getDepotsVisits().iterator().next());
ArrayList<INodeVisit> visits = new ArrayList<INodeVisit>(
instance.getNodeVisits());
Collections.sort(visits, new ObjectWithIdComparator());
for (int i = 0; i < visits.size(); i++) {
if (i < visits.size() / 2) {
route1.appendNode(visits.get(i));
} else {
route2.appendNode(visits.get(i));
}
}
route1.appendNode(instance.getDepotsVisits().iterator().next());
route2.appendNode(instance.getDepotsVisits().iterator().next());
System.out.println("Dummy solution initialized:");
System.out.println(solution);
neighborhood = new StringExchangeNeighborhood<Solution<ArrayListRoute>>(
new ConstraintHandler<Solution<ArrayListRoute>>());
neighborhood.getConstraintHandler().addConstraint(
new CapacityConstraint<Solution<ArrayListRoute>>());
}
/**
* Test method for
* {@link vroom.common.heuristics.vrp.StringExchangeNeighborhood#executeMove(vroom.common.modeling.dataModel.IVRPSolution, vroom.common.heuristics.Move)}
* .
*/
@Test
public void testExecuteMove() {
System.out.println("--------------------------------");
System.out.println("testExecuteMove");
System.out.println("--------------------------------");
Solution<ArrayListRoute> sol = solution.clone();
System.out.println("Solution: " + sol);
StringExchangeMove<Solution<ArrayListRoute>> move = new StringExchangeMove<Solution<ArrayListRoute>>(
solution, 0, 1, 2, 4, 2, 4);
int[] exp1 = new int[] { 0, 1, 7, 8, 9, 5, 0 };
int[] exp2 = new int[] { 0, 6, 2, 3, 4, 10, 0 };
System.out.println("Move : " + move);
neighborhood.executeMove(sol, move);
System.out.println("Result : " + sol);
for (int i = 0; i < exp1.length; i++) {
assertEquals(exp1[i], sol.getRoute(0).getNodeAt(i).getID());
}
for (int i = 0; i < exp2.length; i++) {
assertEquals(exp2[i], sol.getRoute(1).getNodeAt(i).getID());
}
System.out.println();
sol = solution.clone();
System.out.println("Solution: " + sol);
move = new StringExchangeMove<Solution<ArrayListRoute>>(solution, 0, 1,
2, 2, 2, 4);
exp1 = new int[] { 0, 1, 7, 8, 9, 3, 4, 5, 0 };
exp2 = new int[] { 0, 6, 2, 10, 0 };
System.out.println("Move : " + move);
neighborhood.executeMove(sol, move);
System.out.println("Result : " + sol);
for (int i = 0; i < exp1.length; i++) {
assertEquals(exp1[i], sol.getRoute(0).getNodeAt(i).getID());
}
for (int i = 0; i < exp2.length; i++) {
assertEquals(exp2[i], sol.getRoute(1).getNodeAt(i).getID());
}
System.out.println();
sol = solution.clone();
System.out.println("Solution: " + sol);
move = new StringExchangeMove<Solution<ArrayListRoute>>(solution, 0, 0,
2, 2, 3, 4);
exp1 = new int[] { 0, 1, 3, 4, 2, 5, 0 };
exp2 = new int[] { 0, 6, 7, 8, 9, 10, 0 };
System.out.println("Move : " + move);
neighborhood.executeMove(sol, move);
System.out.println("Result : " + sol);
for (int i = 0; i < exp1.length; i++) {
assertEquals(exp1[i], sol.getRoute(0).getNodeAt(i).getID());
}
for (int i = 0; i < exp2.length; i++) {
assertEquals(exp2[i], sol.getRoute(1).getNodeAt(i).getID());
}
System.out.println();
sol = solution.clone();
System.out.println("Solution: " + sol);
move = new StringExchangeMove<Solution<ArrayListRoute>>(solution, 0, 1,
0, 2, 2, 4);
exp1 = new int[] { 7, 8, 9, 3, 4, 5, 0 };
exp2 = new int[] { 0, 6, 0, 1, 2, 10, 0 };
System.out.println("Move : " + move);
neighborhood.executeMove(sol, move);
System.out.println("Result : " + sol);
for (int i = 0; i < exp1.length; i++) {
assertEquals(exp1[i], sol.getRoute(0).getNodeAt(i).getID());
}
for (int i = 0; i < exp2.length; i++) {
assertEquals(exp2[i], sol.getRoute(1).getNodeAt(i).getID());
}
}
/**
* Test method for
* {@link vroom.common.heuristics.vrp.StringExchangeNeighborhood#evaluateCandidateMove(vroom.common.heuristics.vrp.StringExchangeMove)}
* .
*/
@Test
public void testEvaluateCandidateMove() {
System.out.println("--------------------------------");
System.out.println("testEvaluateCandidateMove");
System.out.println("--------------------------------");
Solution<ArrayListRoute> sol;
System.out.println("Solution: " + solution);
List<StringExchangeMove<Solution<ArrayListRoute>>> moves = new LinkedList<StringExchangeMove<Solution<ArrayListRoute>>>();
moves.add(new StringExchangeMove<Solution<ArrayListRoute>>(solution, 0,
1, 2, 4, 2, 4));
moves.add(new StringExchangeMove<Solution<ArrayListRoute>>(solution, 0,
1, 2, 2, 2, 4));
moves.add(new StringExchangeMove<Solution<ArrayListRoute>>(solution, 0,
0, 2, 2, 3, 4));
moves.add(new StringExchangeMove<Solution<ArrayListRoute>>(solution, 0,
1, 0, 2, 2, 4));
Random r = new Random(0);
for (int m = 0; m < 1000; m++) {
int r1 = r.nextInt(2);
int r2 = r.nextInt(2);
int min = r1 == r2 ? 1 : 0;
int i = r.nextInt(solution.getRoute(r1).length() - min);
int j = r.nextInt(solution.getRoute(r1).length() - i - min) + i;
min = r1 == r2 ? j + 1 : 0;
int k, l;
if (r1 == r2 && solution.getRoute(r1).length() - min <= 0) {
k = min;
l = min;
} else {
k = r.nextInt(solution.getRoute(r2).length() - min) + min;
if (solution.getRoute(r2).length() - min - k <= 0) {
l = k;
} else {
l = r.nextInt(solution.getRoute(r2).length() - min - k)
+ min + k;
}
}
if (j < solution.getRoute(0).length()
&& l < solution.getRoute(0).length()) {
moves.add(new StringExchangeMove<Solution<ArrayListRoute>>(
solution, r1, r2, i, j, k, l));
}
}
for (StringExchangeMove<Solution<ArrayListRoute>> move : moves) {
sol = solution.clone();
move.setImprovement(neighborhood.evaluateCandidateMove(move));
System.out.println("Move : " + move);
SolutionChecker.checkSolution(sol, true, true, true);
System.out.println(sol);
double delta = sol.getCost();
neighborhood.executeMove(sol, move);
SolutionChecker.checkSolution(sol, true, true, true);
System.out.println(sol);
delta -= sol.getCost();
System.out.println("Delta : " + delta);
System.out.println("Improv : " + move.getImprovement());
assertEquals(String.format("Wrong improvement for move %s", move),
delta, move.getImprovement(), 1E-3);
}
}
}