org.drools.planner.examples.tsp.solver.solution.initializer.TspStartingSolutionInitializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of drools-planner-examples Show documentation
Show all versions of drools-planner-examples Show documentation
Drools Planner optimizes automated planning by combining metaheuristic search algorithms with rule
engine powered score calculation. This is the drools-planner-examples module which contains examples on how to use
Drools Planner.
/*
* Copyright 2011 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.planner.examples.tsp.solver.solution.initializer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.drools.FactHandle;
import org.drools.WorkingMemory;
import org.drools.planner.core.phase.custom.CustomSolverPhaseCommand;
import org.drools.planner.core.score.DefaultSimpleScore;
import org.drools.planner.core.score.Score;
import org.drools.planner.core.solution.director.SolutionDirector;
import org.drools.planner.examples.common.domain.PersistableIdComparator;
import org.drools.planner.examples.tsp.domain.City;
import org.drools.planner.examples.tsp.domain.CityAssignment;
import org.drools.planner.examples.tsp.domain.TravelingSalesmanTour;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TspStartingSolutionInitializer implements CustomSolverPhaseCommand {
protected final transient Logger logger = LoggerFactory.getLogger(getClass());
public void changeWorkingSolution(SolutionDirector solutionDirector) {
TravelingSalesmanTour travelingSalesmanTour = (TravelingSalesmanTour) solutionDirector.getWorkingSolution();
initializeCityAssignmentList(solutionDirector, travelingSalesmanTour);
}
private void initializeCityAssignmentList(SolutionDirector solutionDirector,
TravelingSalesmanTour travelingSalesmanTour) {
City startCity = travelingSalesmanTour.getStartCity();
WorkingMemory workingMemory = solutionDirector.getWorkingMemory();
// TODO the planning entity list from the solution should be used and might already contain initialized entities
List cityAssignmentList = createCityAssignmentList(travelingSalesmanTour);
List assignedCityAssignmentList = null;
for (CityAssignment cityAssignment : cityAssignmentList) {
FactHandle cityAssignmentHandle = null;
if (assignedCityAssignmentList == null) {
assignedCityAssignmentList = new ArrayList(cityAssignmentList.size());
cityAssignment.setNextCityAssignment(cityAssignment);
cityAssignment.setPreviousCityAssignment(cityAssignment);
cityAssignmentHandle = workingMemory.insert(cityAssignment);
} else {
Score bestScore = DefaultSimpleScore.valueOf(Integer.MIN_VALUE);
CityAssignment bestAfterCityAssignment = null;
FactHandle bestAfterCityAssignmentFactHandle = null;
CityAssignment bestBeforeCityAssignment = null;
FactHandle bestBeforeCityAssignmentFactHandle = null;
for (CityAssignment afterCityAssignment : assignedCityAssignmentList) {
CityAssignment beforeCityAssignment = afterCityAssignment.getNextCityAssignment();
FactHandle afterCityAssignmentFactHandle = workingMemory.getFactHandle(afterCityAssignment);
FactHandle beforeCityAssignmentFactHandle = workingMemory.getFactHandle(beforeCityAssignment);
// Do changes
afterCityAssignment.setNextCityAssignment(cityAssignment);
cityAssignment.setPreviousCityAssignment(afterCityAssignment);
cityAssignment.setNextCityAssignment(beforeCityAssignment);
beforeCityAssignment.setPreviousCityAssignment(cityAssignment);
if (cityAssignmentHandle == null) {
cityAssignmentHandle = workingMemory.insert(cityAssignment);
} else {
workingMemory.update(cityAssignmentHandle, cityAssignment);
}
workingMemory.update(afterCityAssignmentFactHandle, afterCityAssignment);
workingMemory.update(beforeCityAssignmentFactHandle, beforeCityAssignment);
// Calculate score
Score score = solutionDirector.calculateScoreFromWorkingMemory();
if (score.compareTo(bestScore) > 0) {
bestScore = score;
bestAfterCityAssignment = afterCityAssignment;
bestAfterCityAssignmentFactHandle = afterCityAssignmentFactHandle;
bestBeforeCityAssignment = beforeCityAssignment;
bestBeforeCityAssignmentFactHandle = beforeCityAssignmentFactHandle;
}
// Undo changes
afterCityAssignment.setNextCityAssignment(beforeCityAssignment);
beforeCityAssignment.setPreviousCityAssignment(afterCityAssignment);
workingMemory.update(afterCityAssignmentFactHandle, afterCityAssignment);
workingMemory.update(beforeCityAssignmentFactHandle, beforeCityAssignment);
}
if (bestAfterCityAssignment == null) {
throw new IllegalStateException("The bestAfterCityAssignment (" + bestAfterCityAssignment
+ ") cannot be null.");
}
bestAfterCityAssignment.setNextCityAssignment(cityAssignment);
cityAssignment.setPreviousCityAssignment(bestAfterCityAssignment);
cityAssignment.setNextCityAssignment(bestBeforeCityAssignment);
bestBeforeCityAssignment.setPreviousCityAssignment(cityAssignment);
workingMemory.update(cityAssignmentHandle, cityAssignment);
workingMemory.update(bestAfterCityAssignmentFactHandle, bestAfterCityAssignment);
workingMemory.update(bestBeforeCityAssignmentFactHandle, bestBeforeCityAssignment);
}
assignedCityAssignmentList.add(cityAssignment);
if (cityAssignment.getCity() == startCity) {
travelingSalesmanTour.setStartCityAssignment(cityAssignment);
}
logger.debug(" CityAssignment ({}) initialized.", cityAssignment);
}
Collections.sort(cityAssignmentList, new PersistableIdComparator());
travelingSalesmanTour.setCityAssignmentList(cityAssignmentList);
}
public List createCityAssignmentList(TravelingSalesmanTour travelingSalesmanTour) {
List cityList = travelingSalesmanTour.getCityList();
// TODO weight: create by city on distance from the center ascending
List cityAssignmentList = new ArrayList(cityList.size());
int cityAssignmentId = 0;
for (City city : cityList) {
CityAssignment cityAssignment = new CityAssignment();
cityAssignment.setId((long) cityAssignmentId);
cityAssignment.setCity(city);
cityAssignmentList.add(cityAssignment);
cityAssignmentId++;
}
return cityAssignmentList;
}
}