void simplifyPFBlock(const Edges& toUnlink, const PFBlock& block, Blocks& simplifiedBlocks, Nodes& history) { // take a block, unlink some of the edges and // create smaller blocks or a simplified blocks // or if nothing has changed take a copy of the original block if (toUnlink.size() == 0) { // no change needed, just make a copy of block PFBlock newblock(block.elementIds(), block.edges(), simplifiedBlocks.size(), 's'); // will copy edges and ids PDebug::write("Made {}", newblock); auto id = newblock.id(); simplifiedBlocks.emplace(id, std::move(newblock)); // update history makeHistoryLinks(block.elementIds(), {id}, history); } else { Edges modifiedEdges; for (auto edge : block.edges()) { // copying edges Edge e = edge.second; if (toUnlink.find(edge.first) != toUnlink.end()) { e.setLinked(false); } modifiedEdges.emplace(e.key(), e); } // create new blocks and add into simplifiedBlocks buildPFBlocks(block.elementIds(), modifiedEdges, 's', simplifiedBlocks, history); } }
void PFReconstructor::reconstruct() { // TODO sort m_blocks // simplify the blocks by editing the links // each track will end up linked to at most one hcal // sort the blocks by id to ensure match with python std::vector<IdType> blockids; std::vector<IdType> newblockids; Ids ids = m_pfEvent.mergedElementIds(); // create the blocks of linked ids auto bBuilder = PFBlockBuilder(ids, m_pfEvent); m_blocks = bBuilder.blocks(); for (const auto& b : m_blocks) { blockids.push_back(b.first); } #if WITHSORT std::sort(blockids.begin(), blockids.end()); #endif // go through each block and see if it can be simplified // in some cases it will end up being split into smaller blocks // Note that the old block will be marked as disactivated for (auto bid : blockids) { // std::cout<<Id::pretty(bid)<< ":" << bid <<std::endl; Blocks newBlocks = simplifyBlock(bid); if (newBlocks.size() > 0) { for (auto& b : newBlocks) { IdType id = b.first; m_blocks.emplace(id, std::move(b.second)); newblockids.push_back(b.first); } } } blockids.insert(std::end(blockids), std::begin(newblockids), std::end(newblockids)); for (auto bid : blockids) { PFBlock& block = m_blocks.at(bid); if (block.isActive()) { // when blocks are split the original gets deactivated PDebug::write("Processing {}", block); reconstructBlock(block); } } if (m_unused.size() > 0) { PDebug::write("unused elements "); for (auto u : m_unused) PDebug::write("{},", u); // TODO warning message } }
// This is the core solution bool Board::RecursiveSetBlock(Blocks &bs, size_t block_index) { Block* block = bs[block_index]; size_t xmax = width - block->width; size_t ymax = height - block->height; for (size_t x = 0; x <= xmax; x++) { for (size_t y = 0; y <= ymax; y++) { // if there is a place for block, process. if (SetBlock(block, x, y)) { // If the block is the last one, solution found. if (block_index == bs.size() - 1) { cout << "Step: Put block " << block_index << " at [" << x << ", " << y << "]" << endl; block->Print(width, height, x, y, "Block " + to_string(block_index)); return true; } // If not the last one, process other blocks. if (RecursiveSetBlock(bs, block_index + 1)) { // If all other blocks are positioned correctly, solution found. cout << "Step: Put block " << block_index << " at [" << x << ", " << y << "]" << endl; block->Print(width, height, x, y, "Block " + to_string(block_index)); return true; } else { // If not able to found a solution for other blocks, rollback current block, // and continually find next available position for current block. ClearBlock(block, x, y); continue; } } } } return false; }