/*++ Copyright (c) 2017 Microsoft Corporation Module Name: Abstract: Author: Lev Nachmanson (levnach) Revision History: --*/ #include #include "math/lp/lp_utils.h" #include "math/lp/binary_heap_upair_queue.h" namespace lp { template binary_heap_upair_queue::binary_heap_upair_queue(unsigned size) : m_q(size), m_pairs(size) { for (unsigned i = 0; i < size; i++) m_available_spots.push_back(i); } template unsigned binary_heap_upair_queue::dequeue_available_spot() { lp_assert(m_available_spots.empty() == false); unsigned ret = m_available_spots.back(); m_available_spots.pop_back(); return ret; } template void binary_heap_upair_queue::remove(unsigned i, unsigned j) { upair p(i, j); auto it = m_pairs_to_index.find(p); if (it == m_pairs_to_index.end()) return; // nothing to do m_q.remove(it->second); m_available_spots.push_back(it->second); m_pairs_to_index.erase(it); } template bool binary_heap_upair_queue::ij_index_is_new(unsigned ij_index) const { for (auto it : m_pairs_to_index) { if (it.second == ij_index) return false; } return true; } template void binary_heap_upair_queue::enqueue(unsigned i, unsigned j, const T & priority) { upair p(i, j); auto it = m_pairs_to_index.find(p); unsigned ij_index; if (it == m_pairs_to_index.end()) { // it is a new pair, let us find a spot for it if (m_available_spots.empty()) { // we ran out of empty spots unsigned size_was = static_cast(m_pairs.size()); unsigned new_size = size_was << 1; for (unsigned i = size_was; i < new_size; i++) m_available_spots.push_back(i); m_pairs.resize(new_size); } ij_index = dequeue_available_spot(); // lp_assert(ij_indexsecond; } m_q.enqueue(ij_index, priority); } template void binary_heap_upair_queue::dequeue(unsigned & i, unsigned &j) { lp_assert(!m_q.is_empty()); unsigned ij_index = m_q.dequeue(); upair & p = m_pairs[ij_index]; i = p.first; j = p.second; m_available_spots.push_back(ij_index); m_pairs_to_index.erase(p); } template T binary_heap_upair_queue::get_priority(unsigned i, unsigned j) const { auto it = m_pairs_to_index.find(std::make_pair(i, j)); if (it == m_pairs_to_index.end()) return T(0xFFFFFF); // big number return m_q.get_priority(it->second); } #ifdef Z3DEBUG template bool binary_heap_upair_queue::pair_to_index_is_a_bijection() const { std::set tmp; for (auto p : m_pairs_to_index) { unsigned j = p.second; unsigned size = tmp.size(); tmp.insert(j); if (tmp.size() == size) return false; } return true; } template bool binary_heap_upair_queue::available_spots_are_correct() const { std::set tmp; for (auto p : m_available_spots){ tmp.insert(p); } if (tmp.size() != m_available_spots.size()) return false; for (auto it : m_pairs_to_index) if (tmp.find(it.second) != tmp.end()) return false; return true; } #endif }