bool QuadTree_S::Exists(const BitString &code, int x, int y) { DeltaCode delta; uint64_t cur = 0; long long nodes = delta.DecodeNextInt(code, &cur); long long size = code.get_length(); long long nextIndx = 0; long long begRow = 0, begCol = 0, endRow = nodes, endCol = nodes; long long depth = 0, nodesAtDepth = 1, nodesAtNextDepth = 0; for (long long i = 0; i < size;) { for(long long j = i; j < nodesAtDepth + i; j++) { int curQuad = code.GetBit((j*2+cur)) << 1 | code.GetBit((j*2)+cur+1); if (j == nextIndx) { if (curQuad == 3) { double midRow = ((double)begRow + endRow)/2; double midCol = ((double)begCol + endCol)/2; if (x < midRow) { //We are in NE or NW if (y < midCol) { //We are in NW endRow = midRow; endCol = midCol; nextIndx = i + nodesAtDepth + nodesAtNextDepth; } else { //We are in NE endRow = midRow; begCol = midCol; nextIndx = i + nodesAtDepth + nodesAtNextDepth + 1; } } else if (y < midCol) { //We are in SW begRow = midRow; endCol = midCol; nextIndx = i + nodesAtDepth + nodesAtNextDepth + 2; } else { //We are in SE begRow = midRow; begCol = midCol; nextIndx = i + nodesAtDepth + nodesAtNextDepth + 3; } nodesAtNextDepth += 4; int nextQuad = code.GetBit((nextIndx*2)+cur) << 1 | code.GetBit((nextIndx*2)+cur+1); if (nextQuad == 1) return true; if (nextQuad == 0) return false; else if (nextQuad == 2) if (begCol-begRow + x == y) return false; else return true; } else if (curQuad == 1) return true; else if (curQuad == 0) return false; else if (curQuad == 2) { if (begCol-begRow + x == y) return false; else return true; } } else if (curQuad == 3) { nodesAtNextDepth += 4; } } i += nodesAtDepth; nodesAtDepth = nodesAtNextDepth; nodesAtNextDepth = 0; } }
std::vector<int> QuadTree_H::GetNeighbors(const BitString &code, int x) { DeltaCode delta; uint64_t cur = 0; int nodes = delta.DecodeNextInt(code, &cur); long long size = code.get_length(); long long freq[4] = {0, 3, 1, 2}; cur += 8; std::vector<int> neighbors; QueueObj pos; std::queue<QueueObj> posQueue; posQueue.push(QueueObj(0, 0, nodes, 0, nodes)); pos = posQueue.front(); long long depth = 0, nodesAtDepth = 1, nodesAtNextDepth = 0; for(int i = 0; !posQueue.empty();) { for(long long j = i; j < nodesAtDepth + i; j++) { int curQuad = GetNextHuffQuad(code, freq, &cur); if (j == pos.nextPos) { posQueue.pop(); if (curQuad == 3) { double midRow = ((double)pos.begRow + pos.endRow)/2; double midCol = ((double)pos.begCol + pos.endCol)/2; if (x < midRow) { posQueue.push(QueueObj(i + nodesAtDepth + nodesAtNextDepth, pos.begRow, midRow, pos.begCol, midCol)); posQueue.push(QueueObj(i + nodesAtDepth + nodesAtNextDepth + 1, pos.begRow, midRow, midCol, pos.endCol)); } else { posQueue.push(QueueObj(i + nodesAtDepth + nodesAtNextDepth + 2, midRow, pos.endRow, pos.begCol, midCol)); posQueue.push(QueueObj(i + nodesAtDepth + nodesAtNextDepth + 3, midRow, pos.endRow, midCol, pos.endCol)); } nodesAtNextDepth += 4; } else if (curQuad == 1) { for (int n = pos.begCol; n < pos.endCol; ++n) { neighbors.push_back(n); } } else if (curQuad == 2) { for (int n = pos.begCol; n < pos.endCol; ++n) { if (pos.begCol - pos.begRow + x == n) continue; neighbors.push_back(n); } } if (posQueue.empty()) break; pos = posQueue.front(); } else if (curQuad == 3){ nodesAtNextDepth += 4; } } i += nodesAtDepth; nodesAtDepth = nodesAtNextDepth; nodesAtNextDepth = 0; } return neighbors; }
void QuadTree_H::Compress(char * filename, const int &lineSkip, long long size, BitString * result) { std::vector<long long> quadStrings; std::ifstream fin(filename); std::string line; int x, y; for (int i = 0; i < lineSkip; ++i) std::getline(fin, line); while (std::getline(fin, line)) { std::stringstream ss(line); ss >> x >> y; quadStrings.push_back(GetQuadString(size, x, y)); } std::sort(quadStrings.begin(), quadStrings.end()); long long currentString = GetQuadString(size, 0, 0); long long depth = LogFour(currentString); BitString * depthStrings = new BitString[depth]; long long * depthSizes = new long long[depth]; for (int i = 0; i < depth; ++i) depthSizes[i] = 0; long long freq[4] = {0, 0, 0, 0}; long long dCommon, upQuad, upString, upCommon; dCommon = DeepestCommonQuad(depth, currentString, quadStrings[0]); upQuad = QuadAtDepth(quadStrings[0], depth - dCommon - 1); upString = StripNQuads(quadStrings[0], depth - dCommon - 1) - 1; upCommon = DeepestCommonQuad(depth, currentString, upString); if (currentString <= upString) { for (long long d = upCommon; d >= dCommon; --d) { long long curQuad = QuadAtDepth(currentString, depth - d - 1); long long upQuad = QuadAtDepth(upString, depth - d - 1); for (long long q = curQuad; q <= upQuad; ++q) { depthStrings[d].AppendBit(0); depthStrings[d].AppendBit(0); ++depthSizes[d]; ++freq[0]; } if (upQuad == 3) { for (long long y = d; y >= 1; --y) { if (!Compress(depthStrings, depthSizes, freq, y)) break; } } } } currentString = upString + 1; if (currentString < quadStrings[0]) { for (long long d = dCommon; d < depth; ++d) { long long curQuad = QuadAtDepth(currentString, depth - d - 1); long long edgeQuad = QuadAtDepth(quadStrings[0], depth - d - 1); for (long long q = curQuad; q < edgeQuad; ++q) { depthStrings[d].AppendBit(0); depthStrings[d].AppendBit(0); ++depthSizes[d]; ++freq[0]; } if (edgeQuad == 3) Compress(depthStrings, depthSizes, freq, d); } currentString = quadStrings[0]; } depthStrings[depth-1].AppendBit(0); depthStrings[depth-1].AppendBit(1); ++depthSizes[depth-1]; ++freq[1]; for (long long d = depth - 1; d >= 1; --d) { if (!Compress(depthStrings, depthSizes, freq, d)) break; } for (int i = 1; i < quadStrings.size(); ++i) { dCommon = DeepestCommonQuad(depth, currentString, quadStrings[i]); upQuad = QuadAtDepth(quadStrings[i], depth - dCommon - 1); upString = StripNQuads(quadStrings[i], depth - dCommon - 1) - 1; upCommon = DeepestCommonQuad(depth, currentString, upString); if (currentString < upString) { for (long long d = depth - 1; d >= dCommon; --d) { long long curQuad = QuadAtDepth(currentString, depth - d - 1); long long upQuad = QuadAtDepth(upString, depth - d - 1); for (int q = curQuad; q < upQuad; ++q) { depthStrings[d].AppendBit(0); depthStrings[d].AppendBit(0); ++depthSizes[d]; ++freq[0]; } if (upQuad == 3 && upQuad != curQuad) { for (long long y = d; y >= 1; --y) { if (!Compress(depthStrings, depthSizes, freq, y)) break; } } } } currentString = upString + 1; if (currentString < quadStrings[i]) { for (long long d = dCommon; d < depth; ++d) { long long curQuad = QuadAtDepth(currentString, depth - d - 1); long long edgeQuad = QuadAtDepth(quadStrings[i], depth - d - 1); for (long long q = curQuad; q < edgeQuad; ++q) { depthStrings[d].AppendBit(0); depthStrings[d].AppendBit(0); ++depthSizes[d]; ++freq[0]; } if (edgeQuad == 3 && edgeQuad != curQuad) { for (long long y = d; y >= 1; --y) { if (!Compress(depthStrings, depthSizes, freq, y)) break; } } } currentString = quadStrings[i]; } depthStrings[depth-1].AppendBit(0); depthStrings[depth-1].AppendBit(1); ++depthSizes[depth-1]; ++freq[1]; for (long long d = depth - 1; d >= 1; --d) { if (!Compress(depthStrings, depthSizes, freq, d)) break; } } currentString = quadStrings.back(); long long endString = GetQuadString(size, size - 1, size - 1); dCommon = DeepestCommonQuad(depth, currentString, endString); if (currentString < endString) { for (long long d = depth - 1; d >= 0; --d) { long long curQuad = QuadAtDepth(currentString, depth - d - 1); long long upQuad = QuadAtDepth(endString, depth - d - 1); for (long long q = curQuad; q < upQuad; ++q) { depthStrings[d].AppendBit(0); depthStrings[d].AppendBit(0); ++depthSizes[d]; ++freq[0]; } if (upQuad == 3 && curQuad != upQuad) { for (long long y = d; y >= 1; --y) { if (!Compress(depthStrings, depthSizes, freq, y)) break; } } } } result->Init(0); DeltaCode delta; BitString tmp; delta.EncodeInt(size, &tmp); result->AppendBitString(tmp); ++freq[3]; BitString huff[4]; GetHuffStrings(result, freq, huff); result->AppendBitString(huff[3]); for (int i = 0; i < depth; ++i) { BitString * ds = &depthStrings[i]; for ( long long j = 0; j < ds->get_length(); j+=2) { int quad = ds->GetBit(j) << 1 | ds->GetBit(j+1); result->AppendBitString(huff[quad]); } } result->PrintRUSAGE(); }
bool QuadTree_DP::Exists(const BitString &code, int x, int y) { DeltaCode delta; uint64_t cur = 0; long long nodes = delta.DecodeNextInt(code, &cur); long long depth = delta.DecodeNextInt(code, &cur); std::vector<long long> depthSizes(depth+1); depthSizes[0] = 1; for (int i = 1; i <= depth; ++i) { depthSizes[i] = delta.DecodeNextInt(code, &cur); } long long offset = cur; std::vector<long long> depthIndices(depth+2); depthIndices[0] = 0; for (int i = 1; i < depth + 2; ++i) { depthIndices[i] = depthSizes[i-1] + depthIndices[i-1]; } long long size = code.get_length(); long long nextIndx = 0; long long begRow = 0, begCol = 0, endRow = nodes, endCol = nodes; long long curDepth = 0, nodesAtDepth = 1, nodesAtNextDepth = 0; for (long long i = 0; i < depth; ++i) { for(long long j = depthIndices[i]; j < depthIndices[i+1]; ++j) { int curQuad = code.GetBit(offset+(j*2)) << 1 | code.GetBit(offset+(j*2)+1); if (j == nextIndx) { if (curQuad == 3) { double midRow = ((double)begRow + endRow)/2; double midCol = ((double)begCol + endCol)/2; if (x < midRow) { //We are in NE or NW if (y < midCol) { //We are in NW endRow = midRow; endCol = midCol; nextIndx = depthIndices[i+1] + nodesAtNextDepth; } else { //We are in NE endRow = midRow; begCol = midCol; nextIndx = depthIndices[i+1] + nodesAtNextDepth + 1; } } else if (y < midCol) { //We are in SW begRow = midRow; endCol = midCol; nextIndx = depthIndices[i+1] + nodesAtNextDepth + 2; } else { //We are in SE begRow = midRow; begCol = midCol; nextIndx = depthIndices[i+1] + nodesAtNextDepth + 3; } nodesAtNextDepth += 4; int nextQuad = code.GetBit(offset+(nextIndx*2)) << 1 | code.GetBit(offset+(nextIndx*2)+1); if (nextQuad == 1) return true; if (nextQuad == 0) return false; else if (nextQuad == 2) if (begCol-begRow + x == y) return false; else return true; } else if (curQuad == 1) return true; else if (curQuad == 0) return false; else if (curQuad == 2) { if (begCol-begRow + x == y) return false; else return true; } break; } else if (curQuad == 3) { nodesAtNextDepth += 4; } } nodesAtDepth = nodesAtNextDepth; nodesAtNextDepth = 0; } }