void prim(Graph graph, char startNode){ PriorityQueue priorityQueue; Node node; node.key = INT_MAX; node.pi = '\0'; // for (auto it = graph.getVertices().begin(); it != graph.getVertices().end(); it++){ // node.name = *it; // priorityQueue.push(node); // } string tempString = ""; for (auto it = graph.getVertices().begin(); it != graph.getVertices().end(); it++) tempString += *it; cout << tempString << "!!!" << endl; for (int i = 0; i < tempString.length(); i++){ node.name = tempString.c_str()[i]; priorityQueue.push(node); } // Node node; // node.key = INT_MAX; // node.pi = '\0'; // node.name = 'i'; // priorityQueue.push(node); // node.name = 'a'; // priorityQueue.push(node); // node.name = 'b'; // priorityQueue.push(node); // node.name = 'c'; // priorityQueue.push(node); // node.name = 'd'; // priorityQueue.push(node); // node.name = 'e'; // priorityQueue.push(node); // node.name = 'f'; // priorityQueue.push(node); // node.name = 'g'; // priorityQueue.push(node); // node.name = 'h'; // priorityQueue.push(node); cout << "finished inserting vertices" << endl; priorityQueue.decreaseKey(startNode, 0, '\0'); while (!priorityQueue.empty()){ Node node = priorityQueue.extractMin(); cout << "extracted: " << node.name << ": " << node.key << ", " << node.pi << endl; if (node.name != node.pi && node.pi != '\0') cout << "(" << node.name << ", " << node.pi << ") " << endl; for (auto it = graph.getEdges().begin(); it != graph.getEdges().end(); it++){ cout << "checking " << it->first << endl; if (it->first.c_str()[0] == node.name || it->first.c_str()[1] == node.name){// Adjacency char adjacency = (it->first.c_str()[0] == node.name)?it->first.c_str()[1]:it->first.c_str()[0]; cout << "going for adj" << adjacency << endl; if (priorityQueue.find(adjacency) && priorityQueue.getNode(adjacency).key > graph.getWeight(node.name, adjacency)){ cout << "decreasingKey: " << adjacency << ", w: " << graph.getWeight(node.name, adjacency) << ", " << node.name << endl; priorityQueue.decreaseKey(adjacency, graph.getWeight(node.name, adjacency), node.name); } } } } cout << endl; }
void emptyFrameQueue(){ while(!frameQueue.empty()){ frameQueue.pop(); } }
void printQueue(PriorityQueue<int> &queue) //print out current list { std::cout << "The current queue is: "; queue.print(); //print out list std::cout << std::endl << std::endl; }
/* * Method: enqueueEdges * Parameters: BasicGraph graph by reference * PriorityQueue of Edge pointer variables * that comprise the graph * - - - - - - - - - - - - - - - - - - - - - - - - - - * Returns by reference a Priority Queue of Edge pointer * variables according to their randomly assigned weights. * This PQueue is then used to construct the minimum spanning tree. */ void enqueueEdges(BasicGraph& graph, PriorityQueue<Edge*>& pqueue) { Set<Edge*> graphEdges = graph.getEdgeSet(); for(Edge* edge : graphEdges) { pqueue.enqueue(edge, edge->cost); } }
int main( int argc, char **argv ) { // VARIABLES FOR INPUT char str[ MAX_LINE_LENGTH +1 ] ; ssize_t nchars; state_t state; // state_t is defined by the PSVN API. It is the type used for individual states. PriorityQueue<state_t> open; //state_map_t *map = new_state_map();//****** // VARIABLES FOR ITERATING THROUGH state's SUCCESSORS state_t child; ruleid_iterator_t iter; // ruleid_terator_t is the type defined by the PSVN API successor/predecessor iterators. int ruleid ; // an iterator returns a number identifying a rule int64_t totalNodes; // READ A LINE OF INPUT FROM stdin printf("Please enter a state followed by ENTER: "); if ( fgets(str, sizeof str, stdin) == NULL ) { printf("Error: empty input line.\n"); return 0; } // CONVERT THE STRING TO A STATE nchars = read_state( str, &state ); if (nchars <= 0) { printf("Error: invalid state entered.\n"); return 0; } printf("The state you entered is: "); print_state( stdout, &state ); printf("\n"); List StateList = List(); // state_map_add( map, &state, 0 );//******dont know if its a must open.Add(0,0,state); StateList.add(&state); StateList.change_color(&state,1);// Gray // StateList.change_distance(&state,0); totalNodes = 0; int d = 0; /* Search */ while ( !open.Empty() ) { // g.n d = open.CurrentPriority(); printf("D: %d\n",d); state = open.Top(); open.Pop(); totalNodes++; /* DDD */ if (StateList.get_color(&state)==0 || (StateList.get_distance(&state)>(d-1))){ StateList.change_distance(&state,d); if (is_goal(&state)==1){ //PRINT STUFF printf("Estado: "); print_state( stdout, &state); printf(" Estados Generados: %"PRId64" , costo: %d",totalNodes,StateList.get_distance(&state)); return 1;//SUCCES } /* expand node */ init_fwd_iter(&iter, &state); while((ruleid = next_ruleid(&iter)) >= 0){ apply_fwd_rule(ruleid,&state,&child);//'child' is a succesor state_t of 'state' StateList.add(&child); StateList.change_color(&child, 1);//Gray const int child_d = d + get_fwd_rule_cost(ruleid); StateList.change_distance( &child , child_d ); open.Add( child_d , child_d , child ); } StateList.change_color(&state,2); //Black } } printf("FAIL!"); return 2; //FAIL }
//- "k_nearest_neighbor" //- Find the K nearest neighbors to a point. //- //- Description: //- This algorithm is based on the best-first search. The goal of this //- algorithm is to minimize the number of nodes visited by using the //- distance to each subtree's bounding box to avoid visiting subtrees //- which could not possibly contain one of the k nearest objects. //- template <class Z> CubitStatus KDDTree<Z>::k_nearest_neighbor (CubitVector &q, int k, double &closest_dist, DLIList<Z> &nearest_neighbors, typename KDDTree<Z>::DistSqFunc dist_sq_point_data ) { //// Create the priority queues PriorityQueue<KDDTreeNode<Z>*> *queue = new PriorityQueue<KDDTreeNode<Z>*> (KDDTree<Z>::less_than_func); PriorityQueue<KDDTreeNode<Z>*> *queueTemp = new PriorityQueue<KDDTreeNode<Z>*> (KDDTree<Z>::less_than_func); KDDTreeNode<Z> *element = root; // push this node on the queue element->set_dist (min_dist_sq (q, element->safetyBox)); element->set_dist_data (DD_SAFETY); queue->push (element); // if the k closest nodes on the tree are not leaf-nodes, expand the closest // non-leaf node while ( !queue->empty() ) { element = queue->top(); queue->pop(); if (element->get_dist_data() == DD_LEAF) { // this node is a leaf, so it can be pushed onto the temporary queue queueTemp->push (element); } else { // one of the top k nodes is a non-leaf node, so expand it if (element->left) { element->left->set_dist (min_dist_sq (q, element->left->safetyBox)); element->left->set_dist_data (DD_SAFETY); queue->push (element->left); } if (element->right) { element->right->set_dist (min_dist_sq (q, element->right->safetyBox)); element->right->set_dist_data (DD_SAFETY); queue->push (element->right); } element->set_dist (dist_sq_point_data (q, element->data)); element->set_dist_data (DD_LEAF); queue->push (element); // take all the elements in the temporary queue and reinsert them into // the actual queue while ( !queueTemp->empty() ) { queue->push ( queueTemp->top() ); queueTemp->pop (); } } if (queueTemp->size() == k) { // success-- place the k nodes into the nearest_neighbors list element = queueTemp->top(); queueTemp->pop(); closest_dist = element->get_dist(); nearest_neighbors.append (element->data); while ( !queueTemp->empty() ) { nearest_neighbors.append ( queueTemp->top()->data ); queueTemp->pop(); } return CUBIT_SUCCESS; } } return CUBIT_FAILURE; }
int main() { cout << "\n\nLab 12b, PriorityQueueBigOh.cpp\n"; cout << "Programmer: Aysin Oruz \n"; cout << "Editor(s) used: JNotePad and Xcode \n"; cout << "Compiler(s) used: Xcode and Terminal \n"; cout << "Description: The purpose of this lab is for you to learn how to create and apply 12b, PriorityQueueBigOh and get values with BigO().\n"; cout << "File: " << __FILE__ << endl; cout << "Compiled: " << __DATE__ << " at " << __TIME__ << endl; const int REPS = 100000; // for timing fast operations, use REPS up to 100th of the starting n int n = 10000000; // THE STARTING PROBLEM SIZE (MAX 250 MILLION) string bigOh = "O(log n)"; // YOUR PREDICTION: O(1), O(log n), O(n), O(n log n), or O(n squared) int elapsedTimeTicksNorm = 0; double expectedTimeTicks = 0; cout << "\nEnqueue() O(log n)\n" << endl; for (int cycle = 0; cycle < 4; cycle++, n*= 2) { //Declare PQ PriorityQueue<int> List; //Go thru loop to enter values for (int i = n; i > 0; i--) List.enqueue(i); clock_t startTime = clock(); // start the timer assert(List.getSize() == n); for(int j = 0; j < REPS; j++ ) List.enqueue(n + j); assert(List.getSize() == n + REPS); clock_t endTime = clock(); //stop time for (int i = 0; i < List.getSize(); i++) { int first = List.dequeue(); int second = List.dequeue(); assert(first >= second); } // compute timing results long elapsedTimeTicks = (long)(endTime - startTime); double factor = pow(2.0, cycle); if (cycle == 0) elapsedTimeTicksNorm = elapsedTimeTicks; else if (bigOh == "O(1)") expectedTimeTicks = elapsedTimeTicksNorm; else if (bigOh == "O(log n)") expectedTimeTicks = log(double(n)) / log(n / factor) * elapsedTimeTicksNorm; else if (bigOh == "O(n)") expectedTimeTicks = factor * elapsedTimeTicksNorm; else if (bigOh == "O(n log n)") expectedTimeTicks = factor * log(double(n)) / log(n / factor) * elapsedTimeTicksNorm; else if (bigOh == "O(n squared)") expectedTimeTicks = factor * factor * elapsedTimeTicksNorm; cout << elapsedTimeTicks;; if (cycle == 0) cout << " (expected " << bigOh << ')'; else cout << " (expected " << expectedTimeTicks << ')'; cout << " for n = " << n << endl; } { const int REPS = 10000; // for timing fast operations, use REPS up to 100th of the starting n int n = 1000000; // THE STARTING PROBLEM SIZE (MAX 250 MILLION) cout << "\nDequeue() O(log n)\n" << endl; for (int cycle = 0; cycle < 4; cycle++, n*= 2) { PriorityQueue<int> List; for(int i = n; i > 0; i--) List.enqueue(i); assert(List.getSize() == n); //start timing clock_t startTime = clock(); for(int j = 0; j < REPS; j++) List.dequeue(); clock_t endTime = clock(); //stop timign assert(List.getSize() == n - REPS); for (int i = 0; i < List.getSize(); i++) { int first = List.dequeue(); int second = List.dequeue(); assert(first >= second); } // compute timing results long elapsedTimeTicks = (long)(endTime - startTime); double factor = pow(2.0, cycle); if (cycle == 0) elapsedTimeTicksNorm = elapsedTimeTicks; else if (bigOh == "O(1)") expectedTimeTicks = elapsedTimeTicksNorm; else if (bigOh == "O(log n)") expectedTimeTicks = log(double(n)) / log(n / factor) * elapsedTimeTicksNorm; else if (bigOh == "O(n)") expectedTimeTicks = factor * elapsedTimeTicksNorm; else if (bigOh == "O(n log n)") expectedTimeTicks = factor * log(double(n)) / log(n / factor) * elapsedTimeTicksNorm; else if (bigOh == "O(n squared)") expectedTimeTicks = factor * factor * elapsedTimeTicksNorm; // reporting block cout << elapsedTimeTicks;; if (cycle == 0) cout << " (expected " << bigOh << ')'; else cout << " (expected " << expectedTimeTicks << ')'; cout << " for n = " << n << endl; }} }
int main(int argc, char **argv) { // using PriorityQueue = pg::heap::Binary<int>; using PriorityQueue = pg::heap::Pairing<int>; // using PriorityQueue = StdWrapper<int>; test("Basic Push/Pop", []() { PriorityQueue pq; pq.Push(10); pq.Push(5); pq.Push(8); pq.Push(12); pq.Push(1); pq.Push(90); pq.Push(9); assertEquals(1, pq.Pop()); assertEquals(5, pq.Pop()); assertEquals(8, pq.Pop()); assertEquals(9, pq.Pop()); assertEquals(10, pq.Pop()); assertEquals(12, pq.Pop()); assertEquals(90, pq.Pop()); assertEquals(true, pq.Empty()); }); test("Update value", []() { PriorityQueue pq; pq.Push(10); pq.Push(5); pq.Push(8); pq.Push(12); pq.Push(1); pq.Push(90); pq.Push(9); pq.Update(70, 5); pq.Update(7, 12); assertEquals(1, pq.Pop()); assertEquals(7, pq.Pop()); assertEquals(8, pq.Pop()); assertEquals(9, pq.Pop()); assertEquals(10, pq.Pop()); assertEquals(70, pq.Pop()); assertEquals(90, pq.Pop()); assertEquals(true, pq.Empty()); }); test("Performance", []() { constexpr auto size = 1000000; std::default_random_engine random_engine(time(nullptr)); std::uniform_int_distribution<int> distribution(1,9999999); auto rand = std::bind ( distribution, random_engine ); std::vector<int> test; PriorityQueue pq; for(int i = 0 ; i < size; i++) pq.Push(rand()); while(!pq.Empty()) test.push_back(pq.Pop()); assertEquals(true, std::is_sorted(test.begin(), test.end())); }); return 0; }
int main() { PriorityQueue<DataType> testPQA; PriorityQueue<DataType> testPQB; PriorityQueue<DataType> testPQC; char cmdChar; DataType dataItem; int qPriority; char qProcess[ SMALL_STR_LEN ]; bool dataChanged; ShowMenu(); do { dataChanged = false; cout << endl << "Command: "; // Read command cmdChar = GetCommandInput( qProcess, qPriority ); switch ( cmdChar ) { case 'c': case 'C': // clear priority queue while( !testPQA.isEmpty() ) { testPQA.dequeue( dataItem ); } if( VERBOSE ) { cout << " Priority Queue has been cleared " << endl; } dataChanged = true; break; case 'd': case 'D': // dequeue one data item testPQA.dequeue( dataItem ); if( VERBOSE ) { cout << " Process: " << dataItem.process << " has been dequeued with a priority of " << dataItem.priority << PERIOD << endl; } dataChanged = true; break; case 'e': case 'E': // enqueue testPQA.enqueue( qPriority, qProcess ); if( VERBOSE ) { cout << " Process: " << qProcess << " has been enqueued with a priority of " << qPriority << PERIOD << endl; } dataChanged = true; break; case 'h': case 'H': // help request ShowMenu(); break; case 'p': case 'P': // peek at next item testPQA.peekAtFront( dataItem ); if( VERBOSE ) { cout << " Process: " << dataItem.process << " with priority: " << dataItem.priority << " found at front of queue." << endl; } break; case 'q': case 'Q': // quit the test program if( VERBOSE ) { cout << " End Program Requested" << endl; } cout << endl; break; case 'x': case 'X': // create copy constructor PQ // tempPQ constructed in code block to control scope { PriorityQueue<DataType> tempPQ( testPQA ); testPQC = tempPQ; } if( VERBOSE ) { cout << " Test PQ \'C\' has been constructed with test PQ \'A\'." << endl; } dataChanged = true; break; case 'z': case 'Z': // assign to b PQ testPQB = testPQA; if( VERBOSE ) { cout << " Test PQ \'A\' has been assigned to test PQ \'B\'." << endl; } dataChanged = true; break; default : // Invalid command // clear to end of line in case further data input cin.ignore( SMALL_STR_LEN, ENDLINE_CHAR ); if( VERBOSE ) { cout << " Inactive or invalid command" << endl; } } if( dataChanged ) { testPQA.showStructure( 'A' ); testPQB.showStructure( 'B' ); testPQC.showStructure( 'C' ); } } while ( cmdChar != 'q' && cmdChar != 'Q' ); return 0; }
// Builds the tree TreeNode<SymbolPriority>* MakeTree(const string& message) { char currentChar; vector<SymbolPriority> temp; PriorityQueue<TreeNode<SymbolPriority>*> myPriorityQueue; for (int i = 0; i < int(message.size()); i++) { currentChar = message[i]; if ( temp.empty() ) temp.push_back( SymbolPriority(currentChar, 1) ); else if ( characterExists(temp, currentChar) ) { for (int c = 0; c < int (temp.size()); i++) if (currentChar == temp[i].Symbol) temp[i].Priority++; } else temp.push_back( SymbolPriority(currentChar, 1) ); } for (int i = 0; i < int(temp.size()); i++) { if (myPriorityQueue.GetSize() <= 1) myPriorityQueue.Push( new TreeNode<SymbolPriority>( temp[i]) ); else { char aChar; TreeNode<SymbolPriority>* tempNode; // create a new TreeNode<SymbolPriority>* and // make the first popped element its left child // make the second popped element its right child // set its value to the sum of its left and right child priorities tempNode->Left = myPriorityQueue.Top(); aChar = myPriorityQueue.Top()->Data.Priority; myPriorityQueue.Pop(); tempNode->Right = myPriorityQueue.Top(); aChar += myPriorityQueue.Top()->Data.Priority; myPriorityQueue.Pop(); myPriorityQueue.Push( tempNode ); } } return myPriorityQueue.Top(); }
DWORD WINAPI RetranTreat(LPVOID lpParameter){ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1,1); err = WSAStartup(wVersionRequested,&wsaData); if ( err != 0 ) { return -1; } if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1) { WSACleanup( ); return -1; } SOCKET retran_socket=socket(AF_INET,SOCK_DGRAM,0); SOCKADDR_IN retran_addr; //retran_addr.sin_addr.S_un.S_addr=inet_addr("192.168.1.5"); //此处有修改 retran_addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY); retran_addr.sin_family=AF_INET; retran_addr.sin_port=htons(retranport); if(bind(retran_socket,(sockaddr*)&retran_addr,sizeof(SOCKADDR_IN))==-1){ printf("bind error~~~~~~~~~~~~~~\n"); } int priority=0; while(1) { SOCKADDR_IN client_socket; int len = sizeof(SOCKADDR); char recvbuf[1500]; int commd_size=recvfrom(retran_socket,recvbuf,1500,0,(SOCKADDR*)&client_socket,&len); if(commd_size<=0){ //printf("Retan Comm error"); continue; //这个是自己加的9-24 } printf("treat Retan %s to UPD server port %d size:%d\n",inet_ntoa(client_socket.sin_addr),ntohs(client_socket.sin_port),commd_size); int pointer = 0; int userid ; memcpy(&userid,recvbuf,sizeof(int)); pointer +=sizeof(int); while(1){ priority++; long miss_top_id; int sqnum; int timestmp; memcpy(&miss_top_id,recvbuf+pointer,sizeof(long)); pointer += sizeof(miss_top_id); memcpy(&sqnum,recvbuf+pointer,sizeof(int)); pointer += sizeof(sqnum); memcpy(×tmp,recvbuf+pointer,sizeof(int)); pointer += sizeof(timestmp); RestoreCell rc; //printf("apply data id:%d sqnum:%d timestmp%d\n",miss_top_id,sqnum,timestmp); if(rsb.applyData(miss_top_id,sqnum,timestmp,&rc)>=0){ //printf("finded data sqnum:%d\n",sqnum); KeyValue *pkg=new KeyValue(); memcpy(pkg->value,rc.data,rc.size+sizeof(long)+sizeof(int)); pkg->pkgsize=rc.size; pkg->user_id=userid; pkg->key=priority; if(!retransQueue.isInSchedule(*pkg)){ retransQueue.priority_queue_enqueue(pkg); } } if(pointer+1>=commd_size) break; } } return 0; }
int main() { // print my name and this assignment's title cout << "LAB 11a: Write And Test A Priority Queue Template\n"; cout << "Programmer: Jacky Chow\n"; cout << "Editor(s) used: Notepad++\n"; cout << "Compiler(s) used: Visual C++\n"; cout << "File: " << __FILE__ << endl; cout << "Complied: " << __DATE__ << " at " << __TIME__ << endl << endl; PriorityQueue<int> pq; int temp; cout << "Created a PriorityQueue<int> named pq\n"; cout << "Its size should be 0. It is: " << pq.size() << endl; assert(0 == pq.size()); if(pq.empty()) cout << "pq.empty() returned true that it was empty\n"; else cout << "Error: pq.empty() returned false for empty PQ\n"; assert(pq.empty()); cout << "\nEnqueuing the ints 13, 8, 4, 20, 10 into pq\n"; pq.enqueue(13); pq.enqueue(8); pq.enqueue(4); pq.enqueue(20); pq.enqueue(10); if(!pq.empty()) cout << "pq.empty() returned false that it was empty\n"; else cout << "Error: pq.empty() returned true for a non-empty PQ\n"; assert(!pq.empty()); cout << "\nIts size should now be 5. It is: " << pq.size() << endl; assert(5 == pq.size()); cout << "The front should be 20. It is: " << pq.front() << endl; assert(20 == pq.front()); cout << "The back should be 10. It is: " << pq.back() << endl; assert(10 == pq.back()); //const copy constructor test { cout << "\nCreating const copy with copy constructor\n"; const PriorityQueue<int> copy = pq; if(!copy.empty()) cout << "copy.empty() returned false that it was empty\n"; else cout << "Error: copy.empty() returned true for a non-empty PQ\n"; assert(!copy.empty()); cout << "Copy size should now be 5. It is: " << copy.size() << endl; assert(5 == copy.size()); } //operator= copy test { cout << "\nCreating copy with with operator=\n"; PriorityQueue<int> copy; cout << "Should initially have size 0. It is: " << copy.size() << endl; assert(copy.empty()); cout << "Assigning copy to = pq\n"; copy = pq; if(!copy.empty()) cout << "copy.empty() returned false that it was empty\n"; else cout << "Error: copy.empty() returned true for a non-empty copy\n"; assert(!copy.empty()); cout << "Copy 2's size should now be 5. It is: " << copy.size() << endl; assert(5 == copy.size()); cout << "The front should be 20. It is: " << copy.front() << endl; assert(20 == copy.front()); cout << "The back should be 10. It is: " << copy.back() << endl; assert(10 == copy.back()); cout << "Dequeuing the entire copy of pq: \n"; for(; copy.size();) cout << copy.dequeue() << ' '; cout << "\nCopy should now be size 0. It is: " << copy.size() << endl; assert(copy.empty()); if(copy.empty()) cout << "copy.empty() returned true that it was empty\n"; else cout << "Error: copy.empty() returned false for an empty copy\n"; assert(copy.empty()); } temp = pq.dequeue(); cout << "\nDequeuing root of pq. It should return 20. It is: " << temp << endl; assert(20 == temp); cout << "\nIts size should now be 4. It is: " << pq.size() << endl; assert(4 == pq.size()); cout << "The front should be 13. It is: " << pq.front() << endl; assert(13 == pq.front()); cout << "The back should be 8. It is: " << pq.back() << endl; assert(8 == pq.back()); cout << "\nNow using clear to clear pq\n"; pq.clear(); cout << "Size should now be 0. It is: " << pq.size() << endl; assert(0 == pq.size()); if(pq.empty()) cout << "pq.empty() returned true that it was empty\n"; else cout << "Error: pq.empty() returned false for empty PQ\n"; assert(pq.empty()); }
inline void singleDefUse(FlowGraph* fg, X86Instruction* ins, BasicBlock* bb, Loop* loop, std::pebil_map_type<uint64_t, X86Instruction*>& ipebil_map_type, std::pebil_map_type<uint64_t, BasicBlock*>& bpebil_map_type, std::pebil_map_type<uint64_t, LinkedList<X86Instruction::ReachingDefinition*>*>& alliuses, std::pebil_map_type<uint64_t, LinkedList<X86Instruction::ReachingDefinition*>*>& allidefs, int k, uint64_t loopLeader, uint32_t fcnt){ // Get defintions for this instruction: ins LinkedList<X86Instruction::ReachingDefinition*>* idefs = ins->getDefs(); LinkedList<X86Instruction::ReachingDefinition*>* allDefs = idefs; // Skip instruction if it doesn't define anything if (idefs == NULL) { return; } if (idefs->empty()) { delete idefs; return; } set<LinkedList<X86Instruction::ReachingDefinition*>*> allDefLists; allDefLists.insert(idefs); PriorityQueue<struct path*, uint32_t> paths = PriorityQueue<struct path*, uint32_t>(); bool blockTouched[fg->getFunction()->getNumberOfBasicBlocks()]; bzero(&blockTouched, sizeof(bool) * fg->getFunction()->getNumberOfBasicBlocks()); // Initialize worklist with the path from this instruction // Only take paths inside the loop. Since the definitions are in a loop, uses in the loop will be most relevant. if (k == bb->getNumberOfInstructions() - 1){ ASSERT(ins->controlFallsThrough()); if (bb->getNumberOfTargets() > 0){ ASSERT(bb->getNumberOfTargets() == 1); if (flowsInDefUseScope(bb->getTargetBlock(0), loop)){ // Path flows to the first instruction of the next block paths.insert(new path(bb->getTargetBlock(0)->getLeader(), idefs), 1); } } } else { // path flows to the next instruction in this block paths.insert(new path(bb->getInstruction(k+1), idefs), 1); } // while there are paths in worklist while (!paths.isEmpty()) { // take the shortest path in list uint32_t currDist; struct path* p = paths.deleteMin(&currDist); X86Instruction* cand = p->ins; idefs = p->defs; delete p; LinkedList<X86Instruction::ReachingDefinition*>* i2uses, *i2defs, *newdefs; i2uses = alliuses[cand->getBaseAddress()]; // Check if any of idefs is used if(i2uses != NULL && anyDefsAreUsed(idefs, i2uses)){ // Check if use is shortest uint32_t duDist; duDist = trueDefUseDist(currDist, fcnt); if (!ins->getDefUseDist() || ins->getDefUseDist() > duDist) { ins->setDefUseDist(duDist); } // If dist has increased beyond size of function, we must be looping? if (currDist > fcnt) { ins->setDefXIter(); break; } // Stop searching along this path continue; } // Check if any defines are overwritten i2defs = allidefs[cand->getBaseAddress()]; newdefs = removeInvalidated(idefs, i2defs); // If all definitions killed, stop searching along this path if (newdefs == NULL) continue; allDefLists.insert(newdefs); // end of block that is a branch if (cand->usesControlTarget() && !cand->isCall()){ BasicBlock* tgtBlock = bpebil_map_type[cand->getTargetAddress()]; if (tgtBlock && !blockTouched[tgtBlock->getIndex()] && flowsInDefUseScope(tgtBlock, loop)){ blockTouched[tgtBlock->getIndex()] = true; if (tgtBlock->getBaseAddress() == loopLeader){ paths.insert(new path(tgtBlock->getLeader(), newdefs), loopXDefUseDist(currDist + 1, fcnt)); } else { paths.insert(new path(tgtBlock->getLeader(), newdefs), currDist + 1); } } } // non-branching control if (cand->controlFallsThrough()){ BasicBlock* tgtBlock = bpebil_map_type[cand->getBaseAddress() + cand->getSizeInBytes()]; if (tgtBlock && flowsInDefUseScope(tgtBlock, loop)){ X86Instruction* ftTarget = ipebil_map_type[cand->getBaseAddress() + cand->getSizeInBytes()]; if (ftTarget){ if (ftTarget->isLeader()){ if (!blockTouched[tgtBlock->getIndex()]){ blockTouched[tgtBlock->getIndex()] = true; if (ftTarget->getBaseAddress() == loopLeader){ paths.insert(new path(ftTarget, newdefs), loopXDefUseDist(currDist + 1, fcnt)); } else { paths.insert(new path(ftTarget, newdefs), currDist + 1); } } } else { paths.insert(new path(ftTarget, newdefs), currDist + 1); } } } } } if (!paths.isEmpty()){ ins->setDefUseDist(0); } while (!paths.isEmpty()){ delete paths.deleteMin(NULL); } while (!allDefs->empty()){ delete allDefs->shift(); } for(set<LinkedList<X86Instruction::ReachingDefinition*>*>::iterator it = allDefLists.begin(); it != allDefLists.end(); ++it){ delete *it; } }
vector<Node *> dijkstrasAlgorithm(BasicGraph& graph, Vertex* start, Vertex* end) { graph.resetData(); //set as predescessor if that is undefined Vertex* unDefined; //the current node we are checking Vertex* currentNode; //sets startnode cost to zero start->cost=0.0; //create prioqueue PriorityQueue<Vertex*> vertexPrioQueue; //used to keep track of all predeccesors map<Vertex*,Vertex*> predecessor; //set all costs, sets predecessor and adds the to the queue for (Node *node :graph.getNodeSet()){ //all nodes but start should have infinity cost if (node!=start){ node->cost=INFINITY; predecessor[node]=unDefined; } //add all nodes to queue vertexPrioQueue.enqueue(node,node->cost); } //keep track of the alternative cost double alt; //while the queue is not empty while (!vertexPrioQueue.isEmpty()){ //put current node to the one with highest priority currentNode= vertexPrioQueue.front(); vertexPrioQueue.dequeue(); currentNode->setColor(YELLOW); currentNode->visited=true; if (currentNode==end){ break; } //check all the node's neighbors for(Node *node :graph.getNeighbors(currentNode)){ //if we have not visited that node if (!node->visited){ //we check the alternative cost alt=currentNode->cost+graph.getArc(currentNode,node)->cost; //if the alternative cost is lower then we set that to our new cost if (alt<node->cost){ node->cost=alt; predecessor[node]=currentNode; vertexPrioQueue.changePriority(node,alt); } } } currentNode->setColor(GREEN); } //if we havent found end if(predecessor[end]==unDefined){ vector<Vertex*> path; return path; } else{ //if we have found end we trace through the predecessor map to find the path stack<Vertex*> vertexStack; vector<Vertex*> path; currentNode=end; while (currentNode!=start){ vertexStack.push(currentNode); currentNode=predecessor[currentNode]; } vertexStack.push(start); while (!vertexStack.empty()){ path.push_back(vertexStack.top()); vertexStack.pop(); } return path; } }
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/log/log.h> LOG_SETUP("priority_queue_test"); #include <vespa/vespalib/testkit/testapp.h> #include <vespa/vespalib/util/priority_queue.h> using namespace vespalib; TEST("require that default priority order works") { PriorityQueue<int> queue; EXPECT_EQUAL(true, queue.empty()); EXPECT_EQUAL(0u, queue.size()); queue.push(5); queue.push(3); queue.push(7); queue.push(10); queue.push(2); EXPECT_EQUAL(false, queue.empty()); EXPECT_EQUAL(5u, queue.size()); EXPECT_EQUAL(2, queue.front()); queue.front() = 6; queue.adjust(); EXPECT_EQUAL(3, queue.front()); queue.pop_front(); EXPECT_EQUAL(5, queue.front()); queue.pop_front(); EXPECT_EQUAL(6, queue.front()); queue.pop_front(); EXPECT_EQUAL(7, queue.front()); queue.pop_front(); EXPECT_EQUAL(10, queue.front());
//this is the same as dijkstrasAlgorithm except for one thing which is commented vector<Node *> aStar(BasicGraph& graph, Vertex* start, Vertex* end) { graph.resetData(); Vertex* unDefined; Vertex* currentNode; start->cost=0.0; PriorityQueue<Vertex*> vertexPrioQueue; map<Vertex*,Vertex*> predecessor; for (Node *node :graph.getNodeSet()){ if (node!=start){ node->cost=INFINITY; predecessor[node]=unDefined; } vertexPrioQueue.enqueue(node,node->cost);; } double alt; while (!vertexPrioQueue.isEmpty()){ currentNode= vertexPrioQueue.front(); vertexPrioQueue.dequeue(); currentNode->setColor(YELLOW); currentNode->visited=true; if (currentNode==end){ break; } for(Node *node :graph.getNeighbors(currentNode)){ if (!node->visited){ alt=currentNode->cost+graph.getArc(currentNode,node)->cost; if (alt<node->cost){ node->cost=alt; predecessor[node]=currentNode; //this is the change, the queuepriority comes from the node cost + the heuristic vertexPrioQueue.changePriority(node,node->cost+node->heuristic((end))); } } } currentNode->setColor(GREEN); } if(predecessor[end]==unDefined){ vector<Vertex*> path; return path; } else{ stack<Vertex*> vertexStack; vector<Vertex*> path; currentNode=end; while (currentNode!=start){ vertexStack.push(currentNode); currentNode=predecessor[currentNode]; } vertexStack.push(start); while (!vertexStack.empty()){ path.push_back(vertexStack.top()); vertexStack.pop(); } return path; } }
void CCmpPathfinder::ComputeShortPath(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t r, entity_pos_t range, const Goal& goal, pass_class_t passClass, Path& path) { UpdateGrid(); // TODO: only need to bother updating if the terrain changed PROFILE3("ComputeShortPath"); // ScopeTimer UID__(L"ComputeShortPath"); m_DebugOverlayShortPathLines.clear(); if (m_DebugOverlay) { // Render the goal shape m_DebugOverlayShortPathLines.push_back(SOverlayLine()); m_DebugOverlayShortPathLines.back().m_Color = CColor(1, 0, 0, 1); switch (goal.type) { case CCmpPathfinder::Goal::POINT: { SimRender::ConstructCircleOnGround(GetSimContext(), goal.x.ToFloat(), goal.z.ToFloat(), 0.2f, m_DebugOverlayShortPathLines.back(), true); break; } case CCmpPathfinder::Goal::CIRCLE: { SimRender::ConstructCircleOnGround(GetSimContext(), goal.x.ToFloat(), goal.z.ToFloat(), goal.hw.ToFloat(), m_DebugOverlayShortPathLines.back(), true); break; } case CCmpPathfinder::Goal::SQUARE: { float a = atan2f(goal.v.X.ToFloat(), goal.v.Y.ToFloat()); SimRender::ConstructSquareOnGround(GetSimContext(), goal.x.ToFloat(), goal.z.ToFloat(), goal.hw.ToFloat()*2, goal.hh.ToFloat()*2, a, m_DebugOverlayShortPathLines.back(), true); break; } } } // List of collision edges - paths must never cross these. // (Edges are one-sided so intersections are fine in one direction, but not the other direction.) std::vector<Edge> edges; std::vector<Edge> edgesAA; // axis-aligned squares // Create impassable edges at the max-range boundary, so we can't escape the region // where we're meant to be searching fixed rangeXMin = x0 - range; fixed rangeXMax = x0 + range; fixed rangeZMin = z0 - range; fixed rangeZMax = z0 + range; { // (The edges are the opposite direction to usual, so it's an inside-out square) Edge e0 = { CFixedVector2D(rangeXMin, rangeZMin), CFixedVector2D(rangeXMin, rangeZMax) }; Edge e1 = { CFixedVector2D(rangeXMin, rangeZMax), CFixedVector2D(rangeXMax, rangeZMax) }; Edge e2 = { CFixedVector2D(rangeXMax, rangeZMax), CFixedVector2D(rangeXMax, rangeZMin) }; Edge e3 = { CFixedVector2D(rangeXMax, rangeZMin), CFixedVector2D(rangeXMin, rangeZMin) }; edges.push_back(e0); edges.push_back(e1); edges.push_back(e2); edges.push_back(e3); } // List of obstruction vertexes (plus start/end points); we'll try to find paths through // the graph defined by these vertexes std::vector<Vertex> vertexes; // Add the start point to the graph CFixedVector2D posStart(x0, z0); fixed hStart = (posStart - NearestPointOnGoal(posStart, goal)).Length(); Vertex start = { posStart, fixed::Zero(), hStart, 0, Vertex::OPEN, QUADRANT_NONE, QUADRANT_ALL }; vertexes.push_back(start); const size_t START_VERTEX_ID = 0; // Add the goal vertex to the graph. // Since the goal isn't always a point, this a special magic virtual vertex which moves around - whenever // we look at it from another vertex, it is moved to be the closest point on the goal shape to that vertex. Vertex end = { CFixedVector2D(goal.x, goal.z), fixed::Zero(), fixed::Zero(), 0, Vertex::UNEXPLORED, QUADRANT_NONE, QUADRANT_ALL }; vertexes.push_back(end); const size_t GOAL_VERTEX_ID = 1; // Add terrain obstructions { u16 i0, j0, i1, j1; NearestTile(rangeXMin, rangeZMin, i0, j0); NearestTile(rangeXMax, rangeZMax, i1, j1); AddTerrainEdges(edgesAA, vertexes, i0, j0, i1, j1, r, passClass, *m_Grid); } // Find all the obstruction squares that might affect us CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY); std::vector<ICmpObstructionManager::ObstructionSquare> squares; cmpObstructionManager->GetObstructionsInRange(filter, rangeXMin - r, rangeZMin - r, rangeXMax + r, rangeZMax + r, squares); // Resize arrays to reduce reallocations vertexes.reserve(vertexes.size() + squares.size()*4); edgesAA.reserve(edgesAA.size() + squares.size()); // (assume most squares are AA) // Convert each obstruction square into collision edges and search graph vertexes for (size_t i = 0; i < squares.size(); ++i) { CFixedVector2D center(squares[i].x, squares[i].z); CFixedVector2D u = squares[i].u; CFixedVector2D v = squares[i].v; // Expand the vertexes by the moving unit's collision radius, to find the // closest we can get to it CFixedVector2D hd0(squares[i].hw + r + EDGE_EXPAND_DELTA, squares[i].hh + r + EDGE_EXPAND_DELTA); CFixedVector2D hd1(squares[i].hw + r + EDGE_EXPAND_DELTA, -(squares[i].hh + r + EDGE_EXPAND_DELTA)); // Check whether this is an axis-aligned square bool aa = (u.X == fixed::FromInt(1) && u.Y == fixed::Zero() && v.X == fixed::Zero() && v.Y == fixed::FromInt(1)); Vertex vert; vert.status = Vertex::UNEXPLORED; vert.quadInward = QUADRANT_NONE; vert.quadOutward = QUADRANT_ALL; vert.p.X = center.X - hd0.Dot(u); vert.p.Y = center.Y + hd0.Dot(v); if (aa) vert.quadInward = QUADRANT_BR; vertexes.push_back(vert); vert.p.X = center.X - hd1.Dot(u); vert.p.Y = center.Y + hd1.Dot(v); if (aa) vert.quadInward = QUADRANT_TR; vertexes.push_back(vert); vert.p.X = center.X + hd0.Dot(u); vert.p.Y = center.Y - hd0.Dot(v); if (aa) vert.quadInward = QUADRANT_TL; vertexes.push_back(vert); vert.p.X = center.X + hd1.Dot(u); vert.p.Y = center.Y - hd1.Dot(v); if (aa) vert.quadInward = QUADRANT_BL; vertexes.push_back(vert); // Add the edges: CFixedVector2D h0(squares[i].hw + r, squares[i].hh + r); CFixedVector2D h1(squares[i].hw + r, -(squares[i].hh + r)); CFixedVector2D ev0(center.X - h0.Dot(u), center.Y + h0.Dot(v)); CFixedVector2D ev1(center.X - h1.Dot(u), center.Y + h1.Dot(v)); CFixedVector2D ev2(center.X + h0.Dot(u), center.Y - h0.Dot(v)); CFixedVector2D ev3(center.X + h1.Dot(u), center.Y - h1.Dot(v)); if (aa) { Edge e = { ev1, ev3 }; edgesAA.push_back(e); } else { Edge e0 = { ev0, ev1 }; Edge e1 = { ev1, ev2 }; Edge e2 = { ev2, ev3 }; Edge e3 = { ev3, ev0 }; edges.push_back(e0); edges.push_back(e1); edges.push_back(e2); edges.push_back(e3); } // TODO: should clip out vertexes and edges that are outside the range, // to reduce the search space } ENSURE(vertexes.size() < 65536); // we store array indexes as u16 if (m_DebugOverlay) { // Render the obstruction edges for (size_t i = 0; i < edges.size(); ++i) { m_DebugOverlayShortPathLines.push_back(SOverlayLine()); m_DebugOverlayShortPathLines.back().m_Color = CColor(0, 1, 1, 1); std::vector<float> xz; xz.push_back(edges[i].p0.X.ToFloat()); xz.push_back(edges[i].p0.Y.ToFloat()); xz.push_back(edges[i].p1.X.ToFloat()); xz.push_back(edges[i].p1.Y.ToFloat()); SimRender::ConstructLineOnGround(GetSimContext(), xz, m_DebugOverlayShortPathLines.back(), true); } for (size_t i = 0; i < edgesAA.size(); ++i) { m_DebugOverlayShortPathLines.push_back(SOverlayLine()); m_DebugOverlayShortPathLines.back().m_Color = CColor(0, 1, 1, 1); std::vector<float> xz; xz.push_back(edgesAA[i].p0.X.ToFloat()); xz.push_back(edgesAA[i].p0.Y.ToFloat()); xz.push_back(edgesAA[i].p0.X.ToFloat()); xz.push_back(edgesAA[i].p1.Y.ToFloat()); xz.push_back(edgesAA[i].p1.X.ToFloat()); xz.push_back(edgesAA[i].p1.Y.ToFloat()); xz.push_back(edgesAA[i].p1.X.ToFloat()); xz.push_back(edgesAA[i].p0.Y.ToFloat()); xz.push_back(edgesAA[i].p0.X.ToFloat()); xz.push_back(edgesAA[i].p0.Y.ToFloat()); SimRender::ConstructLineOnGround(GetSimContext(), xz, m_DebugOverlayShortPathLines.back(), true); } } // Do an A* search over the vertex/visibility graph: // Since we are just measuring Euclidean distance the heuristic is admissible, // so we never have to re-examine a node once it's been moved to the closed set. // To save time in common cases, we don't precompute a graph of valid edges between vertexes; // we do it lazily instead. When the search algorithm reaches a vertex, we examine every other // vertex and see if we can reach it without hitting any collision edges, and ignore the ones // we can't reach. Since the algorithm can only reach a vertex once (and then it'll be marked // as closed), we won't be doing any redundant visibility computations. PROFILE_START("A*"); PriorityQueue open; PriorityQueue::Item qiStart = { START_VERTEX_ID, start.h }; open.push(qiStart); u16 idBest = START_VERTEX_ID; fixed hBest = start.h; while (!open.empty()) { // Move best tile from open to closed PriorityQueue::Item curr = open.pop(); vertexes[curr.id].status = Vertex::CLOSED; // If we've reached the destination, stop if (curr.id == GOAL_VERTEX_ID) { idBest = curr.id; break; } // Sort the edges so ones nearer this vertex are checked first by CheckVisibility, // since they're more likely to block the rays std::sort(edgesAA.begin(), edgesAA.end(), EdgeSort(vertexes[curr.id].p)); std::vector<EdgeAA> edgesLeft; std::vector<EdgeAA> edgesRight; std::vector<EdgeAA> edgesBottom; std::vector<EdgeAA> edgesTop; SplitAAEdges(vertexes[curr.id].p, edgesAA, edgesLeft, edgesRight, edgesBottom, edgesTop); // Check the lines to every other vertex for (size_t n = 0; n < vertexes.size(); ++n) { if (vertexes[n].status == Vertex::CLOSED) continue; // If this is the magical goal vertex, move it to near the current vertex CFixedVector2D npos; if (n == GOAL_VERTEX_ID) { npos = NearestPointOnGoal(vertexes[curr.id].p, goal); // To prevent integer overflows later on, we need to ensure all vertexes are // 'close' to the source. The goal might be far away (not a good idea but // sometimes it happens), so clamp it to the current search range npos.X = clamp(npos.X, rangeXMin, rangeXMax); npos.Y = clamp(npos.Y, rangeZMin, rangeZMax); } else { npos = vertexes[n].p; } // Work out which quadrant(s) we're approaching the new vertex from u8 quad = 0; if (vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y <= npos.Y) quad |= QUADRANT_BL; if (vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y >= npos.Y) quad |= QUADRANT_TR; if (vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y >= npos.Y) quad |= QUADRANT_TL; if (vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y <= npos.Y) quad |= QUADRANT_BR; // Check that the new vertex is in the right quadrant for the old vertex if (!(vertexes[curr.id].quadOutward & quad)) { // Hack: Always head towards the goal if possible, to avoid missing it if it's // inside another unit if (n != GOAL_VERTEX_ID) { continue; } } bool visible = CheckVisibilityLeft(vertexes[curr.id].p, npos, edgesLeft) && CheckVisibilityRight(vertexes[curr.id].p, npos, edgesRight) && CheckVisibilityBottom(vertexes[curr.id].p, npos, edgesBottom) && CheckVisibilityTop(vertexes[curr.id].p, npos, edgesTop) && CheckVisibility(vertexes[curr.id].p, npos, edges); /* // Render the edges that we examine m_DebugOverlayShortPathLines.push_back(SOverlayLine()); m_DebugOverlayShortPathLines.back().m_Color = visible ? CColor(0, 1, 0, 0.5) : CColor(1, 0, 0, 0.5); std::vector<float> xz; xz.push_back(vertexes[curr.id].p.X.ToFloat()); xz.push_back(vertexes[curr.id].p.Y.ToFloat()); xz.push_back(npos.X.ToFloat()); xz.push_back(npos.Y.ToFloat()); SimRender::ConstructLineOnGround(GetSimContext(), xz, m_DebugOverlayShortPathLines.back(), false); //*/ if (visible) { fixed g = vertexes[curr.id].g + (vertexes[curr.id].p - npos).Length(); // If this is a new tile, compute the heuristic distance if (vertexes[n].status == Vertex::UNEXPLORED) { // Add it to the open list: vertexes[n].status = Vertex::OPEN; vertexes[n].g = g; vertexes[n].h = DistanceToGoal(npos, goal); vertexes[n].pred = curr.id; // If this is an axis-aligned shape, the path must continue in the same quadrant // direction (but not go into the inside of the shape). // Hack: If we started *inside* a shape then perhaps headed to its corner (e.g. the unit // was very near another unit), don't restrict further pathing. if (vertexes[n].quadInward && !(curr.id == START_VERTEX_ID && g < fixed::FromInt(8))) vertexes[n].quadOutward = ((~vertexes[n].quadInward) & quad) & 0xF; if (n == GOAL_VERTEX_ID) vertexes[n].p = npos; // remember the new best goal position PriorityQueue::Item t = { (u16)n, g + vertexes[n].h }; open.push(t); // Remember the heuristically best vertex we've seen so far, in case we never actually reach the target if (vertexes[n].h < hBest) { idBest = (u16)n; hBest = vertexes[n].h; } } else // must be OPEN { // If we've already seen this tile, and the new path to this tile does not have a // better cost, then stop now if (g >= vertexes[n].g) continue; // Otherwise, we have a better path, so replace the old one with the new cost/parent vertexes[n].g = g; vertexes[n].pred = curr.id; // If this is an axis-aligned shape, the path must continue in the same quadrant // direction (but not go into the inside of the shape). if (vertexes[n].quadInward) vertexes[n].quadOutward = ((~vertexes[n].quadInward) & quad) & 0xF; if (n == GOAL_VERTEX_ID) vertexes[n].p = npos; // remember the new best goal position open.promote((u16)n, g + vertexes[n].h); } } } } // Reconstruct the path (in reverse) for (u16 id = idBest; id != START_VERTEX_ID; id = vertexes[id].pred) { Waypoint w = { vertexes[id].p.X, vertexes[id].p.Y }; path.m_Waypoints.push_back(w); } PROFILE_END("A*"); }
int main() { int comps=0; //BH comparisons string txt; cout << "Enter name of txt file without extension: " << endl; cin >> txt; string str(txt + ".txt"); Graph graph(str); graph.PrintGraph(); int sVert, dVert; cout << "Enter the source vertex: " << endl; cin >> sVert; cout << "Enter the destination vertex: " << endl; cin >> dVert; cout << " " << endl; // for storing distances and extracting the minimum; equivalent to Q and d[] on the slides PriorityQueue<int> pq; int size = graph.getSize(); //graph size int kArray[size]; for(int i = 0; i < size; i++) {kArray[i] = INT_MAX;} //key/weight int xArray[size]; for(int i = 1; i <= size; i++) {xArray[i-1] = i;} //element pq.createPriorityQueue(kArray, xArray, xArray, size); // for storing the parent (previous node) on the path; equivalent to pi[] on the slides int* shortestPathParent = new int[size + 1]; for(int i = 0; i < size; i++) {shortestPathParent[i] = 0;} // Dijkstra's algorithm Locator sl = pq.getLocator(sVert); //locator keeps track of element's memory address pq.replaceKey(sl,0); if(sVert > size || dVert > size || sVert < 0 || dVert < 0) throw "No such vertex exists"; vector<Vertex*> del; // removed vertices vector<Vertex*> vertList = graph.getVertices(); while( !pq.isEmpty()) { Vertex* u = vertList[pq.minElement() - 1]; Locator locu = pq.getLocator(u->getID()); int ukey = pq.getKey(locu); pq.removeMin(); del.push_back(u); vector<Edge*> edges = u->getOutEdges(); for( int i = 0; i < edges.size(); i++ ) { Vertex* v = edges[i] -> geteVertP(); int w = edges[i] -> getWeight(); Locator locv = pq.getLocator(v->getID()); if(comps++, pq.getKey(locv) > (ukey + w)) //if (d[b] > d[a] + w(a,b)) { pq.replaceKey(locv, ukey + w); //d[b] = d[a] + w(a,b) shortestPathParent[v->getID()] = u->getID(); //P[b] = a } } } Vertex* d = graph.getVertex(dVert); Vertex* s = graph.getVertex(sVert); vector<int>vers, wt; vector<Edge*> e = vertList[dVert-1]->getInEdges(); int c = 0; vers.push_back(dVert); if (sVert == dVert) { vers.push_back(dVert); wt.push_back(0); } else { while (c != sVert) { //compare edges int minw = e[0]->getWeight(); int minv = e[0]->getsVertP()->getID(); for (int i = 0; i < e.size(); i++) { if(e[i]->getWeight() < minw) { minw = e[i]->getWeight(); minv = e[i]->getsVertP()->getID(); } } wt.push_back(minw); vers.push_back(minv); c = vertList[minv-1]->getID(); e = vertList[minv-1]->getInEdges(); } reverse(wt.begin(),wt.end()); reverse(vers.begin(),vers.end()); } for (int i = 0; i < vers.size()-1; i++) { cout << vers[i] << "--[" << wt[i] << "]-->"; } cout << dVert << endl; int dist = 0; for (int i = 0; i < wt.size(); i++) { dist = dist + wt[i]; } cout << " " << endl; cout << "Total weight of the shortest path from " << sVert << " to " << dVert << " = " << dist << endl; cout << "Total number of comparisons needed to decrease key values: " << comps; return 0; }
PriorityQueue VectorialSearch::search(string query, double alpha, double gamma){ string token; ifstream index; PriorityQueue top; // cout << alpha << " " << gamma << endl; double w_t, w_dt; int previous_doc_id = 0; int word_id, doc_id, freq, pos; unordered_map<unsigned int, double> acc_text; unordered_map<unsigned int, double> acc_anchor; ifstream input; Tokenizer t(query, Stopwords::instance()->get_value()); // this->reset_distance(); // Calculating tfidf for each word in query // TODO: Accumulate tfidf of documents in order to have vectorial product while(t.size() > 0){ token = t.getToken(); if(token.size() > 0){ std::cout << "\tProcessing token: " << token << std::endl; this->set_text_search(); if(!((*this->vocabulary).find(token) == (*this->vocabulary).end())){ this->cossine_similarity(token, acc_text, INDEX_SORTED_FILE_NAME); } this->set_anchor_search(); if(!((*this->vocabulary).find(token) == (*this->vocabulary).end())){ this->cossine_similarity(token, acc_anchor, INDEX_SORTED_FILE_NAME); } } } for (auto item : acc_text){ Ranking rank; // item.first => doc_id // item.second => acc[doc_id] rank.id = item.first; rank.rank = 0.0; if(this->w_d_text.find(rank.id) == this->w_d_text.end()){ this->w_d_text[rank.id] = 0.0; } else { rank.rank = this->w_d_text[rank.id] > 0 ? (acc_text[rank.id] / this->w_d_text[rank.id]) : 0.0; } if(this->w_d_anchor.find(rank.id) == this->w_d_anchor.end()){ this->w_d_anchor[rank.id] = 0.0; } else { double sum = this->w_d_anchor[rank.id] ? (alpha*((acc_anchor[rank.id] / this->w_d_anchor[rank.id]))) : 0.0; rank.rank += sum; } if (this->pagerank.find(rank.id) != this->pagerank.end()){ rank.rank += (gamma*this->pagerank[rank.id]); } top.push(rank); } return top; }
int main() { // print my name and this assignment's title cout << "Lab 11a, The \"Write And Test A Priority Queue Template\" Program \n"; cout << "Programmer: Licong Wang\n"; cout << "Editor(s) used: Visual studio 2013\n"; cout << "Compiler(s) used: Microsoft c++ complier\n"; cout << "File: " << __FILE__ << endl; cout << "Complied: " << __DATE__ << " at " << __TIME__ << endl << endl; PriorityQueue<int> pq; cout << "\nTest size and empty" << endl; cout << "The expected size is 0, the acutal size is " << pq.size() << endl; assert(pq.size() == 0); cout << "Expect it to be empty: "; if (pq.empty()) cout << "Empty" << endl; else cout << "Not Empty" << endl; assert(pq.empty()); cout << "\nEnqueue values 1 to 5" << endl; for (int i = 1; i < 6; i++) { pq.enqueue(i); } cout << "\nTest size and empty again" << endl; cout << "The expected size is 5, the acutal size is " << pq.size() << endl; assert(pq.size() == 5); cout << "Expect it to be not empty: "; if (pq.empty()) cout << "Empty" << endl; else cout << "Not Empty" << endl; assert(!(pq.empty())); cout << "\nCheck its front and back, expecting 5 and 3, accroding to the rule of binary tree" << endl; cout << "Front: " << pq.front() << endl; cout << "back: " << pq.back() << endl; assert(pq.front() == 5); assert(pq.back() == 3); cout << "\nCheck the heap array using copy pop, expecting values from 5-1, " << "since the highest value is popped each time" << endl; for (PriorityQueue<int> copy = pq; copy.size(); ) cout << copy.dequeue() << " "; cout << "\n\nNow dequeue once" << endl; pq.dequeue(); cout << "\nTest size again" << endl; cout << "The expected size is 4, the acutal size is " << pq.size() << endl; assert(pq.size() == 4); cout << "\nCheck its front and back, expecting 4 and 1" << endl; cout << "Front: " << pq.front() << endl; cout << "back: " << pq.back() << endl; assert(pq.front() == 4); assert(pq.back() == 1); cout << "\ncheck the heap array using copy pop, expecting values from 4-1, " << "since 5 is already dequeued" << endl; for (PriorityQueue<int> copy = pq; copy.size(); ) cout << copy.dequeue() << " "; cout << endl; { cout << "\nObject Copy Testing" << endl; const PriorityQueue<int> copy = pq; cout << "\nTest size and empty" << endl; cout << "The expected size is 4, the acutal size is " << pq.size() << endl; assert(pq.size() == 4); cout << "Expect it to be not empty: "; if (pq.empty()) cout << "Empty" << endl; else cout << "Not Empty" << endl; assert(!(pq.empty())); cout << "\ncheck the heap array using copy pop, expecting values from 4-1" << endl; for (PriorityQueue<int> copy2 = copy; copy2.size(); ) cout << copy2.dequeue() << " "; cout << endl; } { cout << "\nObject Assignment Testing" << endl; PriorityQueue<int> copy; copy = pq; cout << "\nTest size and empty" << endl; cout << "The expected size is 4, the acutal size is " << pq.size() << endl; assert(pq.size() == 4); cout << "Expect it to be not empty: "; if (pq.empty()) cout << "Empty" << endl; else cout << "Not Empty" << endl; assert(!(pq.empty())); cout << "\ncheck the heap array using copy pop, expecting values from 4-1" << endl; for (PriorityQueue<int> copy2 = copy; copy2.size();) cout << copy2.dequeue() << " "; cout << endl; } cout << "\nBack to original object, test clear" << endl; pq.clear(); cout << "\nTest size and empty" << endl; cout << "The expected size is 0, the acutal size is " << pq.size() << endl; assert(pq.size() == 0); cout << "Expect it to be empty: "; if (pq.empty()) cout << "Empty" << endl; else cout << "Not Empty" << endl; assert(pq.empty()); cout << "\nCheck its front and back, expecting 0 and 0, dummy got returned" << endl; cout << "Front: " << pq.front() << endl; cout << "back: " << pq.back() << endl; assert(pq.front() == 0); assert(pq.back() == 0); cout << "\nPress ENTER to continue..." << endl; cin.get(); }
/* main() manages the user interface; * instantiates priority queue object, then operates loop to read input * from user and call the appropriate priority queue method */ int main() { PriorityQueue pq; TokenScanner scanner; while (true) { string line = getLine("> "); scanner.setInput(line); scanner.ignoreWhitespace(); string cmd=scanner.nextToken(); if (cmd == "help") { helpCommand(); } else if (cmd == "enqueue") { if(scanner.hasMoreTokens()){ string value=scanner.nextToken(); if(scanner.hasMoreTokens()){ scanner.scanNumbers(); string priorityStr=scanner.nextToken(); double priority=stringToDouble(priorityStr); pq.enqueue(value,priority); } else pq.enqueue(value); } } else if (cmd == "dequeue") { if(pq.isEmpty()) cout<<"The queue is empty"<<endl; else cout<<pq.dequeue()<<endl; } else if (cmd == "peek") { if(pq.isEmpty()) cout<<"The queue is empty"<<endl; else cout<<pq.peek()<<endl; } else if (cmd == "peekPriority"||cmd=="peekpriority") { if(pq.isEmpty()) cout<<"The queue is empty"<<endl; else cout<<pq.peekPriority()<<endl; } else if (cmd == "clear") { pq.clear(); } else if (cmd == "size") { cout<<pq.size()<<endl; } else if (cmd == "isEmpty"||cmd=="isempty") { if(pq.isEmpty()) cout<<"true"; else cout<<"false"; cout<<endl; } else if(cmd=="list") list(pq); else { cout << "Undefined command: " << cmd << endl; } } return 0; }
void sizeQueue(PriorityQueue<int> &queue) //print out the queue size { std::cout << "The size of the queue is: " << queue.size() << std::endl << std::endl; }
vector<Road *> shortestPath(vector<Node *> nodes, int const startingPosition, int const endingPosition){ cout << "\n\n\n"; PriorityQueue nodePQueue; nodePQueue.addNode(nodes[startingPosition]); nodes[startingPosition]->priority = 0; nodePQueue.lowerPriority(1, nodes[startingPosition]); Node * temp; bool pathFound = false; while(nodePQueue.size() > 0){ temp = nodePQueue.popOffTop(); temp->visited = true; if(temp->lineNumber == endingPosition){ // we have reached our destination pathFound = true; break; } // update children for(int i = 0; i < temp->roads.size(); i+=1){ // get the node number of the node on the other side of the road int otherSide = temp->roads[i]->connection2; if(temp->roads[i]->connection2 == temp->lineNumber) otherSide = temp->roads[i]->connection1; if(nodes[otherSide]->visited) continue; // child already visited, no action should be taken // if the node isnt in the heap, add it if(nodes[otherSide]->positionInHeap == -1){ nodes[otherSide]->priority = temp->priority + temp->roads[i]->length; nodePQueue.addNode(nodes[otherSide]); } // if the node is in the heap and its priority is greater than the one we just found, update it else if((nodes[otherSide]->priority) > (temp->priority + temp->roads[i]->length)){ nodes[otherSide]->priority = temp->priority + temp->roads[i]->length; nodePQueue.lowerPriority(nodes[otherSide]->positionInHeap, nodes[otherSide]); } else continue; // the node is in the heap and its priority is better than the one we just found } } vector<Road *> pathToTake; if(!pathFound) return pathToTake; cout << "Destination found. Info following (priority is the distance from our starting point)\n"; cout << "endingPosition: " << endingPosition << " temp->lineNumber: " << temp->lineNumber << endl << endl; temp->print(); // draw the path (need to figure it out first) double pathLength = temp->priority; Node * traversalHelp = temp; int tooManyLoops = 5; while(pathLength > 0){ if(!tooManyLoops){ pathFound == false; break; } //cout << "remaining length: " << pathLength << endl; // search for the correct road for(int i = 0; i < traversalHelp->roads.size(); i+=1){ // find other side of road int otherSide = traversalHelp->roads[i]->connection2; if(traversalHelp->roads[i]->connection2 == traversalHelp->lineNumber) otherSide = traversalHelp->roads[i]->connection1; // check to see if this is the correct road double calculation = (pathLength - traversalHelp->roads[i]->length) - nodes[otherSide]->priority; if(calculation < 0.01 && calculation > -0.01){ tooManyLoops = 5; pathToTake.push_back(traversalHelp->roads[i]); // add the road to the path pathLength -= traversalHelp->roads[i]->length; // adjust the remaining length traversalHelp = nodes[otherSide]; // adjust which node we are considering break; } } tooManyLoops--; } //if(!pathFound) { // pathToTake.clear(); // return pathToTake; } int lastLocation = startingPosition; string oldName = ""; double sumOfSmallRoads = 0.0; for(int i = pathToTake.size()-1; i >=0; i-=1){ int nextPlace = pathToTake[i]->connection1; if(nextPlace == lastLocation) nextPlace = pathToTake[i]->connection2; if(oldName == ""){ oldName = pathToTake[i]->name; sumOfSmallRoads = pathToTake[i]->length; continue; } if(pathToTake[i]->name != oldName){ cout << "Take " << oldName << " towards "; cout << nodes[lastLocation]->placeName << ", " << nodes[lastLocation]->placeState << " for " << sumOfSmallRoads << " miles.\n"; sumOfSmallRoads = pathToTake[i]->length; oldName = pathToTake[i]->name; } else{ sumOfSmallRoads += pathToTake[i]->length; } lastLocation = nextPlace; } cout << "Take " << pathToTake[0]->name << " towards your destination " << " for " << pathToTake[0]->length << " miles.\n"; return pathToTake; }
void EstimatePropagator::propagate(OptimizableGraph::VertexSet& vset, const EstimatePropagator::PropagateCost& cost, const EstimatePropagator::PropagateAction& action, double maxDistance, double maxEdgeCost) { reset(); PriorityQueue frontier; for (OptimizableGraph::VertexSet::iterator vit=vset.begin(); vit!=vset.end(); ++vit){ OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*vit); AdjacencyMap::iterator it = _adjacencyMap.find(v); assert(it != _adjacencyMap.end()); it->second._distance = 0.; it->second._parent.clear(); it->second._frontierLevel = 0; frontier.push(&it->second); } while(! frontier.empty()){ AdjacencyMapEntry* entry = frontier.pop(); OptimizableGraph::Vertex* u = entry->child(); double uDistance = entry->distance(); //cerr << "uDistance " << uDistance << endl; // initialize the vertex if (entry->_frontierLevel > 0) { action(entry->edge(), entry->parent(), u); } /* std::pair< OptimizableGraph::VertexSet::iterator, bool> insertResult = */ _visited.insert(u); OptimizableGraph::EdgeSet::iterator et = u->edges().begin(); while (et != u->edges().end()){ OptimizableGraph::Edge* edge = static_cast<OptimizableGraph::Edge*>(*et); ++et; int maxFrontier = -1; OptimizableGraph::VertexSet initializedVertices; for (size_t i = 0; i < edge->vertices().size(); ++i) { OptimizableGraph::Vertex* z = static_cast<OptimizableGraph::Vertex*>(edge->vertex(i)); AdjacencyMap::iterator ot = _adjacencyMap.find(z); if (ot->second._distance != numeric_limits<double>::max()) { initializedVertices.insert(z); maxFrontier = (max)(maxFrontier, ot->second._frontierLevel); } } assert(maxFrontier >= 0); for (size_t i = 0; i < edge->vertices().size(); ++i) { OptimizableGraph::Vertex* z = static_cast<OptimizableGraph::Vertex*>(edge->vertex(i)); if (z == u) continue; size_t wasInitialized = initializedVertices.erase(z); double edgeDistance = cost(edge, initializedVertices, z); if (edgeDistance > 0. && edgeDistance != std::numeric_limits<double>::max() && edgeDistance < maxEdgeCost) { double zDistance = uDistance + edgeDistance; //cerr << z->id() << " " << zDistance << endl; AdjacencyMap::iterator ot = _adjacencyMap.find(z); assert(ot!=_adjacencyMap.end()); if (zDistance < ot->second.distance() && zDistance < maxDistance){ //if (ot->second.inQueue) //cerr << "Updating" << endl; ot->second._distance = zDistance; ot->second._parent = initializedVertices; ot->second._edge = edge; ot->second._frontierLevel = maxFrontier + 1; frontier.push(&ot->second); } } if (wasInitialized > 0) initializedVertices.insert(z); } } } // writing debug information like cost for reaching each vertex and the parent used to initialize #ifdef DEBUG_ESTIMATE_PROPAGATOR cerr << "Writing cost.dat" << endl; ofstream costStream("cost.dat"); for (AdjacencyMap::const_iterator it = _adjacencyMap.begin(); it != _adjacencyMap.end(); ++it) { HyperGraph::Vertex* u = it->second.child(); costStream << "vertex " << u->id() << " cost " << it->second._distance << endl; } cerr << "Writing init.dat" << endl; ofstream initStream("init.dat"); vector<AdjacencyMapEntry*> frontierLevels; for (AdjacencyMap::iterator it = _adjacencyMap.begin(); it != _adjacencyMap.end(); ++it) { if (it->second._frontierLevel > 0) frontierLevels.push_back(&it->second); } sort(frontierLevels.begin(), frontierLevels.end(), FrontierLevelCmp()); for (vector<AdjacencyMapEntry*>::const_iterator it = frontierLevels.begin(); it != frontierLevels.end(); ++it) { AdjacencyMapEntry* entry = *it; OptimizableGraph::Vertex* to = entry->child(); initStream << "calling init level = " << entry->_frontierLevel << "\t ("; for (OptimizableGraph::VertexSet::iterator pit = entry->parent().begin(); pit != entry->parent().end(); ++pit) { initStream << " " << (*pit)->id(); } initStream << " ) -> " << to->id() << endl; } #endif }
int main(int argc, char *argv[]) { cout << "Usage: " << argv[0] << " [FILENAME].[off|obj|ply] [1-7] [sl]" << endl; cout << "where 1-7 is the cost function to use" << endl; cout << " s = save images at all decimation steps" << endl; cout << " l = disable lighting" << endl; cout << endl; cout << "Keybindings:" << endl; cout << " [space] toggle animation." << endl; cout << " 'r' reset." << endl; cout << " '1' edge collapse." << endl; cout << " '2' vertex split." << endl; cout << " 's' save screenshot." << endl; cout << " 'c' switch color mode." << endl; cout << " 'f' cycle cost function." << endl; cout << endl; // Load a closed manifold mesh string filename; if (argc >= 2) { filename = argv[1]; } else { return 0; } if (argc >= 3) { int idx = stoi(argv[2]) - 1; cost_function_n = idx; if (idx >= 0 && idx < cost_functions.size()) shortest_edge_and_midpoint = *(cost_functions.begin() + idx); } if (!igl::read_triangle_mesh(filename, OV, OF)) { cout << "could not read mesh from \"" << filename << "\"" << endl; return 1; } // compute normals igl::per_face_normals(OV, OF, normals); // Prepare array-based edge data structures and priority queue // EMAP is a map from faces to edges. // Index into it like EMAP(face + i*F.rows()) where i is an edge index // between 0 and 2 corresponding to the three edges of a triangle. VectorXi EMAP; // E is a map from edges to vertices. Given some edge index e, // E(e, 0) and E(e, 1) are the two vertices that the edge is composed of. MatrixXi E; // EF is a map from edges to faces. For some edge index e, // EF(e, 0) and E(e, 1) are the two faces that contain the edge e. MatrixXi EF; // EI is a map from edges to face corners. For some edge index e, // EI(e, 0) is the index i such that EMAP(EF(e, 0) + i*F.rows()) == e and // EI(e, 1) is the index i such that EMAP(EF(e, 1) + i*F.rows()) == e. MatrixXi EI; typedef std::set<std::pair<double, int>> PriorityQueue; // Q stores the list of possible edge collapses and their costs PriorityQueue Q; std::vector<PriorityQueue::iterator> Qit; // If an edge were collapsed, we'd collapse it to these points: MatrixXd C; // Keep some info on edge collapses for reversal and debug reasons int num_collapsed; std::vector<MeshModification> mods; std::vector<int> iters; int total_decimations = 0; const auto &reset_view = [&]() { viewer.data.clear(); viewer.data.set_mesh(V, F); switch (color_mode) { case DISTANCE_VISUALIZATION: generate_distance_field(); case COST_VISUALIZATION: viewer.data.set_colors(colors); break; case SOLID: viewer.data.set_colors(RowVector3d(1.0, 1.0, 1.0)); break; } viewer.data.set_face_based(false); }; // Function to reset original mesh and data structures const auto &reset = [&]() { total_decimations = 0; mods.clear(); iters.clear(); F = OF; V = OV; igl::edge_flaps(F, E, EMAP, EF, EI); Qit.resize(E.rows()); C.resize(E.rows(), V.cols()); colors.resize(V.rows(), 3); colors.setZero(); VectorXd costs(V.rows()); costs.setZero(); for (int e = 0; e < E.rows(); e++) { double cost = e; RowVectorXd p(1, 3); shortest_edge_and_midpoint(e, V, F, E, EMAP, EF, EI, cost, p); C.row(e) = p; Qit[e] = Q.insert(std::pair<double, int>(cost, e)).first; costs(E(e, 0)) += cost; costs(E(e, 1)) += cost; } igl::jet(costs, true, colors); num_collapsed = 0; reset_view(); }; const auto &collapse_edges = [&](igl::viewer::Viewer &viewer) -> bool { // If animating then collapse 10% of edges if (viewer.core.is_animating && !Q.empty()) { bool something_collapsed = false; // collapse edge const int num_iters = 50; // Store the state from before the collapse so that it can be // reversed later. MatrixXd prev_V = V; MatrixXi prev_F = F; MatrixXi prev_E = E; num_collapsed = 0; int total_failures = 0; // If a certain number of failures have // occurred, we exit an infinte fail loop. for (int j = 0; j < num_iters; j++) { int e, e1, e2, f1, f2; std::vector<int> faceInd, vertInd; if (Q.empty()) break; if (!collapse_edge(shortest_edge_and_midpoint, V, F, E, EMAP, EF, EI, Q, Qit, C, e, e1, e2, f1, f2, faceInd)) { total_failures++; j--; if (total_failures > 1000) { break; } continue; } else { total_decimations++; num_collapsed++; } MatrixXi faces(faceInd.size() + 2, 3); faceInd.push_back(f1); faceInd.push_back(f2); for (int i = 0; i < faceInd.size(); i++) { faces.row(i) = prev_F.row(faceInd[i]); // cout << "ffF" << faces.row(i) << endl; } MatrixXd verts(2, 3); vertInd.push_back(prev_E(e, 0)); vertInd.push_back(prev_E(e, 1)); for (int i = 0; i < vertInd.size(); i++) { verts.row(i) = prev_V.row(vertInd[i]); } mods.push_back( MeshModification(vertInd, verts, faceInd, faces)); something_collapsed = true; } if (something_collapsed) { iters.push_back(num_collapsed); reset_view(); } } cout << "Collapsed an Edge\n" << "Decimations: " << total_decimations << "\n"; return false; }; // function to reverse edge collapse const auto &uncollapse_edges = [&](igl::viewer::Viewer &viewer) -> bool { if (viewer.core.is_animating && !mods.empty() && !iters.empty()) { int max_iter = iters.back(); iters.pop_back(); for (int i = 0; i < max_iter; i++) { MeshModification mod = mods.back(); mods.pop_back(); total_decimations--; for (int i = 0; i < mod.vertInd.size(); i++) { V.row(mod.vertInd[i]) = mod.verts.row(i); } for (int i = 0; i < mod.faceInd.size(); i++) { F.row(mod.faceInd[i]) = mod.faces.row(i); } } reset_view(); cout << "Uncollapsed an Edge\n" << "Decimations: " << total_decimations << "\n"; } }; const auto &save_images = [&]() -> bool { reset(); viewer.draw(); save_screenshot(viewer, "images/before.png"); char fn[100]; char command[512]; ofstream distfile("surface_distances", ofstream::trunc); for (int i = 0; i <= 50; i++) { collapse_edges(viewer); distfile << generate_distance_field() << endl; viewer.draw(); sprintf(fn, "images/after%03d.png", i); save_screenshot(viewer, fn); sprintf(command, "composite images/before.png " "images/after%03d.png -compose difference " "images/diff%03d.png ", i, i); system(command); sprintf(command, "composite images/after%03d.png " "images/after%03d.png -compose difference " "images/delta%03d.png ", i, i - 1, i); system(command); cout << "Step " << i << " / 100" << endl; } distfile.close(); exit(EXIT_SUCCESS); }; const auto &key_down = [&](igl::viewer::Viewer &viewer, unsigned char key, int mod) -> bool { switch (key) { case ' ': viewer.core.is_animating ^= 1; break; case 'R': case 'r': reset(); break; case '1': collapse_edges(viewer); break; case '2': uncollapse_edges(viewer); break; case '3': save_images(); break; case 'S': case 's': save_screenshot(viewer, "images/screen.png"); cout << "saved screen to images/screen.png" << endl; break; case 'C': case 'c': ((int &)color_mode)++; ((int &)color_mode) %= MAX_COLOR_MODE; reset_view(); break; case 'F': case 'f': cost_function_n++; cost_function_n %= cost_functions.size(); shortest_edge_and_midpoint = *(cost_functions.begin() + cost_function_n); reset(); break; case 'g': case 'G': cout << generate_distance_field() << endl; break; default: return false; } return true; }; const auto &s_option = [&](igl::viewer::Viewer &viewer) -> bool { if (argc >= 4) { for (char c : string(argv[3])) { switch (c) { case 's': save_images(); break; case 'l': viewer.core.shininess = 1.0; viewer.core.lighting_factor = 0.0; break; } } } }; reset(); viewer.core.is_animating = true; viewer.callback_key_pressed = key_down; viewer.callback_init = s_option; viewer.core.show_lines = false; viewer.core.camera_zoom = 2.0; return viewer.launch(); }
/*************************************************************************** * Que 7. Find the median dynamically for given input array. * * Comments : * 1) A median heap can be implemented using two heaps each * containing half the elements. * 2) One the max-heap containing the smallest elements, the * other is a min-heap, containing the largest elements. * 3) The size of the max-heap may be equal to the size of * the min-heap. * 4) If the total number of elements are even, the median is * the average of the maximum elements of the max-heap and * the minimum element of the min heap. * 5) if there are an odd number of elements, the max-heap will * contain one more element than the min-heap. The median in * this case is simply the maximum element of the max-heap. * * **************************************************************************/ int FindMedian(int val, int& median, PriorityQueue& right, PriorityQueue& left) { int lcount = left.Size(); int rcount = right.Size(); int returnVal = 0; // both same number of elements after adding one more element if(lcount == rcount) { if(val < left.Top()) { //Element will go to left left.InsertElement(val); returnVal = left.Top(); } else { //Element will go to right right.InsertElement(val); returnVal = right.Top(); } } else if( lcount > rcount ) //Left heap has more elements (max heap) { if(val < left.Top()) { right.InsertElement(left.DeleteTop()); left.InsertElement(val); } else { right.InsertElement(val); } returnVal = Average(left.Top(),right.Top()); } else if( lcount < rcount ) //Right heap has more elements (min heap) { if(val < left.Top()) { left.InsertElement(val); } else { left.InsertElement(right.DeleteTop()); right.InsertElement(val); } returnVal = Average(left.Top(),right.Top()); } return returnVal; }
IGL_INLINE bool igl::decimate( const Eigen::MatrixXd & OV, const Eigen::MatrixXi & OF, const std::function<void( const int, const Eigen::MatrixXd &, const Eigen::MatrixXi &, const Eigen::MatrixXi &, const Eigen::VectorXi &, const Eigen::MatrixXi &, const Eigen::MatrixXi &, double &, Eigen::RowVectorXd &)> & cost_and_placement, const std::function<bool( const Eigen::MatrixXd &, const Eigen::MatrixXi &, const Eigen::MatrixXi &, const Eigen::VectorXi &, const Eigen::MatrixXi &, const Eigen::MatrixXi &, const std::set<std::pair<double,int> > &, const std::vector<std::set<std::pair<double,int> >::iterator > &, const Eigen::MatrixXd &, const int, const int, const int, const int, const int)> & stopping_condition, const std::function<bool( const Eigen::MatrixXd & ,/*V*/ const Eigen::MatrixXi & ,/*F*/ const Eigen::MatrixXi & ,/*E*/ const Eigen::VectorXi & ,/*EMAP*/ const Eigen::MatrixXi & ,/*EF*/ const Eigen::MatrixXi & ,/*EI*/ const std::set<std::pair<double,int> > & ,/*Q*/ const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/ const Eigen::MatrixXd & ,/*C*/ const int /*e*/ )> & pre_collapse, const std::function<void( const Eigen::MatrixXd & , /*V*/ const Eigen::MatrixXi & , /*F*/ const Eigen::MatrixXi & , /*E*/ const Eigen::VectorXi & ,/*EMAP*/ const Eigen::MatrixXi & , /*EF*/ const Eigen::MatrixXi & , /*EI*/ const std::set<std::pair<double,int> > & , /*Q*/ const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/ const Eigen::MatrixXd & , /*C*/ const int , /*e*/ const int , /*e1*/ const int , /*e2*/ const int , /*f1*/ const int , /*f2*/ const bool /*collapsed*/ )> & post_collapse, const Eigen::MatrixXi & OE, const Eigen::VectorXi & OEMAP, const Eigen::MatrixXi & OEF, const Eigen::MatrixXi & OEI, Eigen::MatrixXd & U, Eigen::MatrixXi & G, Eigen::VectorXi & J, Eigen::VectorXi & I ) { // Decimate 1 using namespace Eigen; using namespace std; // Working copies Eigen::MatrixXd V = OV; Eigen::MatrixXi F = OF; Eigen::MatrixXi E = OE; Eigen::VectorXi EMAP = OEMAP; Eigen::MatrixXi EF = OEF; Eigen::MatrixXi EI = OEI; typedef std::set<std::pair<double,int> > PriorityQueue; PriorityQueue Q; std::vector<PriorityQueue::iterator > Qit; Qit.resize(E.rows()); // If an edge were collapsed, we'd collapse it to these points: MatrixXd C(E.rows(),V.cols()); for(int e = 0;e<E.rows();e++) { double cost = e; RowVectorXd p(1,3); cost_and_placement(e,V,F,E,EMAP,EF,EI,cost,p); C.row(e) = p; Qit[e] = Q.insert(std::pair<double,int>(cost,e)).first; } int prev_e = -1; bool clean_finish = false; while(true) { if(Q.empty()) { break; } if(Q.begin()->first == std::numeric_limits<double>::infinity()) { // min cost edge is infinite cost break; } int e,e1,e2,f1,f2; if(collapse_edge( cost_and_placement, pre_collapse, post_collapse, V,F,E,EMAP,EF,EI,Q,Qit,C,e,e1,e2,f1,f2)) { if(stopping_condition(V,F,E,EMAP,EF,EI,Q,Qit,C,e,e1,e2,f1,f2)) { clean_finish = true; break; } }else { if(prev_e == e) { assert(false && "Edge collapse no progress... bad stopping condition?"); break; } // Edge was not collapsed... must have been invalid. collapse_edge should // have updated its cost to inf... continue } prev_e = e; } // remove all IGL_COLLAPSE_EDGE_NULL faces MatrixXi F2(F.rows(),3); J.resize(F.rows()); int m = 0; for(int f = 0;f<F.rows();f++) { if( F(f,0) != IGL_COLLAPSE_EDGE_NULL || F(f,1) != IGL_COLLAPSE_EDGE_NULL || F(f,2) != IGL_COLLAPSE_EDGE_NULL) { F2.row(m) = F.row(f); J(m) = f; m++; } } F2.conservativeResize(m,F2.cols()); J.conservativeResize(m); VectorXi _1; remove_unreferenced(V,F2,U,G,_1,I); return clean_finish; }
int main(int argc, char * argv[]) { using namespace std; using namespace Eigen; using namespace igl; cout<<"Usage: ./703_Decimation_bin [filename.(off|obj|ply)]"<<endl; cout<<" [space] toggle animation."<<endl; cout<<" 'r' reset."<<endl; // Load a closed manifold mesh string filename(TUTORIAL_SHARED_PATH "/fertility.off"); if(argc>=2) { filename = argv[1]; } MatrixXd V,OV; MatrixXi F,OF; read_triangle_mesh(filename,OV,OF); igl::viewer::Viewer viewer; // Prepare array-based edge data structures and priority queue VectorXi EMAP; MatrixXi E,EF,EI; typedef std::set<std::pair<double,int> > PriorityQueue; PriorityQueue Q; std::vector<PriorityQueue::iterator > Qit; // If an edge were collapsed, we'd collapse it to these points: MatrixXd C; int num_collapsed; // Function to reset original mesh and data structures const auto & reset = [&]() { F = OF; V = OV; edge_flaps(F,E,EMAP,EF,EI); Qit.resize(E.rows()); C.resize(E.rows(),V.cols()); VectorXd costs(E.rows()); Q.clear(); for(int e = 0;e<E.rows();e++) { double cost = e; RowVectorXd p(1,3); shortest_edge_and_midpoint(e,V,F,E,EMAP,EF,EI,cost,p); C.row(e) = p; Qit[e] = Q.insert(std::pair<double,int>(cost,e)).first; } num_collapsed = 0; viewer.data.clear(); viewer.data.set_mesh(V,F); viewer.data.set_face_based(true); }; const auto &pre_draw = [&](igl::viewer::Viewer & viewer)->bool { // If animating then collapse 10% of edges if(viewer.core.is_animating && !Q.empty()) { bool something_collapsed = false; // collapse edge const int max_iter = std::ceil(0.01*Q.size()); for(int j = 0;j<max_iter;j++) { if(!collapse_edge( shortest_edge_and_midpoint, V,F,E,EMAP,EF,EI,Q,Qit,C)) { break; } something_collapsed = true; num_collapsed++; } if(something_collapsed) { viewer.data.clear(); viewer.data.set_mesh(V,F); viewer.data.set_face_based(true); } } return false; }; const auto &key_down = [&](igl::viewer::Viewer &viewer,unsigned char key,int mod)->bool { switch(key) { case ' ': viewer.core.is_animating ^= 1; break; case 'R': case 'r': reset(); break; default: return false; } return true; }; reset(); viewer.core.is_animating = true; viewer.callback_key_down = key_down; viewer.callback_pre_draw = pre_draw; return viewer.launch(); }
int main() { // push , pop , top test { PriorityQueue<int> p; assert(p.getSize() == 0); assert(p.getCapacity() == 21); p.push(3);p.push(2);p.push(7);p.push(11);p.push(23); p.pop();p.pop(); p.push(3);p.push(2);p.push(43);p.push(21);p.push(25); p.pop();p.pop(); vector<int> vcmp = {7, 11, 21, 23, 25, 43}; assert(p.getSize() == 6); assert( vcmp == print_queue<int>(p)); assert(p.getCapacity() == 21); } // size , capacity , clear , destroy test { PriorityQueue<int> p; assert(p.getSize() == 0); assert(p.getCapacity() == 21); for(auto i = 0; i<21; i++){ p.push(i); } assert(p.getSize() == 21); assert(p.getCapacity() == 42); p.clear(); assert(p.getSize() == 0); assert(p.getCapacity() == 42); p.destroy(); assert(p.getSize() == 0); assert(p.getCapacity() == 0); } // heapsort test { vector<int> v = {1, 16, 12, 2, 25, 5, 6}; vector<int> cmpv = {1, 2, 5, 6, 12, 16, 25}; heap_sort(v.begin(), v.end()); assert(v == cmpv); } cout<< "All TestCases Pass."<<endl; return 0; }