void test_sequential_random_Insert_DeleteMin(){ FibHeap fib; priority_queue<int> ref_q; int NUM_NODES = 100000; for (int i = 0; i < NUM_NODES; i++){ int curr = rand(); fib.insertNode(curr); ref_q.push(-curr); } for (int i = 0; i < NUM_NODES; i++){ int val= fib.deleteMin(); int ref = -ref_q.top(); ref_q.pop(); if (val != ref){ cout << "\n Our value: " << val << " Ref Value: " << ref; return; } } cout << "\n Sequential Insert then Delete Succeeded"; for (int i = 0; i < NUM_NODES; i++){ int curr = rand(); fib.insertNode(curr); ref_q.push(-curr); if (i%50 == 0){ int num_deletes = rand() % fib.getSize()+1; for (int j = 0; j < num_deletes; j++){ int val= fib.deleteMin(); int ref = -ref_q.top(); ref_q.pop(); if (val != ref){ cout << "\n Random : Our value: " << val << " Ref Value: " << ref; return; } } } } cout << "\n Random Insert and Delete Succeeded"; }
//============================================================================================ // Dijkstra::_run // // Input: // fromId: The id of the starting city. // toId: The id of the ending city // cities: A vector of City objectrs representing all the cities in the graph. // forward: A boolean value indicating whether or not the algorithm should be run by following // edges leading to a Node or edges leading away from that Node. // // Output: // A DijkstraResult object. // // Run Dijkstra's Algorithm from the City identified by the fromId parameter to the city identified by the // toId parameter. //============================================================================================ DijkstraResult *Dijkstra::_run(unsigned long fromId, unsigned long toId, std::map<unsigned long, City *> cities, bool forward){ std::map<unsigned long, City*> previous; std::map<unsigned long, Node*> cityNodes; std::map<unsigned long, unsigned long> distances; FibHeap* heap = new FibHeap(); Node *temp; for(auto it = cities.begin(); it != cities.end(); it++){ it->second->visited = false; if (it->second->key == fromId) { it->second->distance = 0; } else{ it->second->distance = ULONG_MAX; } temp = new Node(it->second); FibHeap::insert(temp, heap); cityNodes[it->second->key] = temp; } City *minCity, *neighbor; Road *road; std::vector<Road *> roads; while(heap->min != nullptr) { minCity = heap->deleteMin(heap); if(forward){ roads = minCity->fromRoads; } else{ roads = minCity->toRoads; } for (auto it = roads.begin(); it != roads.end(); it++) { road = *it; if(forward){ neighbor = cities[road->to]; }else{ neighbor = cities[road->from]; } if (neighbor->visited == false) { unsigned long altDistance = minCity->distance + road->length; if (altDistance < neighbor->distance) { if(minCity->distance != ULONG_MAX){ unsigned long sub = neighbor->distance - altDistance; previous[neighbor->key] = minCity; distances[neighbor->key] = altDistance; FibHeap::decreaseKey(sub, cityNodes[neighbor->key], heap); } } } } minCity->visited = true; } distances[toId] = cities[toId]->distance; return new DijkstraResult(previous, distances); }
void test_decrease_key(){ FibHeap fib; int NUM_NODES = 100; boost_heap pq; map<int, boost_heap::handle_type> index; vector<int> keys; set<int> keyset; // Used for getting logarithmic random generation and duplicate detection for (int i = 0; i < NUM_NODES; i++){ unsigned int curr = rand(); if (present(keyset, curr)) continue; fib.insertNode(curr); index[curr]=pq.push(curr); keys.push_back(curr); keyset.insert(curr); if (i % 25 == 0){ //Do some random decrease keys for (int j = 0; j < 20; j++){ //Pick a key to change unsigned int to_change_index = rand() % keys.size(); unsigned int to_change_val = keys[to_change_index]; if (to_change_val == 0) continue; //Find a smaller value to change to which doesnt already exist // Or try for a bit unsigned int new_val = rand() % to_change_val; for (int k = 0; k < 100; k++){ if (present(keyset, new_val)) new_val = rand() % to_change_val; else break; } if (present(keyset,new_val)) continue; //replace the old value with new one keys[to_change_index] = new_val; keyset.erase(to_change_val); keyset.insert(new_val); //perform operation on heaps pq.decrease(index[to_change_val],new_val); index[new_val] = index[to_change_val]; index.erase(to_change_val); fib.decreaseKey(to_change_val, new_val); } } if (i%50 == 0){ int num_deletes = rand() % fib.getSize()+1; for (int j = 0; j < num_deletes; j++){ unsigned int val= fib.deleteMin(); unsigned int ref = pq.top(); pq.pop(); if (val != ref){ cout << "\n Random : Our value: " << val << " Ref Value: " << ref; return; } keyset.erase(val); std::vector<int>::iterator position = std::find(keys.begin(), keys.end(), val); if (position != keys.end()) // == vector.end() means the element was not found keys.erase(position); else cout << "Should never get here, keys messed up"; index.erase(val); } } } cout <<"Test completed"; }