import java.lang.Integer; import java.util.HashMap; import java.util.Map.Entry; import java.util.Iterator; import java.lang.reflect.Type; /** *

Discrete state for tree re-arrangement agent

*

Future work -- currently the "target topology information" * specific to "Formation Morphing Algorithm" is combined with this class. * This should not be the case. The two should be separated, and * Formation Morphing Algorithm should have its own class to store * this info. *

* * @author Michael Schuresko * @version %I%, %G% * @since 1.0 */ public class TreeConstraintState extends LogicVarIntLookup implements ILogicVarBundle, IMsg { HashMap m_mapAdditions; public void setMsgAddition(Type t, IMsg msg) { m_mapAdditions.put(t, msg); } public IMsg getMsgAddition(Type t) { return m_mapAdditions.get(t); } HashMap copyMapAdditions() { try { HashMap mRes= new HashMap(m_mapAdditions.size()); Iterator> iter = m_mapAdditions.entrySet().iterator(); while(iter.hasNext()) { Entry currEntry = iter.next(); if(currEntry.getValue() != null) { mRes.put(currEntry.getKey(), currEntry.getValue()); } } return mRes; } catch(java.lang.NullPointerException e) { return new java.util.HashMap(5); } } /** * makes a copy and returns it */ public TreeConstraintState makeCopy() { return new TreeConstraintState(this); } int m_nDepth, m_nParentId; int m_nRootId; int m_nProposedParent; int m_nRoundId; int m_nIncrementTieBreaker; boolean m_bParDepLess; /* * Here we put the data members for the increase depth alg * and related algorithms */ Integer m_nObjDepTarg; // can be "NULL" for "no depth target" boolean m_bIncreaseDepth; public Integer getDepTarg() { return m_nObjDepTarg; } public void setDepTarg(int nDepTarg) { m_nObjDepTarg = new Integer(nDepTarg); } public void clearDepTarg() { m_nObjDepTarg = null; } public void setIncreaseDepth(boolean bIncreaseDepth) { m_bIncreaseDepth = bIncreaseDepth; } public boolean getIncreaseDepth() { return m_bIncreaseDepth; } public int getDepthEst() { return m_nDepth; } public void updateDepthEst(TreeConstraintState stateParent, int nNumStates) { ++m_nIncrementTieBreaker; m_nIncrementTieBreaker = m_nIncrementTieBreaker%(m_nRootId+1); //if(m_nRootId != getId() || m_nIncrementTieBreaker != 0) { m_nDepth = stateParent.getDepthEst() +1; //} else { // sorry, this stuff didn't work. // Next time, think (and prove!) first then code. /*System.out.println("Did it, id is "+ ((Integer)m_nRootId).toString()); System.out.flush(); */ // m_nDepth = stateParent.getDepthEst(); // } if(this.m_nRootId == this.getId()) { m_nDepth = Math.min(m_nDepth, (nNumStates+1)*m_nRootId); } else { m_nDepth = Math.min(m_nDepth, (nNumStates+1)*m_nRootId+nNumStates); } } /** * Not the preferred way to do this */ public void setDepthEst(int nNewDepth) { m_nDepth = nNewDepth; } public void resetDepthEst() { m_nDepth = 0; } public int getRootId() { return m_nRootId; } public void setRootId(int nRoot) { m_nRootId = nRoot; } public int getParentId() { return m_nParentId; } public void setParentId(int nParentId) { m_nParentId = nParentId; } public int getParentProp() { return m_nProposedParent; } public void setParentProp(int nParentProp) { m_nProposedParent = nParentProp; } public boolean getParDepLess() { return m_bParDepLess; } public void setParDepLess(boolean bParDepLess) { m_bParDepLess = bParDepLess; } public void setParDepLess(TreeConstraintState stateParent) { if(m_nParentId == stateParent.getId()) { m_bParDepLess = (stateParent.m_nDepth < m_nDepth ); } } /** * faked enum for differentiating rounds */ public static final int ROUND_ATTACH=0; /** * faked enum for differentiating rounds */ public static final int ROUND_UPDATE_DEPTH=1; /** * faked enum for differentiating rounds */ public static final int ROUND_SET_PARLESS=2; /** * faked enum for differentiating rounds */ public static final int ROUND_PROPOSE_NEW=3; /** * @param nDepth initial depth estimate (see 2006i) * @param nParentId initial parent id * parent ids has finished for this node and all its children */ public TreeConstraintState(int nDepth, int nParentId) { m_nObjDepTarg=null; m_bIncreaseDepth=false; m_nRoundId=0; m_nDepth = nDepth; m_nParentId = nParentId; m_nRootId = nParentId; // not sure if this is right... m_nIncrementTieBreaker = 0; setId(-1); m_bParDepLess = false; m_nProposedParent = m_nParentId; m_mapAdditions = new HashMap(5); } /** *

Sets depth estimate to zero.

*

Final target configuration and topology information * need to be set seperately.

* @param nParentId initial parent id * parent ids has finished for this node and all its children */ public TreeConstraintState(int nParentId) { m_nIncrementTieBreaker=0; m_nObjDepTarg=null; m_bIncreaseDepth=false; m_nRoundId=0; m_nDepth = 0; m_nParentId = nParentId; m_nRootId = nParentId; m_nProposedParent = m_nParentId; m_bParDepLess = false; setId(-1); m_mapAdditions = new HashMap(5); } /** *

Sets depth estimate to zero, parentId to -1, and * m_bDfsFinished to false

*

Final target configuration and topology information * need to be set seperately.

*/ public TreeConstraintState() { m_nObjDepTarg=null; m_bIncreaseDepth=false; m_nRoundId=0; m_nDepth = 0; m_nParentId = -1; m_nRootId = -1; setId(-1); m_nProposedParent = m_nParentId; m_bParDepLess = false; m_nIncrementTieBreaker = 0; m_mapAdditions = new HashMap(5); } /** * Copy constructor - copies everything * target information copied as well (valid if valid in src) * @param src makes new copies of everything from this state */ public TreeConstraintState(TreeConstraintState src) { m_nObjDepTarg=src.m_nObjDepTarg; m_bIncreaseDepth=src.m_bIncreaseDepth; m_nRoundId=src.m_nRoundId; m_nRootId = src.m_nRootId; m_nDepth = src.m_nDepth; m_nParentId = src.m_nParentId; super.copyFrom(src); setId(src.getId()); m_nProposedParent = src.m_nProposedParent; m_bParDepLess = src.m_bParDepLess; m_nIncrementTieBreaker = src.m_nIncrementTieBreaker; m_mapAdditions = src.copyMapAdditions(); } /** * Increment round counter (e.g which round of the algorithm we're on) * This is essential for * correct negotiation of constraint tree topology re-arrangements * @return this */ public TreeConstraintState incrRound() { m_nRoundId = (m_nRoundId+1)%4; return this; } /** * accessor for current round */ public int getCurrRound() { return m_nRoundId; } }