/** Resets this graph before locating a path */ private boolean reset(List<BusinessTable> requiredTables) { try { // reset required tables and nodes this.requiredTables = requiredTables; if (needsReset) { // Don't need to reset first-time through if (this.searchStack != null) { this.searchStack.clear(); } // Clear required-status from nodes for (Node n : nodes) { n.clearRequirement(); } // Clear required-status from arcs for (Arc a : arcs) { a.clearRequirement(); } } else { this.needsReset = true; } // initialize nodes for (Node n : nodes) { if (requiredTables.contains(n.getTable())) { n.setRequirement(true); } } return true; } catch (ConsistencyException cx) { logger.debug("failed to reset", cx); return false; } }
public JSONObject asJSONTreeAux(ConcurrentHashMap<DomainConcept, DomainConcept> written) { JSONObject jsonObj = new JSONObject(); try { jsonObj.put("class", "ClassModel"); jsonObj.put("id", id); if (written.contains(this)) { return jsonObj; } written.put(this, this); if (getHasArcs() != null) { JSONArray jsonHasArcs = new JSONArray(); for (Arc row : getHasArcs()) { jsonHasArcs.put(row.asJSONTreeAux(written)); } jsonObj.put("hasArcs", jsonHasArcs); } if (getHasPropertySet() != null) { jsonObj.put("hasPropertySet", getHasPropertySet().asJSONTreeAux(written)); } jsonObj.put("id", getId()); if (getHasDomainNodes() != null) { jsonObj.put("hasDomainNodes", getHasDomainNodes().asJSONTreeAux(written)); } written.remove(this); } catch (Exception e1) { logWriter.error("Error in marshalling to JSON ", e1); } return jsonObj; }
private void dumpStateToLog() { if (logger.isDebugEnabled()) { logger.debug("-------------------------------------------------"); for (Arc arc : arcs) { if (arc.isRequired()) { logger.debug(arc + "-> Yes"); } else if (arc.isNotRequired()) { logger.debug(arc + "-> No"); } else { logger.debug(arc + "-> ?"); } } for (Node n : nodes) { if (n.isRequired()) { logger.debug(n + "-> Yes"); } else if (n.isNotRequired()) { logger.debug(n + "-> No"); } else { logger.debug(n + "-> ?"); } } logger.debug("================================================="); } }
/** Calculates graph validity */ private boolean isValid(PathType searchTechnique) { // remove all arcs from queue extendedNodeQueue.clear(); // initialize node queue with all nodes in graph basicNodeQueue.clear(); basicNodeQueue.addAll(nodes); try { // check for all search technique if (searchTechnique == PathType.ALL) { for (Node n : nodes) { n.setRequirement(true); } for (Arc a : arcs) { a.setRequirement(true); } } // start by making initial graph consistent propagate(); // search to test assigning a requirement setting // to tables not yet determined search(searchTechnique); return true; } catch (ConsistencyException cx) { logger.debug("failed to validate", cx); return false; } }
@Override public int compareTo(Object o) { Arc arc = (Arc) o; if (this.getBegin() == arc.getBegin()) { return this.getEnd() - arc.getBegin(); } return this.getBegin() - arc.getBegin(); }
public void deleteArc(Arc arcOfElt) { for (int i = 0; i < exits.length; i++) { Arc exit = exits[i]; if (exit != null && exit.equals(arcOfElt)) { exits[i] = null; } } }
// Methods public boolean ContainsOnEdge(Cartesian p) { for (Arc arc : this.getArcList()) { if (arc.ContainsOnEdge(p)) { return true; } } return false; }
public List<E> getStations() { Set<E> stations = new LinkedHashSet<>(); for (Arc<E> arc : arcs) { stations.add(arc.getStart()); stations.add(arc.getEnd()); } return new ArrayList<>(stations); }
@Override public void setup() { setSize(800, 600); arc.setFillColor(new RGBColor(0.3, 0.7, 0.3)); arc.setStrokeColor(new RGBColor(0.5, 0.9, 0.5)); arc.setStrokeWidth(10); addObject(arc); }
/** * Determines if a transition is enabled in this marking * * @param transition - transition to be checked * @return true if transition is enabled in the marking, otherwise false */ public boolean isEnabled(Transition transition) { boolean isEnabled = true; lock.readLock().lock(); try { for (Arc arc : transition.getConnectedArcs()) { if (arc.isPlaceToTransition()) { if (arc.getReset()) { // reset arc is always fireable continue; // but can be blocked by other arcs } else { if (!arc.getInhibitory()) { if (getTokens(arc.getPlaceNode()) < arc.getMultiplicity()) { // normal arc isEnabled = false; break; } } else { if (getTokens(arc.getPlaceNode()) >= arc.getMultiplicity()) { // inhibitory arc isEnabled = false; break; } } } } } } finally { lock.readLock().unlock(); } return isEnabled; }
public void REinit() { Arc a; for (int i = 0; i < this.ListeArcs.size(); i++) { a = this.ListeArcs.elementAt(i); a.etat = 'r'; a.nbre_veh = 0; for (int j = 0; j < a.ListeCellules.size(); j++) { a.ListeCellules.elementAt(j).oqp = false; } } // demarrer toutes les sources: for (int i = 0; i < this.ListeDesSources.size(); i++) { this.ListeDesSources.elementAt(i).demarrer_source(); } }
Solution( List<Arc> arcs, int rating, List<SearchDirection> searchPath, List<Arc> searchArcs, boolean partial) { this.rating = rating; this.searchPath = searchPath; this.searchArcs = searchArcs; this.partial = partial; this.solutionValues = new LinkedList<Boolean>(); for (Arc a : arcs) { solutionValues.add(a.isRequired()); } }
/** * Attempts to assign an arc to a given requirement status and returns true if consistency may * still be possible */ private boolean attemptArcAssignment(Arc arc, SearchDirection direction) { // initialize search stack for roll back pushSearchStack(); // try to assign value to element and propagate changes // to other elements. If propagation fails, rollback changes try { if (logger.isDebugEnabled()) { logger.debug("Attempting move - Direction[" + direction + "], Arc[" + arc + "]"); } arc.setRequirement((direction == SearchDirection.LEFT) ? false : true); propagate(); if (logger.isDebugEnabled()) { logger.debug("Move succeeded - State after move"); dumpStateToLog(); } return true; } catch (ConsistencyException cx) { logger.debug("Move failed"); popSearchStack(); return false; } }
public boolean canBeUnfired(Transition transition) { boolean canBeUnfired = true; lock.readLock().lock(); try { for (Arc arc : transition.getConnectedArcs()) { if (!arc.isPlaceToTransition()) { if (getTokens(arc.getPlaceNode()) < arc.getMultiplicity()) { canBeUnfired = false; break; } } } } finally { lock.readLock().unlock(); } return canBeUnfired; }
/** * Calculates and returns a path that satisfies the required tables list or null if one cannot be * found * * @param requiredTables Tables that are required to be in path * @return Path with smallest number of relationships to ensure all required tables are included */ public Path getPath(PathType searchTechnique, List<BusinessTable> requiredTables) { // if reset works and validity check passes, build path if (reset(requiredTables) && isValid(searchTechnique)) { logger.debug("Path determined sucessfully"); Path path = new Path(); for (Arc arc : arcs) { if (arc.isRequired()) { if (logger.isDebugEnabled()) { logger.debug("Arc selected for path: " + arc); } path.addRelationship(arc.getRelationship()); } else if (logger.isDebugEnabled()) { logger.debug( "Arc not used for path: Requirement Known[" + arc.isRequirementKnown() + "], Required[" + arc.isRequired() + "]"); } } if (logger.isDebugEnabled()) { for (Node n : nodes) { logger.debug( "Node selection state: Requirement Known[" + n.isRequirementKnown() + "], Required[" + n.isRequired() + "]"); } } if (path.size() > 0) { return path; } } return null; }
// Todos os arcos: Gera o resultado a partir de um objeto da classe Documento, // explicitando as relacoes entre os arcos em forma de Strings public void execute(CommandAllArcs command) throws ParserConfigurationException, SAXException, IOException, SQLException, ClassNotFoundException { if (this.filePrint) { this.context.addResult("Using file " + command.getFile()); this.context.addResult(""); } Expansor expansor = this.getDTS(command); Vector<Arc> documentArcs = new Vector<Arc>(); Vector<Arc> filteredArcs = new Vector<Arc>(); for (int i = 0; documentSet.size() > i; i++) { documentArcs.clear(); filteredArcs.clear(); if (this.filePrint) this.context.addResult( "Arcs from " + ((XmlDocument) documentSet.get(i)).getDocumentName() + ": "); documentArcs = ((XmlDocument) documentSet.get(i)).getArcs(expansor.getInicialDocument(this.base)); filteredArcs = expansor.getFilteredArcs(documentArcs, this.arcsFilter); for (int j = 0; filteredArcs.size() > j; j++) { Arc arc = filteredArcs.get(j); if (this.filePrint) this.context.addResult( "Exist arc between " + arc.getLabelFrom() + " (" + arc.getNodesFrom().size() + ") and " + arc.getLabelTo() + " (" + arc.getNodesTo().size() + ")"); } if (this.filePrint) this.context.addResult(""); addArcs(filteredArcs); } }
/** method to marshall data from caching layer object to JSON * */ public JSONObject asJSON() { JSONObject jsonObj = new JSONObject(); try { jsonObj.put("class", "ClassModel"); jsonObj.put("id", id); if (getHasArcs() != null) { JSONArray jsonHasArcs = new JSONArray(); for (Arc row : getHasArcs()) { jsonHasArcs.put(row.getId()); } jsonObj.put("hasArcs", jsonHasArcs); } if (getHasPropertySet() != null) { jsonObj.put("hasPropertySet", getHasPropertySet().getId()); } jsonObj.put("id", getId()); if (getHasDomainNodes() != null) { jsonObj.put("hasDomainNodes", getHasDomainNodes().getId()); } } catch (Exception e1) { logWriter.error("Error in marshalling to JSON ", e1); } return jsonObj; }
public void undoFire(Transition transition) { lock.writeLock().lock(); try { if (canBeUnfired(transition)) { for (Arc arc : transition.getConnectedArcs()) { if (!arc.isPlaceToTransition()) { int tokens = getTokens(arc.getPlaceNode()); setTokens(arc.getPlaceNode(), tokens - arc.getMultiplicity()); } else { int tokens = getTokens(arc.getPlaceNode()); setTokens(arc.getPlaceNode(), tokens + arc.getMultiplicity()); } } } } finally { lock.writeLock().unlock(); } }
public void specificArc(CommandXPathPlus command) throws ParserConfigurationException, SAXException, IOException, SQLException, ClassNotFoundException { if (this.filePrint) { this.context.addResult("Using file " + command.getFile()); this.context.addResult(""); } Expansor expansor = this.getDTS(command); Vector<Arc> documentArcs = new Vector<Arc>(); Vector<Arc> filteredArcs = new Vector<Arc>(); for (int i = 0; documentSet.size() > i; i++) { documentArcs.clear(); filteredArcs.clear(); if (this.filePrint) this.context.addResult( "Arcs from " + ((XmlDocument) documentSet.get(i)).getDocumentName() + ": "); documentArcs = ((XmlDocument) documentSet.get(i)) .getArcs( expansor.getInicialDocument( this.startpoint == null ? StartPoint.INSTANCE : this.startpoint.getBase())); filteredArcs = expansor.getFilteredArcs(documentArcs, this.arcsFilter); for (int j = 0; filteredArcs.size() > j; j++) { Arc arc = filteredArcs.get(j); if (arc.getLabelFrom().equalsIgnoreCase(command.getElement()) || (arc.getLabelTo().equalsIgnoreCase(command.getElement()))) { if (this.filePrint) this.context.addResult( "Exist arc between " + arc.getLabelFrom() + " (" + arc.getNodesFrom().size() + ") and " + arc.getLabelTo() + " (" + arc.getNodesTo().size() + ")"); } } if (this.filePrint) this.context.addResult(""); addArcs(filteredArcs); } }
/** * Performs work of propagating changes from source nodes to target nodes until consistency is * reached * * @throws ConsistencyException When current graph cannot be made consistent */ private void propagate() throws ConsistencyException { logger.debug("Beginning propagation"); // first prune all non-required nodes for (Node n : nodes) { n.prune(); } // process until queues are empty while (basicNodeQueue.size() > 0 || extendedNodeQueue.size() > 0) { // process basic node consistency enforcement because it's // faster than the extended arc propagation checks if (basicNodeQueue.size() > 0) { Node source = (Node) basicNodeQueue.remove(); // check if source node is bound to a requirement setting // before processing arcs if (source.isRequirementKnown()) { // get list of arcs originating at node List<Arc> sourceArcs = source.getArcs(); for (Arc arc : sourceArcs) { Node target = (arc.getLeft() == source) ? arc.getRight() : arc.getLeft(); // if source is not required, arc is not required and // we can try and prune the target if (source.isNotRequired()) { arc.setRequirement(false); target.prune(); } } } } else { // process extended enforcement of arc constraints on altered nodes // since we need to make sure that any node that is connected already Node source = (Node) extendedNodeQueue.remove(); // enforce arc constraints on nodes List<Arc> sourceArcs = source.getArcs(); for (Arc arc : sourceArcs) { arc.propagate(source); } } } // build required nodes list List<Node> requiredNodes = new LinkedList<Node>(); for (Node n : nodes) { if (n.isRequired()) { requiredNodes.add(n); } } // make sure all required nodes can reach one another before returning // to ensure consistency if (requiredNodes.size() > 1) { List<Node> targetList = new LinkedList<Node>(requiredNodes); Node start = requiredNodes.remove(0); if (!start.canReachAllNodes(targetList)) { logger.debug( "Arc propagation completed, but not all targets could be reached from first node"); throw new ConsistencyException(start); } } logger.debug("Propagation completed successfully"); }
/** * Fires a transition in this marking. Changes this marking. * * @param transition transition to be fired in the marking * @return false if the specified transition was not enabled, otherwise true */ public boolean fire(Transition transition) { boolean success; lock.writeLock().lock(); try { if (isEnabled(transition)) { for (Arc arc : transition.getConnectedArcs()) { if (arc.isPlaceToTransition()) { int tokens = getTokens(arc.getPlaceNode()); if (!arc.getInhibitory()) { // inhibitory arc doesnt consume tokens if (arc.getReset()) { // reset arc consumes them all setTokens(arc.getPlaceNode(), 0); } else { setTokens(arc.getPlaceNode(), tokens - arc.getMultiplicity()); } } } else { int tokens = getTokens(arc.getPlaceNode()); setTokens(arc.getPlaceNode(), tokens + arc.getMultiplicity()); } } success = true; } else { success = false; } } finally { lock.writeLock().unlock(); } return success; }
// Not used. Could be implemented in a better way void organizeNetGraphically() { int thresholdXDistanceApart = 100; int thresholdYDistanceApart = 30; double currentX; double currentY; int size = newTransitions.size(); // otherwise there are no transitons to seperate from each other if (size > 1) { boolean madeAMove = true; while (madeAMove) { madeAMove = false; /* * for(int i = 0; i < size-1; i++){ double prevX = * newTransitions.get(i).getPositionX(); double prevY = * newTransitions.get(i).getPositionY(); for(int j = i+1; * j<size; j++){ currentX = * newTransitions.get(j).getPositionX(); currentY = * newTransitions.get(j).getPositionY(); if((currentX - prevX) > * -thresholdXDistanceApart && Math.abs(currentY - prevY) < * thresholdYDistanceApart){ * newTransitions.get(j).setPositionX(-thresholdXDistanceApart + * prevX); System.out.println("shifting" + * newTransitions.get(i).getId() + ": " + * -thresholdXDistanceApart + prevX); } else if((currentX - * prevX) < thresholdXDistanceApart && Math.abs(currentY - * prevY) < thresholdYDistanceApart){ * newTransitions.get(j).setPositionX(thresholdXDistanceApart + * prevX); System.out.println("shifting" + * newTransitions.get(i).getId() + ": " + * thresholdXDistanceApart + prevX); madeAMove = true; break; } * * } } */ } } // Now align all x position of places with respective transitions for (int i = 0; i < newPlaces.size(); i++) { Iterator<?> it = newPlaces.get(i).getConnectFromIterator(); if (it.hasNext()) { Arc a = (Arc) it.next(); PipeTransition t = (PipeTransition) a.getTarget(); newPlaces.get(i).setPositionX(t.getPositionX()); } } // Now separate all places from each other size = newPlaces.size(); // otherwise there are no transitons to seperate from each other if (size > 1) { for (int i = 0; i < size - 1; i++) { double prevX = newPlaces.get(i).getPositionX(); double prevY = newPlaces.get(i).getPositionY(); for (int j = i + 1; j < size; j++) { currentX = newPlaces.get(j).getPositionX(); currentY = newPlaces.get(j).getPositionY(); /* * if((currentX - prevX) < -thresholdXDistanceApart){ * newPlaces.get(j).setPositionX(-thresholdXDistanceApart + * prevX && Math.abs(currentY - prevY) < * thresholdYDistanceApart); } else */ if ((currentX - prevX) < thresholdXDistanceApart && Math.abs(currentY - prevY) < thresholdYDistanceApart) { newPlaces.get(j).setPositionX(thresholdXDistanceApart + prevX); } } } } }
/** Precomputation. */ public void precomputeArcFlags(double latMin, double latMax, double lngMin, double lngMax) { List<Arc> arcs; Arc arc0; Node headNode; Node tailNode; // compute boundary nodes for (int i = 0; i < graph.getAdjacentArcs().size(); i++) { arcs = graph.getAdjacentArcs().get(i); tailNode = graph.getMapNodeId().get(graph.getNodeIds().get(i)); // if tailNode is in region, check if it is a boundary node if (isInRegion(latMin, latMax, lngMin, lngMax, tailNode)) { for (int j = 0; j < arcs.size(); j++) { arc0 = arcs.get(j); headNode = arc0.headNode; if (!isInRegion(latMin, latMax, lngMin, lngMax, headNode)) { if (!boundaryNodes.contains(tailNode.id)) { boundaryNodes.add(tailNode.getId()); } // break; } else { // set arcFlag to true for arcs inside the region arc0.arcFlag = true; } } } } System.out.println("---All boundary nodes found---"); System.out.println("#Of Boundary nodes: " + boundaryNodes.size()); // compute Dijkstra for each of the boundary nodes // saves the map parents into a list for (int i = 0; i < boundaryNodes.size(); i++) { long boundaryNodeId = boundaryNodes.get(i); DijkstraAlgorithm dijAlg = new DijkstraAlgorithm(graph); dijAlg.computeShortestPath(boundaryNodeId, -1); // we set flags Map<Long, Long> parents = dijAlg.getParents(); Iterator<Long> it = parents.keySet().iterator(); while (it.hasNext()) { Long currentNodeId = (Long) it.next(); Long parentNodeId = parents.get(currentNodeId); // System.out.println(currentNodeId + "-" + parentNodeId); if (parentNodeId != -1) { List<Arc> allArcs = graph.getNodeAdjacentArcs(currentNodeId); for (int k = 0; k < allArcs.size(); k++) { Arc arc = allArcs.get(k); if (arc.getHeadNode().getId() == parentNodeId) { arc.arcFlag = true; } } } } // System.out.println(numberOfArcProBNode); System.out.print(i + " - "); } System.out.println("\n---Dijkstra for all boundary node completed---"); /* * for (int i = 0; i < parentsOfBoundaryNodes.size(); i++) { Map<Integer, * Integer> parents = parentsOfBoundaryNodes.get(i); Iterator<Integer> it = * parents.keySet().iterator(); while (it.hasNext()) { Integer currentNode = * (Integer) it.next(); Integer parentNode = parents.get(currentNode); * List<Arc> allArcs = graph.getNodeAdjacentArcs(parentNode); * * for (int k = 0; k < allArcs.size(); k++) { Arc arc = allArcs.get(k); if * (arc.getHeadNode().getId() == currentNode) { arc.arcFlag = true; } } } } */ // exportToFile(boundaryNodes); System.out.println("---Finish boundary nodes!---"); // TODO: mark arcFlags to arcs in shortest paths to boundary nodes. }
public void actionPerformed(ActionEvent event) { if (d.again) { initTree(tree); d.again = false; } if (event.getSource() == send) { String c1 = attachment1.getText(); String c2 = attachment2.getText(); String c3 = valueOfArc.getText(); if (c1.matches(regularExpression) && c2.matches(regularExpression) && c3.matches(regularExpression)) { int s1 = Integer.parseInt(c1); int s2 = Integer.parseInt(c2); int value = Integer.parseInt(c3); if (s1 <= d.getNumberOfNodes() && s2 <= d.getNumberOfNodes() && s1 != s2) { Arc a = new Arc(s1, s2, value); boolean already = false; int emplacement = 0; int i = 0; while (tree[i] != null && i < tree.length) { if ((tree[i].getNode1() == a.getNode1() || tree[i].getNode1() == a.getNode2()) && (tree[i].getNode2() == a.getNode1() || tree[i].getNode2() == a.getNode2())) { emplacement = i; already = true; } i++; } if (!already) { tree[d.getNumberOfArc()] = a; d.addArc(a, d.getNumberOfArc()); } else { tree[emplacement].setCost(value); d.modifArc(emplacement, value); } d.repaint(); } } } else if (event.getSource() == step) { if (tree[0] != null) { if (d.getCpt() == 0) { if (d.getChoice().equals("Kruskal")) { k = new Kruskal(tree, d.getNumberOfNodes(), d.getNumberOfArc()); d.finalTree = k.tree; } d.end = true; } if (d.finalTree[d.getCpt()] != null) { d.setCpt(d.getCpt() + 1); } d.repaint(); } } }
/** * Attempts to find next valid solution to the graph depending on what type of <code>PathType * </code> is desired. * * @param searchTechnique Indicates type of search that should be performed * @param prevSolution Previous solution to allow this search to continue from that point * @return The resulting solution * @throws ConsistencyException When determine that graph is impossible to satisfy */ private Solution searchForNextSolution(PathType searchTechnique, Solution prevSolution) throws ConsistencyException { // A left move equates to setting a requirement to false and a right move is equivalent to true. // Try setting to "false" first to reduce the number of tables for most searches. // For the "any relevant" search use "true" first which is quicker SearchDirection firstDirection; SearchDirection secondDirection; if (searchTechnique == PathType.ANY_RELEVANT) { firstDirection = SearchDirection.RIGHT; secondDirection = SearchDirection.LEFT; } else { firstDirection = SearchDirection.LEFT; secondDirection = SearchDirection.RIGHT; } // if this is a subsequent search after a solution was already found, we need // to return to the location where the last move in the first direction was made List<SearchDirection> searchPath = new LinkedList<SearchDirection>(); List<Arc> searchArcs = new LinkedList<Arc>(); if (prevSolution != null) { // check for situation where we have already traversed all possible paths boolean prevContainsFirstDirection = false; for (SearchDirection direction : prevSolution.searchPath) { if (direction == firstDirection) { prevContainsFirstDirection = true; break; } } if (!prevContainsFirstDirection) { return null; } ListIterator<SearchDirection> pathIter = prevSolution.searchPath.listIterator(prevSolution.searchPath.size()); // continue to move back in search path until we find an arc that can // be assigned the second direction boolean foundSecondDir = false; while (pathIter.hasPrevious() && !foundSecondDir) { // reset the search function for next search operation reset(requiredTables); propagate(); searchPath.clear(); searchArcs.clear(); // locate the last move that has an alternative while (pathIter.hasPrevious()) { SearchDirection direction = pathIter.previous(); if (direction == firstDirection) { break; } } // recreate path up to point where we can try a different direction Iterator<Arc> arcIter = prevSolution.getSearchArcs().iterator(); if (pathIter.hasPrevious()) { Iterator<SearchDirection> redoIter = prevSolution.getSearchPath().iterator(); int lastIdx = pathIter.previousIndex(); for (int idx = 0; idx <= lastIdx; idx++) { // all of these operations should work without issue SearchDirection direction = redoIter.next(); Arc arc = arcIter.next(); if (!attemptArcAssignment(arc, direction)) { throw new ConsistencyException(arc); } // add movement to newly constructed search path searchPath.add(direction); searchArcs.add(arc); } } // before any searching will begin, make sure the path we are going down shouldn't // just be skipped int rating = getRatingForCurrentState(searchTechnique); // current state isn't any better, return it as next solution if (rating >= prevSolution.getRating()) { return new Solution(arcs, rating, searchPath, searchArcs, true); } // retrieve arc which we are going to move second direction Arc arc = arcIter.next(); // if we can't move the second direction here, continue // to move back in search path until we find an arc that can // be assigned the second direction if (attemptArcAssignment(arc, secondDirection)) { // update new search path searchPath.add(secondDirection); searchArcs.add(arc); // before any searching will begin, make sure the path we are going down shouldn't // just be skipped rating = getRatingForCurrentState(searchTechnique); // current state isn't any better, return it as next solution if (rating >= prevSolution.getRating()) { return new Solution(arcs, rating, searchPath, searchArcs, true); } // set second direction flag so search will continue foundSecondDir = true; } } // if we weren't able to make another movement, there are not more solutions if (searchPath.size() == 0) { return null; } } // dump current state of graph if (logger.isDebugEnabled()) { logger.debug("-- Graph State Before Search --"); dumpStateToLog(); } // look for arcs that are not bound int rating = -1; for (Arc a : arcs) { if (!a.isRequirementKnown()) { // try the first direction if (attemptArcAssignment(a, firstDirection)) { searchPath.add(firstDirection); } else if (attemptArcAssignment( a, secondDirection)) { // if first direction fails, try the second searchPath.add(secondDirection); } else { // If arc cannot be assigned a requirement value, throw an exception throw new ConsistencyException(a); } // record arc that was altered in search path searchArcs.add(a); // make sure solution is getting better if (prevSolution != null) { rating = getRatingForCurrentState(searchTechnique); // current state isn't any better, return it as next solution if (rating >= prevSolution.getRating()) { return new Solution(arcs, rating, searchPath, searchArcs, true); } } } } // compute rating if never computed if (rating < 0) { rating = getRatingForCurrentState(searchTechnique); } // return solution to graph problem return new Solution(arcs, rating, searchPath, searchArcs, false); }