bool IcicleTreeCanvas::compressInit(VisualNode& root, int idx, int absX) { const int kids = root.getNumberOfChildren(); auto& na = node_tree.getNA(); bool hasSolved = false; int leafCnt = 0, expectSolvedCnt = 0, actualSolvedCnt = 0; statistic[idx].ns = root.getStatus(); statistic[idx].absX = absX; for (int i = 0; i < kids; i++) { int kidIdx = root.getChild(i); VisualNode& kid = *na[kidIdx]; if (kid.hasSolvedChildren()) expectSolvedCnt++; if (statistic[kidIdx].height >= compressLevel) { bool kidRes = compressInit(kid, kidIdx, absX + leafCnt); hasSolved |= kidRes; leafCnt += statistic[kidIdx].leafCnt; if (kidRes) actualSolvedCnt++; } } statistic[idx].leafCnt = leafCnt? leafCnt: 1; if (kids && statistic[idx].height == compressLevel) statistic[idx].ns = root.hasSolvedChildren()? SOLVED: FAILED; else if (expectSolvedCnt > actualSolvedCnt) statistic[idx].ns = SOLVED; return hasSolved | (statistic[idx].ns == SOLVED); }
forceinline void UnstopAllCursor::processCurrentNode(void) { VisualNode* n = node(); if (n->getStatus() == STOP) { n->setStop(false); n->dirtyUp(na); } }
void TreeCanvas::mousePressEvent(QMouseEvent* event) { if (mutex.tryLock()) { if (event->button() == Qt::LeftButton) { VisualNode* n = eventNode(event); if (compareNodes) { if (n != NULL && n->getStatus() != UNDETERMINED && currentNode != NULL && currentNode->getStatus() != UNDETERMINED) { Space* curSpace = NULL; Space* compareSpace = NULL; for (int i=0; i<comparators.size(); i++) { if (comparators[i].second) { if (curSpace == NULL) { curSpace = currentNode->getSpace(*na,curBest,c_d,a_d); if (!compareNodesBeforeFP || n->isRoot()) { compareSpace = n->getSpace(*na,curBest,c_d,a_d); } else { VisualNode* p = n->getParent(*na); compareSpace = p->getSpace(*na,curBest,c_d,a_d); switch (compareSpace->status()) { case SS_SOLVED: case SS_FAILED: break; case SS_BRANCH: compareSpace->commit(*p->getChoice(), n->getAlternative(*na)); break; default: GECODE_NEVER; } } } try { comparators[i].first->compare(*curSpace,*compareSpace); } catch (Exception& e) { qFatal("Exception in comparator %d: %s.\n Stopping.", i, e.what()); } } } } } else { setCurrentNode(n); } compareNodes = false; setCursor(QCursor(Qt::ArrowCursor)); if (n != NULL) { event->accept(); mutex.unlock(); return; } } mutex.unlock(); } event->ignore(); }
bool TreeCanvas::event(QEvent* event) { if (mutex.tryLock()) { if (event->type() == QEvent::ToolTip) { VisualNode* n = eventNode(event); if (n != NULL && !n->isHidden() && (n->getStatus() == BRANCH || n->getStatus() == STOP)) { QHelpEvent* he = static_cast<QHelpEvent*>(event); QToolTip::showText(he->globalPos(), QString(n->toolTip(curBest,c_d,a_d).c_str())); } else { QToolTip::hideText(); } } mutex.unlock(); } return QWidget::event(event); }
forceinline void StatCursor::processCurrentNode(void) { VisualNode* n = node(); switch (n->getStatus()) { case SOLVED: solved++; break; case FAILED: failed++; break; case BRANCH: choice++; break; case UNDETERMINED: open++; break; default: break; } }
forceinline void HideFailedCursor::processCurrentNode(void) { VisualNode* n = node(); if (n->getStatus() == BRANCH && !n->hasSolvedChildren() && n->getNoOfOpenChildren(na) == 0) { n->setHidden(true); n->setChildrenLayoutDone(false); n->dirtyUp(na); } }
IcicleNodeStatistic IcicleTreeCanvas::initTreeStatistic(VisualNode& root, int idx, int absX) { const int kids = root.getNumberOfChildren(); auto& na = node_tree.getNA(); IcicleNodeStatistic cntRoot = IcicleNodeStatistic{kids?0: 1, 0, absX, root.getStatus()}; for (int i=0; i < kids; i++) { VisualNode& kid = *root.getChild(na, i); int kidIdx = root.getChild(i); IcicleNodeStatistic cntKid = initTreeStatistic(kid, kidIdx, absX + cntRoot.leafCnt); cntRoot.leafCnt += cntKid.leafCnt; cntRoot.height = std::max(cntRoot.height, cntKid.height + 1); } statistic[idx] = cntRoot; return cntRoot; }
void SearcherThread::run() { { if (!node->isOpen()) return; t->mutex.lock(); emit statusChanged(false); unsigned int kids = node->getNumberOfChildNodes(*t->na, t->curBest, t->stats, t->c_d, t->a_d); if (kids == 0 || node->getStatus() == STOP) { t->mutex.unlock(); updateCanvas(); emit statusChanged(true); return; } std::stack<SearchItem> stck; stck.push(SearchItem(node,kids)); t->stats.maxDepth = std::max(static_cast<long unsigned int>(t->stats.maxDepth), static_cast<long unsigned int>(depth+stck.size())); VisualNode* sol = NULL; int nodeCount = 0; t->stopSearchFlag = false; while (!stck.empty() && !t->stopSearchFlag) { if (t->refresh > 0 && nodeCount >= t->refresh) { node->dirtyUp(*t->na); updateCanvas(); emit statusChanged(false); nodeCount = 0; if (t->refreshPause > 0) msleep(t->refreshPause); } SearchItem& si = stck.top(); si.i++; if (si.i == si.noOfChildren) { stck.pop(); } else { VisualNode* n = si.n->getChild(*t->na,si.i); if (n->isOpen()) { if (n->getStatus() == UNDETERMINED) nodeCount++; kids = n->getNumberOfChildNodes(*t->na, t->curBest, t->stats, t->c_d, t->a_d); if (kids == 0) { if (n->getStatus() == SOLVED) { assert(n->hasCopy()); emit solution(n->getWorkingSpace()); n->purge(*t->na); sol = n; if (!a) break; } } else { if ( n->getStatus() != STOP ) stck.push(SearchItem(n,kids)); else if (!a) break; t->stats.maxDepth = std::max(static_cast<long unsigned int>(t->stats.maxDepth), static_cast<long unsigned int>(depth+stck.size())); } } } } node->dirtyUp(*t->na); t->stopSearchFlag = false; t->mutex.unlock(); if (sol != NULL) { t->setCurrentNode(sol,false); } else { t->setCurrentNode(node,false); } } updateCanvas(); emit statusChanged(true); if (t->finishedFlag) emit searchFinished(); }