Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.sf.gluebooster.java.booster.basic.math.planning.MetaPlanner Maven / Gradle / Ivy
Go to download
Basic classes to support the development of applications. There should be as few dependencies on other frameworks as possible.
package net.sf.gluebooster.java.booster.basic.math.planning;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.tuple.Pair;
import net.sf.gluebooster.java.booster.basic.container.BoostedNode;
import net.sf.gluebooster.java.booster.basic.math.Operation;
import net.sf.gluebooster.java.booster.basic.math.OperationSorter;
import net.sf.gluebooster.java.booster.basic.math.graph.BoostedNodeGraph;
import net.sf.gluebooster.java.booster.basic.transformation.CallableBySelecting;
import net.sf.gluebooster.java.booster.basic.transformation.CallableDelegate;
import net.sf.gluebooster.java.booster.essentials.eventsCommands.Callable;
import net.sf.gluebooster.java.booster.essentials.eventsCommands.CallableAbstraction;
import net.sf.gluebooster.java.booster.essentials.math.Condition;
import net.sf.gluebooster.java.booster.essentials.meta.HasName;
import net.sf.gluebooster.java.booster.essentials.meta.objects.ObjectAttributes;
/**
* Meta planning algorithms.
*
*
* @author CBauer
* @defaultParamText planning the current state of the planning with all necessary data
*
*
*/
public class MetaPlanner
extends CallableAbstraction, Planning>
{
/**
* The variant that does nothing
*/
private static final int VARIANT_IDLE = 0;
/**
* One (the first) planning algorithm
*/
private static final int VARIANT_1 = 1;
/**
* A variant that just expands not but does not solve conflicts.
*/
private static final int VARIANT_JUST_EXPAND = 2;
/**
* The description of the algorithm of the planning.
*/
private int variant = VARIANT_IDLE;
/**
* Selects one of the expanders that are selected with World.getExpander
*/
private Transformer>, Callable> planNodeExpanderSelector = new CallableDelegate(
CallableBySelecting.selectFirstElement("select first element"));
public MetaPlanner(int variant) {
this.variant = variant;
}
/**
* Create a planner that does nothing.
*
* @return the created planner
*/
public static Callable, Planning>/*
* ,
* NameOfObjects> Transformer,
* Planning>
*/ createIdlePlanner() {
return new MetaPlanner/**/(VARIANT_IDLE);
}
/**
* Create a planner with a default planning algorithm
*
* @return the created planner
*/
public static Callable, Planning>/*
* ,
* NameOfObjects> Transformer,
* Planning>
*/ createPlanner1() {
return new MetaPlanner/**/(VARIANT_1);
}
/**
* Create a planner that just expands the nodes, but does no conflict solving, etc.
*
* @return the created planner
*/
public static Callable, Planning>/*
* ,
* NameOfObjects> Transformer,
* Planning>
*/ createPlannerThatJustExpands() {
return new MetaPlanner/**/(VARIANT_JUST_EXPAND);
}
// /**
// * Does the planning
// *
// * @param planningInstance
// * instance of Planning
// * @return Planning
// */
// @Override
// public Object getObjectInstance(Object planningInstance, Name name,
// Context nameCtx, Hashtable, ?> environment) throws Exception {
//
// Planning planning = (Planning) planningInstance;
// switch (variant) {
// case VARIANT_IDLE:
// planIdle(planning);
// break;
// case VARIANT_1:
// plan1(planning);
// break;
// case VARIANT_JUST_EXPAND:
// planJustExpand(planning);
// break;
// default:
// throw new IllegalStateException("variant " + variant
// + " not (yet) supported");
// }
// return planningInstance;
// }
/**
* Does nothing
*
* @param configuration
* the planning
*/
private void planIdle(Planning configuration)
throws Exception {
configuration.info("idle planner, no planning is done");
}
/**
* Algorithm 1
*
* @param planning
*/
private void plan1(Planning planning)
throws Exception {
// planning.debug("planner 1");
int i = 0;
int maxSteps = planning.getEnv().getMaxSteps();
while (i < maxSteps && !planning.getPlan().isSolved()) {
i++;
planning.info("planner ", variant, ": step ", i, " of at most ",
maxSteps);
// TODO use a time dependent combineNodes instead of i
if (!nextStep1(planning, i < 30)) {
simplify1(planning);
}
if (planning.getPlan().isSolved())
planning.getPlan().removeSuperfluousOperators();
if (planning.getPlan().getVersion() == null) {
planning.getPlan().setVersion(1);
} else {
planning.getPlan().setVersion(
planning.getPlan().getVersion().intValue() + 1);
}
}
}
/**
* Algorithm 1
*
* @param plan
* @param env
* @throws Exception
*/
private void planJustExpand(Planning planning)
throws Exception {
int i = 0;
int maxSteps = planning.getEnv().getMaxSteps();
planning.getPlan().setVersion(1);
while (i < maxSteps && !planning.getPlan().isSolved()) {
i++;
planning.info("planner ", variant, ": step ", i, " of at most ",
maxSteps);
nextStepJustExpandOneNode(planning);
planning.getPlan().setVersion(
planning.getPlan().getVersion().intValue() + 1);
}
}
/**
* Do one step (of planning algorithm 1)
*
* @param combineNodes
* the nodes to combine
* @return true, if the plan has been modified
*/
private boolean nextStep1(Planning planning,
boolean combineNodes) throws Exception {
boolean result = instantiateOneRandomVirtualObject(planning);
result |= solveSomeUnsolvedNodeWithMaximumAbstraction(planning, 10);
if (combineNodes) {
result |= combineNodes(planning);
while (combineNodes(planning)) {
// just repeat the combining process as long as possible
}
}
result |= solveEarlyConflictSeries(planning);
while (solveEarlyConflictSeries(planning)) {
// just repeat the solving process as long as possible
}
if (!result) {
result = solveGoalConflict(planning);
}
if (!result) {
// plan->combine_above = 0;
result = combineNodes(planning);
// plan->combine_above = 1;
}
return result;
}
/**
* Do one step (of planning algorithm 1)
*
* @param plan
* @return true, if the plan has been modified
*/
private boolean nextStepJustExpandOneNode(
Planning planning)
throws Exception {
boolean result = planning.removeSuperfluousOperators();
if (!result) {
result = instantiateOneRandomVirtualObject(planning);
}
if (!result) {
result = solveSomeUnsolvedNodeWithMaximumAbstraction(planning, 1);
}
return result;
}
/**
* Tries to solve the nodes with the highest abstraction level.
*
* If the highest abstraction level is not solvable continue with the next lower level. Try to solve all nodes with the same abstraction level. If any node
* is solved, do not continue with the next lower abstraction level, but stop
*
* @param maxNumberOfNodes
* the maximum number of nodes to solve/expand
* @return true, if the plan has been modified
* @throws Exception
*/
public boolean solveSomeUnsolvedNodeWithMaximumAbstraction(
Planning planning, int maxNumberOfNodes)
throws Exception {
int abstractionLevel = 0;
boolean solved = false;
Collection unsolvedNodes = planning.getPlan()
.getUnsolvedNodes(
OperationSorter.createSortByOperatorAbstractionDesc());
int counter = 0;
for (BoostedNode unsolvedNode : unsolvedNodes) {
int newAbstractionLevel = Operation.getOperation(unsolvedNode)
.getOperator()
.getAbstractionLevel();
if (solved) {
if (newAbstractionLevel < abstractionLevel) {
break; // stop solving
}
} else {
abstractionLevel = newAbstractionLevel;
}
if (counter < maxNumberOfNodes) {
boolean tempResult = expandUnsolvedNode(planning, unsolvedNode);
solved |= tempResult;
if (tempResult) {
counter++;
}
} else {
break;
}
}
return solved;
}
/**
* Expands an unsolved node to a graph with of (easier solvable ) nodes. The plan is modified
*
* @param planning
* contains the plan
* @param unsolvedNode
* the node to expland
* @return true if something has been changed
* @throws Exception
*/
public boolean expandUnsolvedNode(
Planning planning,
BoostedNode unsolvedNode) throws Exception {
// Refactor.checkPredecessorSuccessor(unsolvedNode);
Collection> solvers = planning
.getPlan().getWorld()
.getExpander(unsolvedNode);
if (solvers.isEmpty()) {
return false;
} else {
boolean result = planning.transformNode(unsolvedNode,
planNodeExpanderSelector.transform(solvers));
// planning.getPlan().simpleDisplay();
return result;
}
}
/**
* If nodes do the same operation in parallel branches, it may be possible
* merge the two operations into one by changing the plan structure. One
* operation is removed, its predecessors become predecessors of the other
* operation; its successors become successors of the other operation.
*
* @return true, if the plan has been modified
*/
public boolean combineNodes(Planning planning) throws Exception {
// Algorithm
// first get all nodes with equal operators
// try to merge two of them.
// first get all nodes with equal operators
Set> setsOfnodesWithEqualOperators = planning
.getPlan()
.getNodesWithEqualOperations(null, null); // TODO use a higher level
// TODO check abstraction level here
// get pairs of the nodes ant try to combine them until something was
// sucessful or you run out of nodes
for (Set nodesWithEqualOperators : setsOfnodesWithEqualOperators) {
ArrayList otherNodes = new ArrayList(
nodesWithEqualOperators);
for (BoostedNode node : nodesWithEqualOperators) {
otherNodes.remove(node); // so that there is no duplicate
for (BoostedNode otherNode : otherNodes) {
HashSet nodesToCombine = new HashSet(Arrays.asList(node, otherNode));
if (planning.getPlan().combineNodesWithEqualOperators(nodesToCombine)) {
return true;
}
}
}
}
return false;
}
/**
* Solves the possible conflicts in the order of their graph position
*
* @return true, if the plan has been modified
*/
public boolean solveEarlyConflictSeries(
Planning planning) throws Exception {
List>*/> possibleConflicts = planning
.getPlan().orderPossibleConflictsByGraphPosition();
for (ObjectAttributes/* > */ possibleConflict : possibleConflicts) {
if (planning.getPlan().solvePossibleConflictByReordering(
possibleConflict)) {
return true;
}
}
return false;
}
/**
* Solve a goal conflict.
*
* @return true, if the plan has been modified
*/
public boolean solveGoalConflict(Planning planning) {
planning.error("solveGoalConflict is not yet implemented");
// TODO do something
// updateGlobalConditions();
return false;
}
/**
* Instantiates a temporary object with a random instance.
*
* @return true, if the plan has been modified
*/
public boolean instantiateOneRandomVirtualObject(
Planning planning)
throws Exception {
Plan plan = planning.getPlan();
Set nodes = plan.getNodesWithVirtualProperties();
if (nodes.isEmpty()) {
return false;
} else {
// take the first object and instantiate it with a random instance
BoostedNode node = nodes.iterator().next();
Set initializers = plan.getWorld()
.getVirtualObjectInitializer(node);
Pair virtualAndConcreteObject = (Pair) initializers
.iterator().next()
.call(node, Planning.createHashtableWithPlan(plan));
if (virtualAndConcreteObject != null) {
planning.instantiateVirtualObject(node,
virtualAndConcreteObject.getLeft(),
virtualAndConcreteObject.getRight());
return true;
}
else
return false;
}
}
/**
* Simplify a plan by replacing subtrees with new nodes that are to be
* solved. Simplifies the plan according to planning algorithm 1.
*
* @param plan
*/
public void simplify1(Planning planning) {
planning.error("simplify1 is not yet implemented");
// TODO implement plan->undo();
}
/**
* Does the planning
*
*/
@Override
protected Planning callImpl(Planning... parameters) throws Exception {
Planning planning = parameters[0];
switch (variant) {
case VARIANT_IDLE:
planIdle(planning);
break;
case VARIANT_1:
plan1(planning);
break;
case VARIANT_JUST_EXPAND:
planJustExpand(planning);
break;
default:
throw new IllegalStateException("variant " + variant + " not (yet) supported");
}
return planning;
}
}