bgu.dcr.az.api.tools.DFSPsaudoTree Maven / Gradle / Ivy
/*
* The MIT License
*
* Copyright 2016 Benny Lutati.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package bgu.dcr.az.api.tools;
import java.util.Set;
import bgu.dcr.az.api.Agent;
import bgu.dcr.az.api.agt.SimpleAgent;
import bgu.dcr.az.api.ano.Algorithm;
import bgu.dcr.az.api.ano.WhenReceived;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
/**
*
* @author bennyl
*/
public class DFSPsaudoTree extends NestableTool implements PsaudoTree {
private static final int COLOR_BLACK = 0;
private static final int COLOR_WHITE = 1;
private static final int COLOR_GRAY = 2;
private List children;
private List pchildren;
private Integer parent;
private int root = 0;
private int vertexId;
private List pparents;
private Set seperator;
private RootSelectionAlgorithm lsa;
private int depth = 0;
private List descendants;
private List pParentsDepths;
public DFSPsaudoTree() {
children = new LinkedList();
pchildren = new LinkedList();
parent = -1;
pparents = new LinkedList();
seperator = new HashSet();
descendants = new LinkedList();
pParentsDepths = new LinkedList();
}
@Override
public List getChildren() {
return children;
}
@Override
public List getPsaudoChildren() {
return pchildren;
}
@Override
public Integer getParent() {
return parent;
}
@Override
public List getPsaudoParents() {
return pparents;
}
@Override
public String toString() {
return "Vertex: " + vertexId + "\r\n"
+ "Children: " + Agent.str(children) + "\r\n"
+ "Psaudo Childen: " + Agent.str(pchildren) + "\r\n"
+ "Parent: " + parent + "\r\n"
+ "Psaudo Parents: " + Agent.str(pparents) + "\r\n";
}
@Override
public boolean isRoot() {
return vertexId == root;
}
@Override
public boolean isLeaf() {
return getChildren().isEmpty();
}
@Override
public Set getSeperator() {
return seperator;
}
@Override
public int getDepth() {
return depth;
}
@Override
public List getDescendants() {
return descendants;
}
@Override
public List getPseudoParentDepths() {
return pParentsDepths;
}
@Override
protected SimpleAgent createNestedAgent() {
return new DFSTreeComputingAgent();
}
@Algorithm(name="DDFS")
public class DFSTreeComputingAgent extends SimpleAgent {
private int color = COLOR_WHITE;
private List neighbors;
private boolean[] dones;
@Override
public void start() {
// log("starting dfs");
vertexId = this.getId();
dones = new boolean[getNumberOfVariables()];
for (int i = 0; i < dones.length; i++) {
dones[i] = false;
}
root = 0;//lsa.select(callingAgent);
if (this.getId() == root) {
// log("starting dfsVisit");
dfsVisit();
}
}
@Override
public void handleTermination() {
// log("terminating");
super.handleTermination();
descendants.remove(this.getId());
}
private void dfsVisit() {
color = COLOR_GRAY;
// //System.out.println("A"+getId()+" IS GREY");
neighbors = new LinkedList(getProblem().getNeighbors(this.getId()));
// //System.out.println("A"+getId()+" NEIGHBORS ARE: "+ neighbors);
if (parent != null) {
neighbors.remove(parent);
}
neighbors.removeAll(pparents);
visitNextNeighbor();
}
private void visitNextNeighbor() {
if (neighbors.size() > 0) {
// //System.out.println("A"+getId()+" SENDING VISIT TO: "+ neighbors.get(0));
send("VISIT", depth + 1).to(neighbors.get(0));
} else {
// //System.out.println("A"+getId()+" ENDED WITH NEIGHBORS");
noMoreNeighbors();
}
}
private void noMoreNeighbors() {
color = COLOR_BLACK;
//System.out.println("A"+getId()+" IS BLACK");
dones[getId()] = true;
if (parent >= 0) { // not root
// //System.out.println("A"+getId()+" SENDING SET_CHILD TO: "+parent);
send("SET_CHILD", seperator, descendants).to(parent);
}
// //System.out.println("A"+getId()+" SENDING DONE TO ALL");
send("DONE").toAll(range(0, getProblem().getNumberOfVariables() - 1));
//send("DONE").to(1-getId());
}
@WhenReceived("VISIT")
public void handleVisit(int pDepth) {
int sendingAgent = 0;
sendingAgent = getCurrentMessage().getSender();
//System.out.println("A"+getId()+" GOT VISIT FROM:" + sendingAgent);
if (color == COLOR_WHITE) {
parent = sendingAgent;
depth = pDepth;
seperator.add(parent);
dfsVisit();
} else if (color == COLOR_BLACK) {
insertPseudoParent(sendingAgent, depth);
seperator.add(sendingAgent);
//System.out.println("A"+getId()+" SENDING SET_PSAUDO_CHILD TO: "+sendingAgent);
send("SET_PSAUDO_CHILD", descendants).to(sendingAgent);
} else {
//System.out.println("A"+getId()+" SENDING REFUSE_VISIT TO: "+sendingAgent);
send("REFUSE_VISIT").to(sendingAgent);
}
}
@WhenReceived("DONE")
public void handleDone() {
if (!isRoot() && getCurrentMessage().getSender() == root && !dones[this.getId()]) {
panic(new NotConnectivityGraphException("The recived problem not represents a conetivity graph"));
}
final Integer node = getCurrentMessage().getSender();
//System.out.println("A"+getId()+" GOT DONE FROM: "+node);
dones[getCurrentMessage().getSender()] = true;
if (allDone()) {
//System.out.println("A"+getId()+" FINISHING!!");
finish();//finish = true;
} else if (color == COLOR_GRAY && neighbors.get(0) == node) {
neighbors.remove(node);
//System.out.println("A"+getId()+" VISITING NEIGHBORE");
visitNextNeighbor();
}
}
@WhenReceived("SET_CHILD")
public void handleSetChild(Set childSeperator, LinkedList childDescendants) {
final Integer node = getCurrentMessage().getSender();
//System.out.println("A"+getId()+" GOT SET_CHILD FROM: "+node);
children.add(node);
seperator.addAll(childSeperator);
seperator.remove(this.getId());
descendants.remove(node);
descendants.removeAll(childDescendants);
descendants.add(node);
descendants.addAll(childDescendants);
}
@WhenReceived("SET_PSAUDO_CHILD")
public void handleSetPsaudoChild(LinkedList childDescendants) {
final Integer node = getCurrentMessage().getSender();
//System.out.println("A"+getId()+" GOT SET_PSAUDO_CHILD FROM: "+node);
pchildren.add(node);
descendants.remove(node);
descendants.removeAll(childDescendants);
descendants.add(node);
descendants.addAll(childDescendants);
handleDone();
}
@WhenReceived("REFUSE_VISIT")
public void handleRefuseVisit() {
final Integer node = getCurrentMessage().getSender();
//System.out.println("A"+getId()+" GOT REFUSE_VISIT FROM: "+node);
neighbors.remove(node);
visitNextNeighbor();
}
private boolean allDone() {
for (boolean b : dones) {
if (!b) {
return false;
}
}
return true;
}
public void insertPseudoParent(int agentIdx, int depth) {
int index = findInsertionIdx(depth);
pParentsDepths.add(index, depth);
pparents.add(index, agentIdx);
}
public int findInsertionIdx(int depth) {
if (pParentsDepths.isEmpty()) {
return 0;
}
//else binary search this vector:
int low = 0, high = pParentsDepths.size();
while (high > low && pParentsDepths.get(low) < depth) {
int mid = low + (high - low) / 2;
if (pParentsDepths.get(mid) < depth) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy