List of usage examples for org.apache.commons.collections.buffer PriorityBuffer size
int size
To view the source code for org.apache.commons.collections.buffer PriorityBuffer size.
Click Source Link
From source file:de._13ducks.cor.game.server.movement.SubSectorPathfinder.java
/** * Sucht einen Weg auf Freiflchen (FreePolygon) um ein Hindernis herum. * Beachtet weitere Hindernisse auf der "Umleitung". * Sucht die Route nur bis zum nchsten Ziel. * Der Mover darf sich nicht bereits auf einer Umleitung befinden, * diese muss ggf vorher gelscht worden sein. * @param mover/*w w w . j a va 2 s . c om*/ * @param obstacle * @return */ static List<SubSectorEdge> searchDiversion(Moveable mover, Moveable obstacle, SimplePosition target) { // Vorberprfung: Ist das Ziel berhaupt noch frei? List<Moveable> moversAroundTarget = Server.getInnerServer().moveMan.moveMap .moversAroundPoint(target.toFPP(), mover.getRadius() + 5); moversAroundTarget.remove(mover); // Falls drin for (Moveable m : moversAroundTarget) { if (m.getPrecisePosition().getDistance(target.toFPP()) < m.getRadius() + mover.getRadius() + ServerBehaviourMove.MIN_DISTANCE) { System.out.println("No div, target blocked!"); return null; } } /** * Wegsuche in 2 Schritten: * 1. Aufbauen eines geeigneten Graphen, der das gesamte Problem enthlt. * 2. Suchen einer Route in diesem Graphen mittels A* (A-Star). */ // Aufbauen des Graphen: ArrayList<SubSectorObstacle> graph = new ArrayList<SubSectorObstacle>(); // Der Graph selber LinkedList<Moveable> openObstacles = new LinkedList<Moveable>(); // Die Liste mit noch zu untersuchenden Knoten ArrayList<Moveable> closedObstacles = new ArrayList<Moveable>(); // Bearbeitete Knoten openObstacles.add(obstacle); // Startpunkt des Graphen. closedObstacles.add(mover); // Wird im Graphen nicht mitbercksichtigt. double radius = mover.getRadius() + ServerBehaviourMove.MIN_DISTANCE; while (!openObstacles.isEmpty()) { // Neues Element aus der Liste holen und als bearbeitet markieren. Moveable work = openObstacles.poll(); closedObstacles.add(work); SubSectorObstacle next = new SubSectorObstacle(work.getPrecisePosition().x(), work.getPrecisePosition().y(), work.getRadius()); // Zuerst alle Punkte des Graphen lschen, die jetzt nichtmehr erreichbar sind: for (SubSectorObstacle obst : graph) { obst.removeNearNodes(next, radius); } // Mit Graph vernetzen for (SubSectorObstacle node : graph) { if (node.inColRange(next, radius)) { // Schnittpunkte suchen SubSectorNode[] intersections = node.calcIntersections(next, radius); for (SubSectorNode n2 : intersections) { boolean reachable = true; for (SubSectorObstacle o : graph) { if (o.equals(node)) { continue; // Um den gehts jetzt ja gerade, natrlich liegen wir auf diesem Kreis } if (o.moveCircleContains(n2, radius)) { reachable = false; break; } } if (reachable) { // Schnittpunkt einbauen next.addNode(n2); node.addNode(n2); } } } } // Bearbeitetes selbst in Graph einfgen graph.add(next); // Weitere Hindernisse suchen, die jetzt relevant sind. List<Moveable> moversAround = Server.getInnerServer().moveMan.moveMap.moversAround(work, (work.getRadius() + radius) * 2); for (Moveable pmove : moversAround) { if (!closedObstacles.contains(pmove) && !openObstacles.contains(pmove)) { openObstacles.add(pmove); } } } // Jetzt drber laufen und Graph aufbauen: for (SubSectorObstacle obst : graph) { // Vorgensweise: // In jedem Hinderniss die Linie entlanglaufen und Knoten mit Kanten verbinden. // Ein Knoten darf auf einem Kreis immer nur in eine Richtung gehen. // (das sollte mithilfe seiner beiden, bekannten hindernisse recht einfach sein) // Die Lnge des Kreissegments lsst sich einfach mithilfe des winkels ausrechnen (Math.atan2(y,x) // Dann darf der A*. Bzw. Dijkstra, A* ist hier schon fast Overkill. // Alle Knoten ihrem Bogenma nach sortieren. obst.sortNodes(); obst.interConnectNodes(radius); } // Start- und Zielknoten einbauen und mit dem Graph vernetzten. SubSectorNode startNode = new SubSectorNode(mover.getPrecisePosition().x(), mover.getPrecisePosition().y()); SubSectorNode targetNode = new SubSectorNode(target.x(), target.y()); double min = Double.POSITIVE_INFINITY; SubSectorObstacle minObstacle = null; for (SubSectorObstacle obst : graph) { double newdist = Math.sqrt((obst.getX() - startNode.getX()) * (obst.getX() - startNode.getX()) + (obst.getY() - startNode.getY()) * (obst.getY() - startNode.getY())); newdist -= obst.getRadius() + radius; // Es interessiert uns der nchstmgliche Kreis, nicht das nchste Hinderniss if (newdist < min) { min = newdist; minObstacle = obst; } } // Punkt auf Laufkreis finden Vector direct = new Vector(startNode.getX() - minObstacle.getX(), startNode.getY() - minObstacle.getY()); direct = direct.normalize().multiply(minObstacle.getRadius() + radius); SubSectorNode minNode = new SubSectorNode(minObstacle.getX() + direct.getX(), minObstacle.getY() + direct.getY(), minObstacle); // In das Hinderniss integrieren: minObstacle.lateIntegrateNode(minNode); SubSectorEdge startEdge = new SubSectorEdge(startNode, minNode, min); if (!startNode.equals(minNode)) { startNode.addEdge(startEdge); minNode.addEdge(startEdge); } else { // Wir stehen schon auf dem minNode. // Die Einsprungkante ist nicht notwendig. startNode = minNode; } double min2 = Double.POSITIVE_INFINITY; SubSectorObstacle minObstacle2 = null; for (SubSectorObstacle obst : graph) { double newdist = Math.sqrt((obst.getX() - targetNode.getX()) * (obst.getX() - targetNode.getX()) + (obst.getY() - targetNode.getY()) * (obst.getY() - targetNode.getY())); newdist -= obst.getRadius() + radius; // Es interessiert uns der nchstmgliche Kreis, nicht das nchste Hinderniss if (newdist < min2) { min2 = newdist; minObstacle2 = obst; } } // Punkt auf Laufkreis finden Vector direct2 = new Vector(targetNode.getX() - minObstacle2.getX(), targetNode.getY() - minObstacle2.getY()); direct2 = direct2.normalize().multiply(minObstacle2.getRadius() + radius); SubSectorNode minNode2 = new SubSectorNode(minObstacle2.getX() + direct2.getX(), minObstacle2.getY() + direct2.getY(), minObstacle2); // In das Hinderniss integrieren: minObstacle2.lateIntegrateNode(minNode2); SubSectorEdge targetEdge = new SubSectorEdge(minNode2, targetNode, min2); if (!targetNode.equals(minNode2)) { targetNode.addEdge(targetEdge); minNode2.addEdge(targetEdge); } else { // Das Ziel ist schon auf dem Laufkreis. // Die Aussprungkante ist nicht ntig. targetNode = minNode2; } /** * Hier jetzt einen Weg suchen von startNode nach targetNode. * Die Kanten sind in node.myEdges * Die Ziele bekommt man mit edge.getOther(startNode) * Die Lnge (Wegkosten) stehen in edge.length (vorsicht: double-Wert!) */ PriorityBuffer open = new PriorityBuffer(); // Liste fr entdeckte Knoten LinkedHashSet<SubSectorNode> containopen = new LinkedHashSet<SubSectorNode>(); // Auch fr entdeckte Knoten, hiermit kann viel schneller festgestellt werden, ob ein bestimmter Knoten schon enthalten ist. LinkedHashSet<SubSectorNode> closed = new LinkedHashSet<SubSectorNode>(); // Liste fr fertig bearbeitete Knoten double cost_t = 0; //Movement Kosten (gerade 5, diagonal 7, wird spter festgelegt) open.add(startNode); while (open.size() > 0) { SubSectorNode current = (SubSectorNode) open.remove(); containopen.remove(current); if (current.equals(targetNode)) { //Abbruch, weil Weg von Start nach Ziel gefunden wurde //targetNode.setParent(current.getParent()); //"Vorgngerfeld" von Ziel bekannt break; } // Aus der open wurde current bereits gelscht, jetzt in die closed verschieben closed.add(current); ArrayList<SubSectorEdge> neighbors = current.getMyEdges(); for (SubSectorEdge edge : neighbors) { SubSectorNode node = edge.getOther(current); if (closed.contains(node)) { continue; } // Kosten dort hin berechnen cost_t = edge.getLength(); if (containopen.contains(node)) { //Wenn sich der Knoten in der openlist befindet, muss berechnet werden, ob es einen krzeren Weg gibt if (current.getCost() + cost_t < node.getCost()) { //krzerer Weg gefunden? node.setCost(current.getCost() + cost_t); //-> Wegkosten neu berechnen //node.setValF(node.cost + node.getHeuristic()); //F-Wert, besteht aus Wegkosten vom Start + Luftlinie zum Ziel node.setParent(current); //aktuelles Feld wird zum Vorgngerfeld } } else { node.setCost(current.getCost() + cost_t); //node.setHeuristic(Math.sqrt(Math.pow(Math.abs((targetNode.getX() - node.getX())), 2) + Math.pow(Math.abs((targetNode.getY() - node.getY())), 2))); // geschtzte Distanz zum Ziel //Die Zahl am Ende der Berechnung ist der Aufwand der Wegsuche //5 ist schnell, 4 normal, 3 dauert lange node.setParent(current); // Parent ist die RogPosition, von dem der aktuelle entdeckt wurde //node.setValF(node.cost + node.getHeuristic()); //F-Wert, besteht aus Wegkosten vom Start aus + Luftlinie zum Ziel open.add(node); // in openlist hinzufgen containopen.add(node); } } } if (targetNode.getParent() == null) { //kein Weg gefunden return null; } ArrayList<SubSectorNode> pathrev = new ArrayList<SubSectorNode>(); //Pfad aus parents erstellen, von Ziel nach Start while (!targetNode.equals(startNode)) { pathrev.add(targetNode); targetNode = targetNode.getParent(); } pathrev.add(startNode); ArrayList<SubSectorNode> path = new ArrayList<SubSectorNode>(); //Pfad umkehren, sodass er von Start nach Ziel ist for (int k = pathrev.size() - 1; k >= 0; k--) { path.add(pathrev.get(k)); } // Nachbearbeitung: // Wir brauchen eine Kanten-Liste mit arc/direct Informationen ArrayList<SubSectorEdge> finalPath = new ArrayList<SubSectorEdge>(); for (int i = 0; i < path.size() - 1; i++) { SubSectorNode from = path.get(i); SubSectorNode to = path.get(i + 1); SubSectorEdge edge = shortestCommonEdge(from, to); if (edge != null) { finalPath.add(edge); } else { throw new RuntimeException("ERROR Cannot find edge from " + from + " to " + to + " but it is part of the calculated path!!!"); } } return finalPath; //Pfad zurckgeben }
From source file:uk.ac.ebi.orchem.search.SimilaritySearch.java
/** * Performs a similarity search between a query molecule and the orchem fingerprint table. * * @param queryFp fingerprint of the query molecule * @param _cutOff tanimoto score below which to stop searching * @param _topN top N results after which to stop searching * @param debugYN Y or N to debug output back * @param idsOnlyYN Y or N to indicate to just return IDs of results (faster) * @param extraWhereClause option to include an extra SQL where clause refering to the base compound table * @return array of {@link uk.ac.ebi.orchem.bean.OrChemCompound compounds} * @throws Exception/* ww w . j a v a 2s .c om*/ */ private static oracle.sql.ARRAY search(BitSet queryFp, Float _cutOff, Integer _topN, String debugYN, String idsOnlyYN, String extraWhereClause) throws Exception { /* * The comment block below describes the search algorithm. From: "Bounds and Algorithms for Fast Exact Searches of Chemical Fingerprints in Linear and Sub-Linear Time" S.Joshua Swamidass and Pierre Baldi http://dx.doi.org/10.1021/ci600358f Top K Hits ---------- We can search for the top K hits by starting from the maximum (where A=B), and exploring discrete possible values of B right and left of the maximum. More precisely, for binary fingerprints, we first index the molecules in the database by their fingerprint "bit count" to enable efficient referencing of a particular bit count bin. Next, with respect to a particular query, we calculate the bound on the similarity for every bit count in the database. Then we sort these bit counts by their associated bound and iterate over the molecules in the database, in order of decreasing bound. As we iterate, we calculate the similarity between the query and the database molecule and use a heap to efficiently track the top hits. The algorithm terminates when "the lowest similarity value in the heap is greater than the bound associated with the current database bin" Algorithm 1 Top K Search Require: database of fingerprints binned by bit count Bs Ensure: hits contains top K hits which satisfy SIMILARITY( ) > T 1: hits <- MINHEAP() 2: bounds <- LIST() 3: for all B in database do //iterate over bins 4: tuple <- TUPLE(BOUND(A,B),B) 5: LISTAPPEND(bounds, tuple) 6: end for 7: QUICKSORT(bounds) //NOTE: the length of bounds is constant 8: for all bound, B in bounds do //iterate in order of decreasing bound 9: if bound < T then 10: break //threshold stopping condition 11: end if 12: if K HEAPSIZE(hits) and bound < MINSIMILARITY(hits) then 13: break //top-K stopping condition 14: end if 15: for all in database[B] do 16: S=SIMILARITY( ) 17: tuple <- TUPLE(S, ) 18: if S T then 19: continue //ignore this and continue to next 20: else if LENGTH(hits)< K then 21: HEAPPUSH(hits, tuple) 22: else if S > MINSIMILARITY(hits) then 23: HEAPPOPMIN(hits) 24: HEAPPUSH(hits,tuple) 25: end if 26: end for 27: end for 28: return hits */ boolean debugging = false; if (debugYN.toLowerCase().equals("y")) debugging = true; debug("started", debugging); /********************************************************************** * Similarity search algorithm section * * * **********************************************************************/ Comparator heapComparator = new SimHeapElementTanimComparator(); PriorityBuffer heap = null; OracleConnection conn = null; PreparedStatement pstmtFp = null; PreparedStatement pstmLookup = null; String query = " select bit_count, id, fp from orchem_fingprint_simsearch s where bit_count = ? "; float cutOff = _cutOff.floatValue(); int topN = -1; if (_topN == null) { debug("No topN breakout specified.. searching until lower bound reached", debugging); } else { topN = _topN.intValue(); debug("topN is " + topN + ", result set size limited.", debugging); } try { conn = (OracleConnection) new OracleDriver().defaultConnection(); String compoundTableName = OrChemParameters.getParameterValue(OrChemParameters.COMPOUND_TABLE, conn); String compoundTablePkColumn = OrChemParameters.getParameterValue(OrChemParameters.COMPOUND_PK, conn); String compoundTableMolfileColumn = OrChemParameters.getParameterValue(OrChemParameters.COMPOUND_MOL, conn); if (extraWhereClause != null) { query = " select s.bit_count, s.id, s.fp from " + " orchem_fingprint_simsearch s , " + compoundTableName + " c " + " where s.bit_count = ? " + " and s.id = c." + compoundTablePkColumn + " " + " and " + extraWhereClause; debug("QUERY is " + query, debugging); } float queryBitCount = queryFp.cardinality(); byte[] queryBytes = Utils.toByteArray(queryFp, extFpSize); int queryByteArrLen = queryBytes.length; float lowBucketNum = queryBitCount - 1; float highBucketNum = queryBitCount + 1; float currBucketNum = queryBitCount; pstmtFp = conn.prepareStatement(query); pstmtFp.setFetchSize(250); ResultSet resFp = null; boolean done = false; byte[] dbByteArray = null; float tanimotoCoeff = 0f; heap = new PriorityBuffer(true, heapComparator); int bucksSearched = 0; int loopCount = 0; while (!done) { debug("bucket is " + currBucketNum, debugging); loopCount++; pstmtFp.setFloat(1, currBucketNum); bucksSearched++; resFp = pstmtFp.executeQuery(); float bound = 0f; if (currBucketNum < queryBitCount) bound = currBucketNum / queryBitCount; else bound = queryBitCount / currBucketNum; /* Algorithm step 9..11 Here we can break out because the tanimoto score is becoming to low */ if (bound < cutOff) { debug("bound < cutOff, done", debugging); done = true; } if (!done) { //Algorithm 15-26 while (resFp.next()) { dbByteArray = resFp.getBytes("fp"); tanimotoCoeff = calcTanimoto(queryBytes, queryByteArrLen, dbByteArray, queryBitCount, currBucketNum); if (tanimotoCoeff >= cutOff) { SimHeapElement elm = new SimHeapElement(); elm.setID(resFp.getString("id")); elm.setTanimotoCoeff(new Float(tanimotoCoeff)); if (heap.size() < topN || topN == -1) { heap.add(elm); debug("add elem " + elm.getID(), debugging); } else if (tanimotoCoeff > ((SimHeapElement) (heap.get())).getTanimotoCoeff() .floatValue()) { heap.remove(); heap.add(elm); debug("remove + add elem " + elm.getID(), debugging); } } } resFp.close(); /* Algorithm 12-14: * When top N hits is reached, and the lowest score of the * hits is greater than the current bucket bound, stop. * If not, the next bucket may contain a better score, so go on. */ if (topN != -1 && heap.size() >= topN && ((SimHeapElement) (heap.get())).getTanimotoCoeff().floatValue() > bound) { done = true; debug("topN reached, done", debugging); } else { // calculate new currBucket float up = queryBitCount / highBucketNum; float down = lowBucketNum / queryBitCount; if (up > down) { currBucketNum = highBucketNum; highBucketNum++; } else { currBucketNum = lowBucketNum; lowBucketNum--; } if (lowBucketNum < 1 && highBucketNum > extFpSize) done = true; } } } debug("searched bit_count buckets: " + loopCount, debugging); /******************************************************************** * Search completed. * * * * Next section is just looking up the compounds by ID and * * returning the results, sorted by Tanimoto coefficient * * * *******************************************************************/ String lookupCompoundQuery = " select " + compoundTableMolfileColumn + " from " + " " + compoundTableName + " where " + " " + compoundTablePkColumn + " =?"; pstmLookup = conn.prepareStatement(lookupCompoundQuery); List compounds = new ArrayList(); while (heap.size() != 0) { SimHeapElement bElm = (SimHeapElement) heap.remove(); if (idsOnlyYN.equals("N")) { // return structure to user pstmLookup.setString(1, bElm.getID()); ResultSet resLookup = pstmLookup.executeQuery(); if (resLookup.next()) { OrChemCompound c = new OrChemCompound(); c.setId(bElm.getID()); c.setScore(bElm.getTanimotoCoeff().floatValue()); c.setMolFileClob(resLookup.getClob(compoundTableMolfileColumn)); compounds.add(c); } resLookup.close(); } else { // only return ID and score to user OrChemCompound c = new OrChemCompound(); c.setId(bElm.getID()); c.setScore(bElm.getTanimotoCoeff().floatValue()); compounds.add(c); } } pstmLookup.close(); long befSort = System.currentTimeMillis(); Collections.sort(compounds, new OrChemCompoundTanimComparator()); debug("sorting time (ms) " + (System.currentTimeMillis() - befSort), debugging); OrChemCompound[] output = new OrChemCompound[compounds.size()]; for (int i = 0; i < compounds.size(); i++) { output[i] = (OrChemCompound) (compounds.get(i)); } ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("ORCHEM_COMPOUND_LIST", conn); debug("#compounds in result list : " + compounds.size(), debugging); debug("ended", debugging); return new ARRAY(arrayDescriptor, conn, output); } catch (Exception ex) { ex.printStackTrace(); throw (ex); } finally { if (pstmLookup != null) pstmLookup.close(); if (pstmtFp != null) pstmtFp.close(); if (conn != null) conn.close(); } }