Package graphplan.graph.planning

Source Code of graphplan.graph.planning.PlanningGraph

/*
* ---------------------------------------------------------------------------
* Copyright (C) 2010  Felipe Meneguzzi
* JavaGP is distributed under LGPL. See file LGPL.txt in this directory.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* To contact the author:
* http://www.meneguzzi.eu/felipe/contact.html
* ---------------------------------------------------------------------------
*/
package graphplan.graph.planning;

import graphplan.domain.Operator;
import graphplan.domain.Proposition;
import graphplan.graph.ActionLevel;
import graphplan.graph.GraphElement;
import graphplan.graph.GraphElementVisitor;
import graphplan.graph.GraphLevel;
import graphplan.graph.PropositionLevel;
import graphplan.graph.algorithm.ActionLevelGenerator;
import graphplan.graph.algorithm.MutexGenerator;
import graphplan.graph.algorithm.PropositionLevelGenerator;
import graphplan.graph.algorithm.impl.LevelGeneratorImpl;
import graphplan.graph.algorithm.impl.MutexGeneratorImpl;
import graphplan.graph.draw.TextDrawVisitor;
import graphplan.graph.memo.mutexes.StaticMutexesTable;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Logger;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class PlanningGraph implements GraphElement {

  private static final long serialVersionUID = -941628537295487625L;

  @SuppressWarnings("unused")
  private static final Logger logger = Logger.getLogger(PlanningGraph.class.getName());

  protected List<GraphLevel> graphLevels = null;
  protected ActionLevelGenerator actionLevelGenerator = null;
  protected PropositionLevelGenerator propositionLevelGenerator = null;
  protected MutexGenerator mutexGenerator = null;
  protected TreeSet<Proposition> propositions;
  protected TreeSet<Operator> operators;
 
  //The level in which the graph has levelled off
  protected int levelOff = 0;

  public PlanningGraph() {
    this.graphLevels = new ArrayList<GraphLevel>();
    //XXX Right now I'm hard coding the instantiation of the level generators
    //TODO Eventually this should be done through configuration and reflection
    LevelGeneratorImpl levelGenerator = new LevelGeneratorImpl();
    this.actionLevelGenerator = levelGenerator;
    this.propositionLevelGenerator = levelGenerator;
    //And the mutex generator
    this.mutexGenerator = new MutexGeneratorImpl();
    this.propositions = new TreeSet<Proposition>();
    this.operators = new TreeSet<Operator>();
  }

  public PlanningGraph(PropositionLevel initialState) {
    this();
    this.addGraphLevel(initialState);
  }
 
  public PlanningGraph(PropositionLevel initialState, StaticMutexesTable staticsMutexesTable) {
    this();
    this.mutexGenerator = new MutexGeneratorImpl(staticsMutexesTable);
    this.addGraphLevel(initialState);
    this.setIndexForPropositions(initialState);
  }

  public PlanningGraph(PropositionLevel initialState, Map<String, Set<String>> types, Map<String, List<String>> parameterTypes, StaticMutexesTable staticsMutexesTable) {
    this(initialState, staticsMutexesTable);

    LevelGeneratorImpl levelGenerator = new LevelGeneratorImpl(types, parameterTypes);
    this.actionLevelGenerator = levelGenerator;
    this.propositionLevelGenerator = levelGenerator;
  }

  public boolean accept(GraphElementVisitor visitor) {
    /*for (GraphLevel level : graphLevels) {
      visitor.visitGraphLevel(level);
    }*/
    return visitor.visitElement(this);
  }

  public Iterator<GraphElement> iterator() {
    Iterator<GraphElement> iterator = new Iterator<GraphElement>() {
      protected Iterator<GraphElement> elementIterator = null;

      protected Iterator<GraphLevel> levelIterator = graphLevels
          .iterator();

      public boolean hasNext() {
        if (elementIterator == null) {
          if (levelIterator.hasNext()) {
            elementIterator = (Iterator<GraphElement>) levelIterator
                .next().iterator();
          }
        }
        if (elementIterator.hasNext()) {
          return true;
        } else {
          if (levelIterator.hasNext()) {
            elementIterator = (Iterator<GraphElement>) levelIterator
                .next().iterator();
            return this.hasNext();
          }
        }
        return false;
      }

      public GraphElement next() {
        return elementIterator.next();
      }

      public void remove() {
        throw new UnsupportedOperationException();
      }

    };
    return iterator;
  }

  /**
   * Returns the number of levels in this graph
   *
   * @return
   */
  public int size() {
    return graphLevels.size();
  }

  /**
   * Returns the specified graph level
   *
   * @param iLevel
   * @return
   */
  public GraphLevel getGraphLevel(int iLevel) {
    return this.graphLevels.get(iLevel);
  }

  /**
   * Helper method to get the last GraphLevel.
   *
   * @return The last level in the planning graph.
   */
  public GraphLevel getLastGraphLevel() {
    if (graphLevels.size() > 0) {
      return graphLevels.get(graphLevels.size() - 1);
    } else {
      return null;
    }
  }

  /**
   * Adds a new graph level, enforcing the alternation of Proposition and
   * Action levels.
   *
   * @param graphLevel
   *            The new level to be added.
   */
  public boolean addGraphLevel(GraphLevel graphLevel) {
    if ((graphLevels.isEmpty() && graphLevel.isPropositionLevel()) ||
      (this.graphLevels.get(this.graphLevels.size() - 1).isActionLevel()
          != graphLevel.isActionLevel())) {
      if(!graphLevels.isEmpty()){
        graphLevel.setPrevLevel(this.getLastGraphLevel());
      }
     
      this.graphLevels.add(graphLevel);
      graphLevel.setIndex(this.graphLevels.size() - 1);
      return true;
    } else {
      return false;
    }
  }

  /**
   * Determines if the propositions given as a parameter are a possible set of
   * goals in the specified proposition level.
   *
   * @param goals
   * @return
   */
  public boolean goalsPossible(List<Proposition> goals, int level) {
    if (graphLevels.get(level).isPropositionLevel()) {
      PropositionLevel propositionLevel = (PropositionLevel) this.graphLevels.get(level);
      return propositionLevel.goalsPossible(goals);
    } else {
      return false;
    }
  }

  /**
   * Expands the planning graph by adding one action level and one proposition
   * level.
   *
   */
  public void expandGraph() throws PlanningGraphException {
    if (getLastGraphLevel().isPropositionLevel()) {
      PropositionLevel lastLevel = (PropositionLevel) getLastGraphLevel();
      //First we create a new action level from the last proposition level
      ActionLevel actionLevel = actionLevelGenerator.createNextActionLevel(lastLevel);
      this.addGraphLevel(actionLevel);
      this.setIndexForOperators(actionLevel);
      //Then we add the action mutexes for these actions
      this.mutexGenerator.addActionMutexes(lastLevel, actionLevel);
      //And then add the subsequent proposition level
      PropositionLevel propositionLevel = propositionLevelGenerator.createNextPropositionLevel(actionLevel);
      this.addGraphLevel(propositionLevel);
      this.setIndexForPropositions(propositionLevel);
      //Finally adding the proposition mutexes
      this.mutexGenerator.addPropositionMutexes(actionLevel, propositionLevel);
    } else {
      throw new PlanningGraphException(
          "Last graph level is not proposition.",
          graphLevels.size() - 1);
    }
  }

  /**
   * Returns whether or not this graph has levelled off according to the
   * level size criterion. The entire graph levels off when both the levels
   * have levelled off and the memoization table has levelled off.
   * @return
   */
  public boolean levelledOff() {
    //If the graph has already levelled off, then we don't have to check
    //again
    if(levelOff > 0) {
      return true;
    } else {
      final int lastGraphLevel = graphLevels.size() - 1;
     
      if(lastGraphLevel > 3) {
        boolean levelledOff = false;
       
        //If the graph has levelled off, store the index where it
        //happened to check for the memoization stop condition       
        levelledOff =
          (graphLevels.get(lastGraphLevel).size() == graphLevels.get(lastGraphLevel-2).size())
          &&(graphLevels.get(lastGraphLevel).mutexCount() == graphLevels.get(lastGraphLevel-2).mutexCount())
          &&(graphLevels.get(lastGraphLevel-1).size() == graphLevels.get(lastGraphLevel-3).size())
          &&(graphLevels.get(lastGraphLevel-1).mutexCount() == graphLevels.get(lastGraphLevel-3).mutexCount());
       
        if(levelledOff) {
          levelOff = lastGraphLevel;
        }
       
        return levelledOff;
      } else {
        return false;
      }
    }
  }
 
  /**
   * Returns the level at which the graph has levelled off.
   * @return The level at which the graph has levelled off.
   */
  public final int levelOffIndex() {
    return levelOff;
  }
 
  public void setIndexForPropositions(PropositionLevel propositionLevel){
    for (Iterator<Proposition> it = propositionLevel.iterator(); it.hasNext();) {
      Proposition p = it.next();
      if(!this.propositions.contains(p)){
        p.setIndex(propositionLevel.getIndex());
        this.propositions.add(p);
      } else p.setIndex(this.propositions.ceiling(p).getIndex());
    }
  }
 
  public void setIndexForOperators(ActionLevel actionLevel){
    for (Iterator<Operator> it = actionLevel.iterator(); it.hasNext();) {
      Operator op = it.next();
      if(!this.operators.contains(op)){
        op.setIndex(actionLevel.getIndex());
        this.operators.add(op);
      } else op.setIndex(this.operators.ceiling(op).getIndex());
    }
  }
 
  public String toString() {
    TextDrawVisitor visitor = new TextDrawVisitor();
    if(this.accept(visitor)) {
      return visitor.toString();
    } else {
      return super.toString();
    }
  }

  public TreeSet<Proposition> getPropositions() {
    return propositions;
  }
}
TOP

Related Classes of graphplan.graph.planning.PlanningGraph

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.