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; }
}