All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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