package edu.isi.karma.modeling.steiner.topk; import java.util.Set; import java.util.TreeSet; /** * This class serves as the main building block of a Steiner tree. * Additionally to the the class Entity a SteinerNode has also the edges that * contain it and a predecessor node from which the SteinerNode is reached. * @author kasneci * */ public class SteinerNode extends Entity { /* * Each edge has this Steiner Node either as sink or as source node. */ protected TreeSet<SteinerEdge> edges; /* * needed to reconstruct paths */ protected SteinerNode predecessor ; protected String relationToPredecessor; protected float weightToPredecessor; protected boolean wasArg1; protected double [] distancesToSources=new double [2]; protected SteinerEdge predecessorLink; /* * for BANKS II */ public SteinerNode(String id){ super(id); edges= new TreeSet<>(); } /** * copies only the name of the node * @return */ public SteinerNode copy(){ SteinerNode newNode = new SteinerNode(this.name); return newNode; } public int hashCode(){ return name.hashCode(); } /** * sets n as the predecessor of this node, during a search process... * ...needed for rebuilding issues... * @param n */ public void setPredecessor(SteinerNode n){ predecessor=n; } /** * @param e * @return the neighbor connected to this node through the steiner edge e */ public SteinerNode getNeighborInEdge(SteinerEdge e){ if(e.sourceNode.equals(this)) return e.sinkNode; else if(e.sinkNode.equals(this)) return e.sourceNode; else return null; } /** * @param n * @return the steiner edge that connects this node to n */ public SteinerEdge getEdgeToNode(SteinerNode n){ SteinerEdge e=null; for(SteinerEdge edge: edges){ if(edge.sourceNode.equals(n)||edge.sinkNode.equals(n)){ e=edge; break; } } return e; } public String getEdgeLabelToNode(SteinerNode n){ return getEdgeToNode(n).label().name; } /** * * @return all neighbors of this steiner node */ public TreeSet<SteinerNode> getNeighbors(){ TreeSet<SteinerNode> ts = new TreeSet<>(); for(SteinerEdge e: edges){ if(e.sourceNode.equals(this)) ts.add(e.sinkNode); if(e.sinkNode.equals(this)) ts.add(e.sourceNode); } return ts; } /** * * @param exceptForEdge * @return return all neighbors of this node except for the node connected to this node * through exceptForEdge */ public TreeSet<SteinerNode> getNeighbors(SteinerEdge exceptForEdge){ TreeSet<SteinerNode> ts = new TreeSet<>(); if(exceptForEdge==null){ return getNeighbors(); } else for(SteinerEdge e: edges) if(!e.equals(exceptForEdge)){ if(e.sourceNode.equals(this)) ts.add(e.sinkNode); if(e.sinkNode.equals(this)) ts.add(e.sourceNode); } return ts; } public void addEdge(SteinerEdge edge){ if(edge.sourceNode.equals(this)){ edges.add(edge); edge.sinkNode.edges.add(edge); } if( edge.sinkNode.equals(this)){ edges.add(edge); edge.sourceNode.edges.add(edge); } } /** * * @param n the new node connected to this node through the new steiner edge to be added * @param isSourceNode boolean variable indicating whether n is the source node * in the new steiner edge (which is going to be added) * @param l label of the new edge * @param weight weight of the new edge */ public void addEdge(SteinerNode n, boolean isSourceNode, String l, float weight){ if(isSourceNode) addEdge(new SteinerEdge(n,l,this,weight)); else addEdge(new SteinerEdge(this, l, n,weight)); } /** * deletes all edges of this node * */ public void deleteEdges(){ edges= new TreeSet<>(); } /** * @param e steiner edge to be removed */ public void deleteEdge(SteinerEdge e){ Set<SteinerEdge> badEdges= new TreeSet<>(); for(SteinerEdge e1: edges) if(e1.sinkNode.equals(e.sinkNode)&& e1.sourceNode.equals(e.sourceNode)) badEdges.add(e1); edges.removeAll(badEdges); } /** * * @return number of edges this node is involved in */ public int getDegree(){ return edges.size(); } /** * * @return true if this node has more than two edges */ public boolean isFixedNode(){ return edges.size()>=3; } public String getNodeId(){ return name; } public String getRelationToPredecessor() { return relationToPredecessor; } public void setRelationToPredecessor(String relationToPredecessor) { this.relationToPredecessor = relationToPredecessor; } public boolean isWasArg1() { return wasArg1; } public void setWasArg1(boolean wasArg1) { this.wasArg1 = wasArg1; } public float getWeightToPredecessor() { return weightToPredecessor; } public void setWeightToPredecessor(float weightToPredecessor) { this.weightToPredecessor = weightToPredecessor; } public SteinerNode getPredecessor() { return predecessor; } public TreeSet<SteinerEdge> getEdges() { return edges; } }