//we fill all arrays that store the inner/outer activity status void ClusterAnalysis::init() { //does it make sense to split into detecting inner / outer activity? //is it faster to run once over the edges, with bidirectional detection //and a check if the edge is processed already, or is it at least almost //always as fast when testing from both directions? //first outactive vertices const Graph &G = m_C->constGraph(); m_iactive.init(G); m_oactive.init(G); m_ialevel.init(G, IsNotActiveBound); m_oalevel.init(G, IsNotActiveBound); delete m_oanum; delete m_ianum; delete m_bags; m_oanum = new ClusterArray<int>(*m_C, 0); m_ianum = new ClusterArray<int>(*m_C, 0); m_bags = new ClusterArray<int>(*m_C, 0); m_lcaEdges = new ClusterArray<List<edge> >(*m_C); if (m_storeoalists) m_oalists = new ClusterArray<List<node> >(*m_C); //We don't want to set dynamic depths update for clusters in m_C, //therefore we just compute the values here //top-down run through the cluster tree, depth 0 for the root ClusterArray<int> cdepth(*m_C); cdepth[m_C->rootCluster()] = 0; Queue<cluster> cq; for (cluster ci : m_C->rootCluster()->children) { cq.append(ci); } while (!cq.empty()) { cluster cc = cq.pop(); cdepth[cc] = cdepth[cc->parent()]+1; for(cluster ci : cc->children) { cq.append(ci); } } //store that we already visited e, as we don't have a static lookup //for the paths, running the search from both directions is slower. EdgeArray<bool> visited(G, false); for(node v : G.nodes) { // See comment on use of ClusterArrays above m_iactive[v] = new ClusterArray<int>(*m_C,0,m_C->maxClusterIndex()+1); m_oactive[v] = new ClusterArray<int>(*m_C,0,m_C->maxClusterIndex()+1); } for(node v : G.nodes) { for(adjEntry adj : v->adjEntries) { edge e = adj->theEdge(); if (!visited[e]) { node w = e->opposite(v); List<cluster> el; // result cluster list of path in cluster tree T between v,w cluster c1,c2; // ancestors of lca(v,w) on path, we don't really need them here cluster lca = m_C->commonClusterAncestorsPath(v, w, c1, c2, el); OGDF_ASSERT(el.size() > 0); ListIterator<cluster> ctit = el.begin();//m_C->clusterOf(v); //run over the path, set activity status (vertices are //active for a cluster if adjacent edge crosses the border //clusters before lca are left, i.e. v is outer active //clusters behind lca are entered, i.e. v is inner active while (ctit.valid() && (*ctit) != lca) { (*m_oactive[v])[*ctit]++; (*m_iactive[w])[*ctit]++; //only count vertices a single time if ((*m_oactive[v])[*ctit] == 1) (*m_oanum)[*ctit]++; if ((*m_iactive[w])[*ctit] == 1) (*m_ianum)[*ctit]++; //update the activity levels //could do this just for the last in the line... int clevel = cdepth[*ctit]; if (m_ialevel[w] > clevel) m_ialevel[w] = clevel; if (m_oalevel[v] > clevel) m_oalevel[v] = clevel; ++ctit; } OGDF_ASSERT((*ctit) == lca); //vertices are never active wrt lca //we store however the corresponding edges //for later use in bag detection (*m_lcaEdges)[lca].pushBack(e); ++ctit; while (ctit.valid()) { (*m_iactive[v])[*ctit]++; (*m_oactive[w])[*ctit]++; if ((*m_iactive[v])[*ctit] == 1) (*m_ianum)[*ctit]++; if ((*m_oactive[w])[*ctit] == 1) (*m_oanum)[*ctit]++; //update the activity levels int clevel = cdepth[*ctit]; //could do this just for the last in the line... if (m_ialevel[v] > clevel) m_ialevel[v] = clevel; if (m_oalevel[w] > clevel) m_oalevel[w] = clevel; ++ctit; } visited[e] = true; #ifdef OGDF_DEBUG std::cout << "Edge "<< v << " " << w <<"\n"; #endif } } } #ifdef OGDF_DEBUG for(node v : G.nodes) { std::cout << "Knoten "<<v<<" ist"; List<cluster> ol; List<cluster> il; for(cluster c : m_C->clusters) { if ((*m_iactive[v])[c]>0) il.pushBack(c); if ((*m_oactive[v])[c]>0) ol.pushBack(c); } std::cout << " inneractive for "; for (cluster ci : il) { std::cout << ci << ", "; } std::cout << "\n"; std::cout << " outeractive for "; for (cluster ci : ol) { std::cout << ci << ", "; } std::cout << "\n"; } #endif }
/** * @brief Saves the last place the player was. * * @param wid Unused. * @param wgt Unused. * @param tab Tab changed to. */ static void land_changeTab( unsigned int wid, char *wgt, int tab ) { int i; (void) wid; (void) wgt; unsigned int w; const char *torun_hook; unsigned int to_visit; /* Sane defaults. */ torun_hook = NULL; to_visit = 0; /* Find what switched. */ for (i=0; i<LAND_NUMWINDOWS; i++) { if (land_windowsMap[i] == tab) { last_window = i; w = land_getWid( i ); /* Must regenerate outfits. */ switch (i) { case LAND_WINDOW_MAIN: land_checkAddRefuel(); break; case LAND_WINDOW_OUTFITS: outfits_update( w, NULL ); outfits_updateQuantities( w ); to_visit = VISITED_OUTFITS; torun_hook = "outfits"; break; case LAND_WINDOW_SHIPYARD: shipyard_update( w, NULL ); to_visit = VISITED_SHIPYARD; torun_hook = "shipyard"; break; case LAND_WINDOW_BAR: bar_update( w, NULL ); to_visit = VISITED_BAR; torun_hook = "bar"; break; case LAND_WINDOW_MISSION: misn_update( w, NULL ); to_visit = VISITED_MISSION; torun_hook = "mission"; break; case LAND_WINDOW_COMMODITY: commodity_update( w, NULL ); to_visit = VISITED_COMMODITY; torun_hook = "commodity"; break; case LAND_WINDOW_EQUIPMENT: equipment_updateShips( w, NULL ); equipment_updateOutfits( w, NULL ); to_visit = VISITED_EQUIPMENT; torun_hook = "equipment"; break; default: break; } /* Clear markers if closing Mission Computer. */ if (i != LAND_WINDOW_MISSION) space_clearComputerMarkers(); break; } } /* Check land missions - always run hooks. */ /*if ((to_visit != 0) && !has_visited(to_visit)) {*/ { /* Run hooks, run after music in case hook wants to change music. */ if (torun_hook != NULL) if (hooks_run( torun_hook ) > 0) bar_genList( land_getWid(LAND_WINDOW_BAR) ); visited(to_visit); if (land_takeoff) takeoff(1); } }
void getNextUnvisited() { checkIfAllVisited(); signed char x1 = currentPosition[0]; signed char y1 = currentPosition[1]; signed char cnt =0; signed char colX=0; signed char compare; signed char rowY=0; signed char foundOne=0; //ecrobot_sound_tone(900,90,100); if((allVisited)&&(getTokensFound()!=3)) { addToPath(none); return; } if(getTokensFound()==3) { getPathComplicated(x1,y1,6,6); return; } signed char l,t,r,d; for(colX=0; colX<=12;colX++){ for(rowY=0; rowY<=12;rowY++){ mazeVisited[colX][rowY]=visited(colX,rowY); mazeDistance[colX][rowY]=0; } } //now start calculatin' mazeDistance[x1][y1]=50; for(cnt=0; cnt<=35 ; cnt++)//nah, don't calculate how much: just do it ;) { for(colX=0;colX<=12;colX++) { for(rowY=12;rowY>=0;rowY--) { //if((mazeDistance[x1][y1]!=0)){foundOne !=0 ;break;}; l=r=t=d=0; if((hasDirection(left,colX,rowY)==1) && (mazeDistance[colX-1][rowY] != 0)) { if(colX>0) l=mazeDistance[colX-1][rowY]-1; } if((hasDirection(right,colX,rowY)==1) && (mazeDistance[colX+1][rowY] != 0)) { if(colX<12) r=mazeDistance[colX+1][rowY]-1; } if((hasDirection(top,colX,rowY)==1) && (mazeDistance[colX][rowY+1] != 0)) { if(rowY<12) t=mazeDistance[colX][rowY+1]-1; } if((hasDirection(down,colX,rowY)==1) && (mazeDistance[colX][rowY-1] != 0)) { if(rowY>0) d=mazeDistance[colX][rowY-1]-1; } mazeDistance[colX][rowY]=getLargestValue(l,t,r,d,mazeDistance[colX][rowY]); } } } for(colX=0; colX<=12;colX++){ for(rowY=0; rowY<=12;rowY++){ mazeDistance[colX][rowY]=50-mazeDistance[colX][rowY]; } } for(compare=0; compare<=35;compare++) { if(foundOne){return;}; for(rowY=12;rowY>=0;rowY--) { if(foundOne){return;}; for(colX=0;colX<=12;colX++) { if((mazeVisited[colX][rowY]==0)&&(mazeDistance[colX][rowY]==compare)) { getPathComplicated(x1,y1,colX,rowY); foundOne =1; return; } } } } //alle besucht ecrobot_sound_tone(400,250,100); systick_wait_ms(250); ecrobot_sound_tone(900,250,100); systick_wait_ms(250); if(!allVisited) getPathComplicated(x1,y1,6,6); setAllVisited(1); }
void solveSudoku(vector<vector<char>>& board) { vector<pair<int, int>> v; int n = 9; for(int i = 0; i < n; ++i) { for(int j = 0; j < n; ++j) { if(board[i][j] == '.') v.emplace_back(make_pair(i, j)); } } function<bool(int)> validSquare = [&](int i) { vector<bool> visited(n + 1, false); int x = (i / 3) * 3; int y = (i % 3) * 3; for(int i = x; i < x + 3; ++i) { for(int j = y; j < y + 3; ++j) { if(board[i][j] != '.') { if(visited[board[i][j] - '0']) return false; visited[board[i][j] - '0'] = true; } } } return true; }; function<bool(int)> validCol = [&](int i) { vector<bool> visited(n + 1, false); for(int j = 0; j < n; ++j) { if(board[j][i] != '.') { if(visited[board[j][i] - '0']) return false; visited[board[j][i] - '0'] = true; } } return true; }; function<bool(int)> validRow = [&](int i) { vector<bool> visited(n + 1, false); for(int j = 0; j < n; ++j) { if(board[i][j] != '.') { if(visited[board[i][j] - '0']) return false; visited[board[i][j] - '0'] = true; } } return true; }; function<bool()> validBoard = [&]() { for(int i = 0; i < n; ++i) if(!validRow(i)) return false; for(int i = 0; i < n; ++i) if(!validCol(i)) return false; for(int i = 0; i < n; ++i) if(!validSquare(i)) return false; return true; }; function<bool(int)> dfs = [&](int i) { for(const auto& a : board) { for(const auto& b : a) { cout<<b<<" "; } cout<<endl; } cout<<"---------"<<endl; if(!validBoard()) return false; if(i == v.size()) return true; for(int j = 1; j < n + 1; ++j) { board[v[i].first][v[i].second] = '0' + j; if(dfs(i + 1)) return true; board[v[i].first][v[i].second] = '.'; } return false; }; dfs(0); }
//************************************************************* // call for SubgraphPlanarizer // returns crossing number int SimDrawCaller::callSubgraphPlanarizer(int cc, int numberOfPermutations) { // transfer edge costs if existent EdgeArray<int> ec(*m_G, 1); if(m_GA->attributes() & GraphAttributes::edgeIntWeight) { edge e; forall_edges(e,*m_G) ec[e] = m_GA->intWeight(e); } // initialize updateESG(); int crossNum = 0; PlanRep PR(*m_G); // actual call for connected component cc SubgraphPlanarizer SP; VariableEmbeddingInserter* vei = new VariableEmbeddingInserter; vei->removeReinsert(rrIncremental); SP.setInserter(vei); SP.permutations(numberOfPermutations); SP.call(PR, cc, crossNum, &ec, 0, m_esg); // insert all dummy nodes into original graph *m_G NodeArray<node> newOrigNode(PR); node vPR; forall_nodes(vPR, PR) { if(PR.isDummy(vPR)) { node vOrig = m_G->newNode(); newOrigNode[vPR] = vOrig; m_SD->isDummy(vOrig) = true; } else newOrigNode[vPR] = PR.original(vPR); //original nodes are saved } // insert all edges incident to dummy nodes into *m_G EdgeArray<bool> toBeDeleted(*m_G, false); EdgeArray<bool> visited(PR, false); forall_nodes(vPR, PR) { if(PR.isDummy(vPR)) { node vNewOrig = newOrigNode[vPR]; //lebt in *m_G edge e; forall_adj_edges(e, vPR) //lebt in PR { if(!visited[e]) { node w = e->opposite(vPR); //lebt in PR node wNewOrig = newOrigNode[w]; //lebt in *m_G edge eNewOrig = m_G->newEdge(vNewOrig,wNewOrig); m_GA->subGraphBits(eNewOrig) = m_GA->subGraphBits(PR.original(e)); toBeDeleted[PR.original(e)] = true; visited[e] = true; } } } }
void CSSSelector::extractPseudoType() const { if (m_match != PseudoClass && m_match != PseudoElement) return; AtomicString active("active"); AtomicString after("after"); AtomicString anyLink("-webkit-any-link"); AtomicString autofill("-webkit-autofill"); AtomicString before("before"); AtomicString checked("checked"); AtomicString fileUploadButton("-webkit-file-upload-button"); AtomicString disabled("disabled"); AtomicString drag("-webkit-drag"); AtomicString dragAlias("-khtml-drag"); // was documented with this name in Apple documentation, so keep an alias AtomicString empty("empty"); AtomicString enabled("enabled"); AtomicString firstChild("first-child"); AtomicString firstLetter("first-letter"); AtomicString firstLine("first-line"); AtomicString firstOfType("first-of-type"); AtomicString nthChild("nth-child("); AtomicString nthOfType("nth-of-type("); AtomicString nthLastChild("nth-last-child("); AtomicString nthLastOfType("nth-last-of-type("); AtomicString focus("focus"); AtomicString hover("hover"); AtomicString indeterminate("indeterminate"); AtomicString lastChild("last-child"); AtomicString lastOfType("last-of-type"); AtomicString link("link"); AtomicString lang("lang("); AtomicString mediaControlsPanel("-webkit-media-controls-panel"); AtomicString mediaControlsMuteButton("-webkit-media-controls-mute-button"); AtomicString mediaControlsPlayButton("-webkit-media-controls-play-button"); AtomicString mediaControlsTimeDisplay("-webkit-media-controls-time-display"); AtomicString mediaControlsTimeline("-webkit-media-controls-timeline"); AtomicString mediaControlsSeekBackButton("-webkit-media-controls-seek-back-button"); AtomicString mediaControlsSeekForwardButton("-webkit-media-controls-seek-forward-button"); AtomicString mediaControlsFullscreenButton("-webkit-media-controls-fullscreen-button"); AtomicString notStr("not("); AtomicString onlyChild("only-child"); AtomicString onlyOfType("only-of-type"); AtomicString root("root"); AtomicString searchCancelButton("-webkit-search-cancel-button"); AtomicString searchDecoration("-webkit-search-decoration"); AtomicString searchResultsDecoration("-webkit-search-results-decoration"); AtomicString searchResultsButton("-webkit-search-results-button"); AtomicString selection("selection"); AtomicString sliderThumb("-webkit-slider-thumb"); AtomicString target("target"); AtomicString visited("visited"); bool element = false; // pseudo-element bool compat = false; // single colon compatbility mode m_pseudoType = PseudoUnknown; if (m_value == active) m_pseudoType = PseudoActive; else if (m_value == after) { m_pseudoType = PseudoAfter; element = true; compat = true; } else if (m_value == anyLink) m_pseudoType = PseudoAnyLink; else if (m_value == autofill) m_pseudoType = PseudoAutofill; else if (m_value == before) { m_pseudoType = PseudoBefore; element = true; compat = true; } else if (m_value == checked) m_pseudoType = PseudoChecked; else if (m_value == fileUploadButton) { m_pseudoType = PseudoFileUploadButton; element = true; } else if (m_value == disabled) m_pseudoType = PseudoDisabled; else if (m_value == drag || m_value == dragAlias) m_pseudoType = PseudoDrag; else if (m_value == enabled) m_pseudoType = PseudoEnabled; else if (m_value == empty) m_pseudoType = PseudoEmpty; else if (m_value == firstChild) m_pseudoType = PseudoFirstChild; else if (m_value == lastChild) m_pseudoType = PseudoLastChild; else if (m_value == lastOfType) m_pseudoType = PseudoLastOfType; else if (m_value == onlyChild) m_pseudoType = PseudoOnlyChild; else if (m_value == onlyOfType) m_pseudoType = PseudoOnlyOfType; else if (m_value == firstLetter) { m_pseudoType = PseudoFirstLetter; element = true; compat = true; } else if (m_value == firstLine) { m_pseudoType = PseudoFirstLine; element = true; compat = true; } else if (m_value == firstOfType) m_pseudoType = PseudoFirstOfType; else if (m_value == focus) m_pseudoType = PseudoFocus; else if (m_value == hover) m_pseudoType = PseudoHover; else if (m_value == indeterminate) m_pseudoType = PseudoIndeterminate; else if (m_value == link) m_pseudoType = PseudoLink; else if (m_value == lang) m_pseudoType = PseudoLang; else if (m_value == mediaControlsPanel) { m_pseudoType = PseudoMediaControlsPanel; element = true; } else if (m_value == mediaControlsMuteButton) { m_pseudoType = PseudoMediaControlsMuteButton; element = true; } else if (m_value == mediaControlsPlayButton) { m_pseudoType = PseudoMediaControlsPlayButton; element = true; } else if (m_value == mediaControlsTimeDisplay) { m_pseudoType = PseudoMediaControlsTimeDisplay; element = true; } else if (m_value == mediaControlsTimeline) { m_pseudoType = PseudoMediaControlsTimeline; element = true; } else if (m_value == mediaControlsSeekBackButton) { m_pseudoType = PseudoMediaControlsSeekBackButton; element = true; } else if (m_value == mediaControlsSeekForwardButton) { m_pseudoType = PseudoMediaControlsSeekForwardButton; element = true; } else if (m_value == mediaControlsFullscreenButton) { m_pseudoType = PseudoMediaControlsFullscreenButton; element = true; } else if (m_value == notStr) m_pseudoType = PseudoNot; else if (m_value == nthChild) m_pseudoType = PseudoNthChild; else if (m_value == nthOfType) m_pseudoType = PseudoNthOfType; else if (m_value == nthLastChild) m_pseudoType = PseudoNthLastChild; else if (m_value == nthLastOfType) m_pseudoType = PseudoNthLastOfType; else if (m_value == root) m_pseudoType = PseudoRoot; else if (m_value == searchCancelButton) { m_pseudoType = PseudoSearchCancelButton; element = true; } else if (m_value == searchDecoration) { m_pseudoType = PseudoSearchDecoration; element = true; } else if (m_value == searchResultsDecoration) { m_pseudoType = PseudoSearchResultsDecoration; element = true; } else if (m_value == searchResultsButton) { m_pseudoType = PseudoSearchResultsButton; element = true; } else if (m_value == selection) { m_pseudoType = PseudoSelection; element = true; } else if (m_value == sliderThumb) { m_pseudoType = PseudoSliderThumb; element = true; } else if (m_value == target) m_pseudoType = PseudoTarget; else if (m_value == visited) m_pseudoType = PseudoVisited; if (m_match == PseudoClass && element) { if (!compat) m_pseudoType = PseudoUnknown; else m_match = PseudoElement; } else if (m_match == PseudoElement && !element) m_pseudoType = PseudoUnknown; }
// Rueckgabe: jeder vector hat die Knoten in einer SCC vector<vector<int> > scc(const vector<vector<edge> >& graph, const vector<vector<edge> >& rgraph) {// rgraph ist der Graph mit Kanten in umgekehrten Richtung vector<bool> visited(graph.size(), false); vector<bool> done(graph.size(), false); vector<bool> in_order(graph.size(), false); vector<int> order; std::stack<int> s; for (int start = 0; start < (int)graph.size(); start++) { if (visited[start]) continue; s.push(start); while (!s.empty()) { int c; do {c = s.top(); s.pop();} while (!s.empty() && (visited[c] && !done[c])); if (visited[c] && !done[c]) break; else visited[c] = true; if (done[c] && !in_order[c]) { order.push_back(c); in_order[c] = true; } else if (!done[c]) { s.push(c); for (size_t i = 0; i < graph[c].size(); i++) if (!visited[graph[c][i].to]) s.push(graph[c][i].to); done[c] = true; } } } vector<vector<int> > answer; for (size_t i = 0; i < visited.size(); i++) visited[i] = false; for (int si = (int)order.size()-1; si >= 0; si--) { const int& start = order[si]; if (visited[start]) continue; answer.push_back(vector<int>()); std::stack<int> s; s.push(start); visited[start] = true; answer.back().push_back(start); while (!s.empty()) { int c = s.top(); s.pop(); for (size_t i = 0; i < rgraph[c].size(); i++) if (!visited[rgraph[c][i].to]) { visited[rgraph[c][i].to] = true; s.push(rgraph[c][i].to); answer.back().push_back(rgraph[c][i].to); } } } return answer; }
void Graph::findNewCycles (std::vector< std::vector<vertex_t> > &cycles, std::vector<vertex_t> sub_path ) { // if (oddDupeFlag) return ; vertex_t start_node = sub_path[0]; vertex_t next_node; // visit each edge and each node of each edge for(auto edge : edges) { if( edge.has(start_node) ) { vertex_t node1 = edge.v1, node2 = edge.v2; if(node1 == start_node) next_node = node2; else next_node = node1; if( !visited(next_node, sub_path) ) { // neighbor node not on path yet std::vector<vertex_t> sub; sub.push_back(next_node); sub.insert(sub.end(), sub_path.begin(), sub_path.end()); findNewCycles(cycles, sub); } else if( sub_path.size() > 2 && next_node == sub_path.back() ) { // cycle found auto p = rotate_to_smallest(sub_path); auto inv = invert(p); if( isNew(cycles, p) && isNew(cycles, inv) ){ // std::cout << "SIZE " << p.size() << std::endl; ; int ps = (int) p.size(); if (ps % 2) { oddDupeFlag=1; cycSizes.clear(); cycSizes.push_back(-2); hasOddCycle=1; } // check if ps is contained in cycSIzes std::vector<int>::iterator first = cycSizes.begin(); std::vector<int>::iterator last = cycSizes.end(); bool psInCycSizes = false; while (first!=last) { if (*first==ps) { psInCycSizes = true; break; } ++first; } if (psInCycSizes) { // std::cout << "DUPE FOUND size " << p.size() << std::endl;; oddDupeFlag=1; cycSizes.clear(); cycSizes.push_back(-1); hasDupeCycleSize=1; } cycles.push_back( p ); cycSizes.push_back((int) p.size()); } } } } }
//build the VOR once void CVT::vor(cv::Mat & img) { cv::Mat dist(img.size(), CV_32F, cv::Scalar::all(FLT_MAX)); //an image with infinity distance cv::Mat root(img.size(), CV_16U, cv::Scalar::all(USHRT_MAX)); //an image of root index cv::Mat visited(img.size(), CV_8U, cv::Scalar::all(0)); //all unvisited //init std::vector< std::pair<float, cv::Point> > open; //YH open is a vector(float, cvPoint) ushort site_id = 0; for (auto& c : this->cells) { if (debug) { if (c.site.x<0 || c.site.x>img.size().height) std::cout << "! Warning: c.site.x=" << c.site.x << std::endl; if (c.site.y<0 || c.site.y>img.size().width) std::cout << "! Warning: c.site.y=" << c.site.y << std::endl; } cv::Point pix((int)c.site.x, (int)c.site.y); //YH a VOR site, pix(x,y) float d = color2dist(img, pix); //YH d is distance, color2dist convert a color intensity to distance between 0~1 dist.at<float>(pix.x, pix.y) = d; root.at<ushort>(pix.x, pix.y) = site_id++; open.push_back( std::make_pair(d, pix) ); c.coverage.clear(); } std::make_heap(open.begin(), open.end(), compareCell); // YH make min heap using the begining vector(pair) and the ending vector(pair) //propagate // YH do "while" for all cell and find the smallest distance as checking neighbors while (open.empty() == false) { std::pop_heap(open.begin(), open.end(), compareCell); //move the smallest element to the end auto cell = open.back(); //YH from hightest node, which has the smallest value, set cell auto& cpos = cell.second; //YH cell position open.pop_back(); // remove it //if(cell.first != dist.at<float>(cpos.x, cpos.y) )("first %f \t, dist %f \n", cell.first, dist.at<float>(cpos.x, cpos.y)); //check if the distance from this cell is already updated if (cell.first > dist.at<float>(cpos.x, cpos.y)) continue; //YH first = distance(intensity) if (visited.at<uchar>(cpos.x, cpos.y) > 0) continue; //visited //YH the if cpos already visited, skip this time and do next cell visited.at<uchar>(cpos.x, cpos.y) = 1; //check the neighbors for (int dx =-1; dx <= 1; dx++) //x is row { int x = cpos.x + dx; if (x < 0 || x >= img.size().height) continue; //YH check the x is inside an image for (int dy = -1; dy <= 1; dy++) //y is column { if (dx == 0 && dy == 0) continue; //itself... int y = cpos.y + dy; if (y < 0 || y >= img.size().width) continue; //YH check the y is inside an image float newd = dist.at<float>(cpos.x, cpos.y) + color2dist(img, cv::Point(x, y)); //YH new distance float oldd = dist.at<float>(x, y); //YH old distance //if((newd<oldd)&&oldd<100) printf("tot %.6f \t // old %.6f \n", newd, oldd);// color2dist(img, cv::Point(x, y)), dist.at<float>(cpos.x, cpos.y)); //cv::waitKey(1000); if (newd < oldd) //YH check new one has the smallest value and push it in the heap { dist.at<float>(x, y)=newd; root.at<ushort>(x, y) = root.at<ushort>(cpos.x, cpos.y); open.push_back(std::make_pair(newd, cv::Point(x, y))); // add the element at the next end of list container std::push_heap(open.begin(), open.end(), compareCell); } }//end for dy }//end for dx }//end while //collect cells for (int x = 0; x < img.size().height; x++) { for (int y = 0; y < img.size().width; y++) { ushort rootid = root.at<ushort>(x, y); this->cells[rootid].coverage.push_back(cv::Point(x,y)); // YH make coverage }//end y }//end x //remove empty cells... int cvt_size = this->cells.size(); for (int i = 0; i < cvt_size; i++) { if (this->cells[i].coverage.empty()) { this->cells[i] = this->cells.back(); this->cells.pop_back(); i--; cvt_size--; } }//end for i if (debug) { //this shows the progress... double min; double max; cv::minMaxIdx(dist, &min, &max); //YH finds global minimum and maximum array elements and returns their values and their locations cv::Mat adjMap; cv::convertScaleAbs(dist, adjMap, 255 / max); //YH scales array elements, computes absolute values and converts the results to 8-bit unsigned integers: dst(i)=saturate_cast<uchar>abs(src(i)*alpha+beta) //cv::applyColorMap(adjMap, adjMap, cv::COLORMAP_JET); for (auto& c : this->cells) { cv::circle(adjMap, cv::Point(c.site.y, c.site.x), 2, CV_RGB(0, 0, 255), -1); } //cv::imshow("CVT", adjMap); //cv::waitKey(5); } }
bool Component::computeUnfoundedSet( Var variable ) { trace_msg( unfoundedset, 1, "Starting the computation of Unfounded Set from variable " << Literal( variable, POSITIVE ) ); numberOfCalls++; vector< Var > toConsider; assert( unfoundedSet.empty() ); toConsider.push_back( variable ); visit( variable ); for( unsigned int i = 0; i < toConsider.size(); i++ ) { assert_msg( toConsider.size() <= solver.numberOfVariables(), "Loop!" ); Var next = toConsider[ i ]; assert( solver.getComponent( next ) == this ); assert( visited( next ) ); assert( !solver.isFalse( next ) ); if( getGUSData( next ).isFounded() ) continue; if( getGUSData( next ).isAux() ) { vector< Literal >& literals = getGUSData( next ).literals; #ifndef NDEBUG unsigned int count = 0; #endif for( unsigned int j = 0; j < literals.size(); j++ ) { Literal currentLiteral = literals[ j ]; Var currentVariable = currentLiteral.getVariable(); assert( !solver.isFalse( currentLiteral ) ); if( currentLiteral.isNegative() || solver.getComponent( currentVariable ) != this || getGUSData( currentVariable ).isFounded() ) continue; assert( ++count ); assert( solver.getComponent( currentVariable ) == this ); if( visited( currentVariable ) ) continue; visit( currentVariable ); toConsider.push_back( currentVariable ); } assert_msg( count > 0 && count == getGUSData( next ).numberOfSupporting, count << " - " << getGUSData( next ).numberOfSupporting ); unfoundedSet.push_back( next ); continue; } bool hasSource = false; vector< Literal >& externalLiterals = getGUSData( next ).externalLiterals; for( unsigned int j = 0; j < externalLiterals.size(); j++ ) { Literal lit = externalLiterals[ j ]; if( solver.isFalse( lit ) ) continue; trace_msg( unfoundedset, 1, "Literal " << lit << " is an external source pointer of " << Literal( next, POSITIVE ) ); propagateSourcePointer( next, lit ); hasSource = true; break; } if( hasSource ) continue; vector< Literal >& internalLiterals = getGUSData( next ).internalLiterals; for( unsigned int j = 0; j < internalLiterals.size(); j++ ) { Literal lit = internalLiterals[ j ]; assert( lit.isPositive() ); if( solver.isFalse( lit ) ) continue; Var var = lit.getVariable(); assert( solver.getComponent( var ) == this ); if( !getGUSData( var ).isFounded() ) { if( visited( var ) ) continue; visit( var ); toConsider.push_back( var ); } else { trace_msg( unfoundedset, 1, "Literal " << lit << " is an internal source pointer of " << Literal( next, POSITIVE ) ); propagateSourcePointer( next, lit ); hasSource = true; break; } } if( hasSource ) continue; assert( !unfoundedSet.existElement( next ) ); unfoundedSet.push_back( next ); } unsigned int j = 0; for( unsigned int i = 0; i < unfoundedSet.size(); i++ ) { unfoundedSet[ j ] = unfoundedSet[ i ]; if( getGUSData( unfoundedSet[ i ] ).isFounded() ) continue; getGUSData( unfoundedSet[ i ] ).setInUnfoundedSet(); j++; if( conflict || !solver.isTrue( unfoundedSet[ i ] ) ) continue; assert( conflict == 0 ); assert( unfoundedSet[ i ] != 0 ); conflict = unfoundedSet[ i ]; } unfoundedSet.shrink( j ); return !unfoundedSet.empty(); }
/** * \brief Non-recusrive start point for performing DFS */ bool DirectedDFS::searchForPath(const Point2d &start, const Point2d &goal, uint32_t depth, bool in_obstacle_space) { std::vector<bool> visited(map_.info.height * map_.info.width, false); return searchForPath(start, goal, depth, visited, in_obstacle_space); }
void FaceSinkGraph::sinkSwitches(FaceArray< List<adjEntry> > &faceSwitches) { OGDF_ASSERT(m_pE->externalFace() != nullptr); List<adjEntry> dummyList; faceSwitches.init(*m_pE, dummyList); NodeArray<bool> visited(m_pE->getGraph(), false); List<face> toDo; FaceArray<bool> faceDone(*m_pE, false); #if 0 m_pE->getGraph().writeGML("c:/temp/debug.gml"); #endif //compute sink-switches for the ext. face for(adjEntry adj : m_pE->externalFace()->entries) { node u = adj->theNode(); if (u->outdeg() == 0 && !visited[u]) faceSwitches[m_pE->externalFace()].pushBack(adj); if (u->indeg() > 1 && !visited[u]) { List<edge> outEdges; u->outEdges(outEdges); if (outEdges.empty()) { for(adjEntry run : u->adjEntries) { if (m_pE->rightFace(run) != m_pE->externalFace()) toDo.pushBack(m_pE->rightFace(run)); } } else { edge e = outEdges.front(); adjEntry run = e->adjSource(); run = run->cyclicSucc(); while (run->theEdge() != e) { adjEntry next = run->cyclicSucc(); if (next->theEdge()->target() == u && run->theEdge()->target() == u) toDo.pushBack(m_pE->rightFace(run)); run = run->cyclicSucc(); } } } visited[u] = true; } faceDone[m_pE->externalFace()] = true; while (!toDo.empty()) { face f = toDo.popFrontRet(); if (faceDone[f]) continue; for(adjEntry adj : f->entries) { node u = adj->theNode(); if (visited[u] && adj->theEdge()->target() == adj->faceCyclePred()->theEdge()->target() && m_pE->rightFace(adj) != m_pE->leftFace(adj)) faceSwitches[f].pushFront(adj); // the top sink switch of f else { if (u->outdeg() == 0) faceSwitches[f].pushBack(adj); // the non top sink switch of f } if (u->indeg() > 1) { List<edge> outEdges; u->outEdges(outEdges); if (outEdges.empty()) { for(adjEntry run : u->adjEntries) { if (m_pE->rightFace(run) != f) toDo.pushBack(m_pE->rightFace(run)); } } else { edge e = outEdges.front(); adjEntry run = e->adjSource(); run = run->cyclicSucc(); while (run->theEdge() != e) { adjEntry next = run->cyclicSucc(); if (next->theEdge()->target() == u && run->theEdge()->target() == u) toDo.pushBack(m_pE->rightFace(run)); run = run->cyclicSucc(); } } } visited[u] = true; } faceDone[f] = true; OGDF_ASSERT(!faceSwitches[f].empty()); } #if 0 std::cout << std::endl; std::cout << "switche (FaceSinkGraph::sinkSwitches) : " << std::endl; for(face f : m_pE->faces) { std::cout << "face : " << f->index() << std::endl; const List<adjEntry> &adjList = faceSwitches[f]; for(adjEntry adj : adjList) { std::cout << adj->theNode() << "; "; } std::cout << std::endl; } #endif }
Reachability::Result *VipsBitReachability::reachability(Arg *arg) const{ const Machine &machine = arg->machine; Result *result = new Result(machine); result->timer.start(); result->result = UNREACHABLE; bool found_forbidden = false; VipsBitConstraint::Common common(machine); /* buf contains constraints that have been found but not explored */ CBuf buf(CBuf::QUEUE); /* The set of keys of visited is the set of visited constraints. * Each visited constraint maps to a description of its parent. */ std::map<const VipsBitConstraint*,parent_t,vbcmp_t> visited(get_comparator(common)); /* Find the initial constraints */ { std::set<VipsBitConstraint*> init = common.get_initial_constraints(); result->generated_constraints = result->stored_constraints = init.size(); for(auto it = init.begin(); it != init.end(); ++it){ if((*it)->is_forbidden(common)){ result->trace = new Trace(0); result->result = REACHABLE; found_forbidden = true; } buf.push(*it); visited[*it] = parent_t(); } } while(!found_forbidden && buf.size()){ const VipsBitConstraint *vbc = buf.pop(); VecSet<const Machine::PTransition*> transes = vbc->partred(common); for(int i = 0; !found_forbidden && i < transes.size(); ++i){ VipsBitConstraint *child = vbc->post(common,*transes[i]); if(child){ ++result->generated_constraints; if(visited.count(child)){ common.dealloc(child); }else{ visited[child] = parent_t(transes[i],vbc); buf.push(child); if(child->is_forbidden(common)){ result->result = REACHABLE; found_forbidden = true; /* Construct trace */ { Trace tr(0); const parent_t *pt = &visited[child]; while(pt->parent){ tr.push_front(0,*pt->trans); pt = &visited[pt->parent]; } result->trace = VipsBitConstraint::explicit_vips_trace(tr); } } } } } } result->stored_constraints = visited.size(); /* Cleanup */ /* Destruction of common automatically cleans up the remaining * constraints. */ result->timer.stop(); return result; };
// Constructor from components Foam::labelList Foam::bandCompression(const labelListList& cellCellAddressing) { labelList newOrder(cellCellAddressing.size()); // the business bit of the renumbering SLList<label> nextCell; labelList visited(cellCellAddressing.size()); label currentCell; label cellInOrder = 0; // reset the visited cells list forAll (visited, cellI) { visited[cellI] = 0; } // loop over the cells forAll (visited, cellI) { // find the first cell that has not been visited yet if (visited[cellI] == 0) { currentCell = cellI; // use this cell as a start nextCell.append(currentCell); // loop through the nextCell list. Add the first cell into the // cell order if it has not already been visited and ask for its // neighbours. If the neighbour in question has not been visited, // add it to the end of the nextCell list while (nextCell.size()) { currentCell = nextCell.removeHead(); if (visited[currentCell] == 0) { visited[currentCell] = 1; // add into cellOrder newOrder[cellInOrder] = currentCell; cellInOrder++; // find if the neighbours have been visited const labelList& neighbours = cellCellAddressing[currentCell]; forAll (neighbours, nI) { if (visited[neighbours[nI]] == 0) { // not visited, add to the list nextCell.append(neighbours[nI]); } } } } }
/// @par /// /// Non-null regions will consist of connected, non-overlapping walkable spans that form a single contour. /// Contours will form simple polygons. /// /// If multiple regions form an area that is smaller than @p minRegionArea, then all spans will be /// re-assigned to the zero (null) region. /// /// Watershed partitioning can result in smaller than necessary regions, especially in diagonal corridors. /// @p mergeRegionArea helps reduce unecessarily small regions. /// /// See the #rcConfig documentation for more information on the configuration parameters. /// /// The region data will be available via the rcCompactHeightfield::maxRegions /// and rcCompactSpan::reg fields. /// /// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions. /// /// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig bool rcBuildRegions(rcCompactHeightfield& chf, const int borderSize, const int minRegionArea, const int mergeRegionArea) { const int w = chf.width; const int h = chf.height; rcScopedDelete<unsigned short> buf = (unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount*4, RC_ALLOC_TEMP); if (!buf) { return false; } const int LOG_NB_STACKS = 3; const int NB_STACKS = 1 << LOG_NB_STACKS; rcIntArray lvlStacks[NB_STACKS]; for (int i=0; i<NB_STACKS; ++i) lvlStacks[i].resize(1024); rcIntArray stack(1024); rcIntArray visited(1024); unsigned short* srcReg = buf; unsigned short* srcDist = buf+chf.spanCount; unsigned short* dstReg = buf+chf.spanCount*2; unsigned short* dstDist = buf+chf.spanCount*3; memset(srcReg, 0, sizeof(unsigned short)*chf.spanCount); memset(srcDist, 0, sizeof(unsigned short)*chf.spanCount); unsigned short regionId = 1; unsigned short level = (chf.maxDistance+1) & ~1; // TODO: Figure better formula, expandIters defines how much the // watershed "overflows" and simplifies the regions. Tying it to // agent radius was usually good indication how greedy it could be. // const int expandIters = 4 + walkableRadius * 2; const int expandIters = 8; if (borderSize > 0) { // Make sure border will not overflow. const int bw = rcMin(w, borderSize); const int bh = rcMin(h, borderSize); // Paint regions paintRectRegion(0, bw, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(w-bw, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(0, w, 0, bh, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(0, w, h-bh, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; chf.borderSize = borderSize; } int sId = -1; while (level > 0) { level = level >= 2 ? level-2 : 0; sId = (sId+1) & (NB_STACKS-1); if (sId == 0) sortCellsByLevel(level, chf, srcReg, NB_STACKS, lvlStacks, 1); else appendStacks(lvlStacks[sId-1], lvlStacks[sId], srcReg); // copy left overs from last level // Expand current regions until no empty connected cells found. if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, lvlStacks[sId], false) != srcReg) { rcSwap(srcReg, dstReg); rcSwap(srcDist, dstDist); } // Mark new regions with IDs. for (int j=0; j<lvlStacks[sId].size(); j+=3) { int x = lvlStacks[sId][j]; int y = lvlStacks[sId][j+1]; int i = lvlStacks[sId][j+2]; if (i >= 0 && srcReg[i] == 0) { if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack)) regionId++; } } } // Expand current regions until no empty connected cells found. if (expandRegions(expandIters*8, 0, chf, srcReg, srcDist, dstReg, dstDist, stack, true) != srcReg) { rcSwap(srcReg, dstReg); rcSwap(srcDist, dstDist); } // Filter out small regions. chf.maxRegions = regionId; if (!filterSmallRegions(minRegionArea, mergeRegionArea, chf.maxRegions, chf, srcReg)) return false; // Write the result out. for (int i = 0; i < chf.spanCount; ++i) chf.spans[i].reg = srcReg[i]; return true; }
dtStatus dtBuildTileCacheRegions(dtTileCacheAlloc* alloc, const int minRegionArea, const int mergeRegionArea, dtTileCacheLayer& layer, dtTileCacheDistanceField dfield) { dtAssert(alloc); const int w = (int)layer.header->width; const int h = (int)layer.header->height; const int size = w*h; dtFixedArray<unsigned short> buf(alloc, size*4); if (!buf) { return DT_FAILURE | DT_OUT_OF_MEMORY; } dtIntArray stack(1024); dtIntArray visited(1024); unsigned short* srcReg = buf; unsigned short* srcDist = buf+size; unsigned short* dstReg = buf+size*2; unsigned short* dstDist = buf+size*3; memset(srcReg, 0, sizeof(unsigned short)*size); memset(srcDist, 0, sizeof(unsigned short)*size); unsigned short regionId = 1; unsigned short level = (dfield.maxDist+1) & ~1; // TODO: Figure better formula, expandIters defines how much the // watershed "overflows" and simplifies the regions. Tying it to // agent radius was usually good indication how greedy it could be. // const int expandIters = 4 + walkableRadius * 2; const int expandIters = 8; while (level > 0) { level = level >= 2 ? level-2 : 0; // Expand current regions until no empty connected cells found. if (expandRegions(expandIters, level, layer, dfield, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { dtSwap(srcReg, dstReg); dtSwap(srcDist, dstDist); } // Mark new regions with IDs. for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { const int i=x+y*w; if (dfield.data[i] < level || srcReg[i] != 0 || layer.areas[i] == DT_TILECACHE_NULL_AREA) continue; if (floodRegion(x, y, i, level, regionId, layer, dfield, srcReg, srcDist, stack)) regionId++; } } } // Expand current regions until no empty connected cells found. if (expandRegions(expandIters*8, 0, layer, dfield, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { dtSwap(srcReg, dstReg); dtSwap(srcDist, dstDist); } dtStatus status = filterSmallRegions(alloc, layer, minRegionArea, mergeRegionArea, regionId, srcReg); if (dtStatusFailed(status)) { return status; } // Write the result out. memcpy(layer.regs, srcReg, sizeof(unsigned short)*size); layer.regCount = regionId; return DT_SUCCESS; }
/// @par /// /// Non-null regions will consist of connected, non-overlapping walkable spans that form a single contour. /// Contours will form simple polygons. /// /// If multiple regions form an area that is smaller than @p minRegionArea, then all spans will be /// re-assigned to the zero (null) region. /// /// Watershed partitioning can result in smaller than necessary regions, especially in diagonal corridors. /// @p mergeRegionArea helps reduce unecessarily small regions. /// /// See the #rcConfig documentation for more information on the configuration parameters. /// /// The region data will be available via the rcCompactHeightfield::maxRegions /// and rcCompactSpan::reg fields. /// /// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions. /// /// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf, const int borderSize, const int minRegionArea, const int mergeRegionArea) { rcAssert(ctx); ctx->startTimer(RC_TIMER_BUILD_REGIONS); const int w = chf.width; const int h = chf.height; rcScopedDelete<unsigned short> buf = (unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount*4, RC_ALLOC_TEMP); if (!buf) { ctx->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'tmp' (%d).", chf.spanCount*4); return false; } ctx->startTimer(RC_TIMER_BUILD_REGIONS_WATERSHED); rcIntArray stack(1024); rcIntArray visited(1024); unsigned short* srcReg = buf; unsigned short* srcDist = buf+chf.spanCount; unsigned short* dstReg = buf+chf.spanCount*2; unsigned short* dstDist = buf+chf.spanCount*3; memset(srcReg, 0, sizeof(unsigned short)*chf.spanCount); memset(srcDist, 0, sizeof(unsigned short)*chf.spanCount); unsigned short regionId = 1; unsigned short level = (chf.maxDistance+1) & ~1; // TODO: Figure better formula, expandIters defines how much the // watershed "overflows" and simplifies the regions. Tying it to // agent radius was usually good indication how greedy it could be. // const int expandIters = 4 + walkableRadius * 2; const int expandIters = 8; if (borderSize > 0) { // Make sure border will not overflow. const int bw = rcMin(w, borderSize); const int bh = rcMin(h, borderSize); // Paint regions paintRectRegion(0, bw, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(w-bw, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(0, w, 0, bh, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(0, w, h-bh, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; chf.borderSize = borderSize; } while (level > 0) { level = level >= 2 ? level-2 : 0; ctx->startTimer(RC_TIMER_BUILD_REGIONS_EXPAND); // Expand current regions until no empty connected cells found. if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { rcSwap(srcReg, dstReg); rcSwap(srcDist, dstDist); } ctx->stopTimer(RC_TIMER_BUILD_REGIONS_EXPAND); ctx->startTimer(RC_TIMER_BUILD_REGIONS_FLOOD); // Mark new regions with IDs. for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { const rcCompactCell& c = chf.cells[x+y*w]; for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) { if (chf.dist[i] < level || srcReg[i] != 0 || chf.areas[i] == RC_NULL_AREA) continue; if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack)) regionId++; } } } ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FLOOD); } // Expand current regions until no empty connected cells found. if (expandRegions(expandIters*8, 0, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { rcSwap(srcReg, dstReg); rcSwap(srcDist, dstDist); } ctx->stopTimer(RC_TIMER_BUILD_REGIONS_WATERSHED); ctx->startTimer(RC_TIMER_BUILD_REGIONS_FILTER); // Filter out small regions. chf.maxRegions = regionId; if (!filterSmallRegions(ctx, minRegionArea, mergeRegionArea, chf.maxRegions, chf, srcReg)) return false; ctx->stopTimer(RC_TIMER_BUILD_REGIONS_FILTER); // Write the result out. for (int i = 0; i < chf.spanCount; ++i) chf.spans[i].reg = srcReg[i]; ctx->stopTimer(RC_TIMER_BUILD_REGIONS); return true; }
bool rcBuildRegions(rcCompactHeightfield& chf, int borderSize, int minRegionSize, int mergeRegionSize) { rcTimeVal startTime = rcGetPerformanceTimer(); const int w = chf.width; const int h = chf.height; if (!chf.regs) { chf.regs = new unsigned short[chf.spanCount]; if (!chf.regs) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'chf.reg' (%d).", chf.spanCount); return false; } } rcScopedDelete<unsigned short> tmp = new unsigned short[chf.spanCount*4]; if (!tmp) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'tmp' (%d).", chf.spanCount*4); return false; } rcTimeVal regStartTime = rcGetPerformanceTimer(); rcIntArray stack(1024); rcIntArray visited(1024); unsigned short* srcReg = tmp; unsigned short* srcDist = tmp+chf.spanCount; unsigned short* dstReg = tmp+chf.spanCount*2; unsigned short* dstDist = tmp+chf.spanCount*3; memset(srcReg, 0, sizeof(unsigned short)*chf.spanCount); memset(srcDist, 0, sizeof(unsigned short)*chf.spanCount); unsigned short regionId = 1; unsigned short level = (chf.maxDistance+1) & ~1; // TODO: Figure better formula, expandIters defines how much the // watershed "overflows" and simplifies the regions. Tying it to // agent radius was usually good indication how greedy it could be. // const int expandIters = 4 + walkableRadius * 2; const int expandIters = 8; // Mark border regions. paintRectRegion(0, borderSize, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(w-borderSize, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(0, w, 0, borderSize, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(0, w, h-borderSize, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; rcTimeVal expTime = 0; rcTimeVal floodTime = 0; while (level > 0) { level = level >= 2 ? level-2 : 0; rcTimeVal expStartTime = rcGetPerformanceTimer(); // Expand current regions until no empty connected cells found. if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { rcSwap(srcReg, dstReg); rcSwap(srcDist, dstDist); } expTime += rcGetPerformanceTimer() - expStartTime; rcTimeVal floodStartTime = rcGetPerformanceTimer(); // Mark new regions with IDs. for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { const rcCompactCell& c = chf.cells[x+y*w]; for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) { if (chf.dist[i] < level || srcReg[i] != 0 || chf.areas[i] == RC_NULL_AREA) continue; if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack)) regionId++; } } } floodTime += rcGetPerformanceTimer() - floodStartTime; } // Expand current regions until no empty connected cells found. if (expandRegions(expandIters*8, 0, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { rcSwap(srcReg, dstReg); rcSwap(srcDist, dstDist); } rcTimeVal regEndTime = rcGetPerformanceTimer(); rcTimeVal filterStartTime = rcGetPerformanceTimer(); // Filter out small regions. chf.maxRegions = regionId; if (!filterSmallRegions(minRegionSize, mergeRegionSize, chf.maxRegions, chf, srcReg)) return false; rcTimeVal filterEndTime = rcGetPerformanceTimer(); // Write the result out. memcpy(chf.regs, srcReg, sizeof(unsigned short)*chf.spanCount); rcTimeVal endTime = rcGetPerformanceTimer(); /* if (rcGetLog()) { rcGetLog()->log(RC_LOG_PROGRESS, "Build regions: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - reg: %.3f ms", rcGetDeltaTimeUsec(regStartTime, regEndTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - exp: %.3f ms", rcGetDeltaTimeUsec(0, expTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - flood: %.3f ms", rcGetDeltaTimeUsec(0, floodTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - filter: %.3f ms", rcGetDeltaTimeUsec(filterStartTime, filterEndTime)/1000.0f); } */ if (rcGetBuildTimes()) { rcGetBuildTimes()->buildRegions += rcGetDeltaTimeUsec(startTime, endTime); rcGetBuildTimes()->buildRegionsReg += rcGetDeltaTimeUsec(regStartTime, regEndTime); rcGetBuildTimes()->buildRegionsExp += rcGetDeltaTimeUsec(0, expTime); rcGetBuildTimes()->buildRegionsFlood += rcGetDeltaTimeUsec(0, floodTime); rcGetBuildTimes()->buildRegionsFilter += rcGetDeltaTimeUsec(filterStartTime, filterEndTime); } return true; }
//=======================================================================// unsigned fordFulkerson(const CommonGraphPtr& graph, unsigned source, unsigned sink) { std::vector<std::vector<int>> residualGraph(graph->numberOfVertices_); for (unsigned i = 0; i < graph->numberOfVertices_; ++i) { residualGraph[i].resize(graph->numberOfVertices_); for (unsigned j = 0; j < graph->numberOfVertices_; ++j) { auto cost = graph->getCost(i, j); residualGraph[i][j] = cost; } } // std::vector<std::vector<int>> backFlow(graph->numberOfVertices_); // for (unsigned i = 0; i < graph->numberOfVertices_; ++i) // { // backFlow[i].resize(graph->numberOfVertices_); // } std::vector<int> parents(graph->numberOfVertices_, -1); int maxFlow = 0; int j; auto bfs = [&]() -> bool { std::vector<bool> visited(graph->numberOfVertices_, false); std::queue<int> q; q.push(source); visited[source] = true; parents[source] = -1; // Standard BFS Loop while (!q.empty()) { int u = q.front(); q.pop(); for (int v=0; v<graph->numberOfVertices_; ++v) { if (visited[v] == false && residualGraph[u][v] > 0) { q.push(v); parents[v] = u; visited[v] = true; } } } // If we reached sink in BFS starting from source, then return // true, else false return visited[sink]; }; // auto dfs = [&]() -> bool // { // std::vector<bool> visited(graph->numberOfVertices_, false); // std::stack<int> q; // q.push(source); // visited[source] = true; // parents[source] = -1; // // // Standard BFS Loop // while (!q.empty()) // { // int u = q.top(); // q.pop(); // // for (int v=graph->numberOfVertices_-1; v>=0; --v) // { // if (visited[v] == false && residualGraph[u][v] > 0) // { // q.push(v); // parents[v] = u; // visited[v] = true; // } // } // } // // // If we reached sink in BFS starting from source, then return // // true, else false // return visited[sink] == true; // }; while (bfs()) { int pathFlow = std::numeric_limits<int>::max(); for (int i=sink; i!=source; i=parents[i]) { j = parents[i]; if (residualGraph[j][i] < pathFlow) { pathFlow = residualGraph[j][i]; } } for (int i=sink; i != source; i=parents[i]) { j = parents[i]; residualGraph[j][i] -= pathFlow; residualGraph[i][j] += pathFlow; } maxFlow += pathFlow; } const int setwLength = 6; std::cout << std::setw(setwLength) << "from" << std::setw(setwLength) << "to" << std::setw(setwLength) << "max" << " / curr" << std::endl; auto edges = graph->getEdges(); for (const auto& e : edges) { auto s = e.from; auto d = e.to; auto maxFlow = e.cost; auto flow = maxFlow - residualGraph[s][d]; std::cout << std::setw(setwLength) << s << std::setw(setwLength) << d << std::setw(setwLength) << maxFlow << " / " << flow << std::endl; } return maxFlow; }
void BFS(std::vector< std::vector<int> > &edges) { std::vector<bool> visited(edges.size(), false); for (int i = 0; i < edges.size(); i++) if (!visited[i]) BFS(edges, visited, i); }
bool canPartitionKSubsets(vector<int>& nums, int k) { int sum = accumulate(nums.begin(), nums.end(), 0); if (sum % k != 0) return false; vector<bool> visited(nums.size(), false); return helper(nums, k, sum / k, 0, 0, visited); }
void BlockTab::print( ostream &out ) { vector< bool > visited( curBlockNum + 1, false ); print( blockList[ 1 ], visited, out ); }
bool rcBuildRegions(rcCompactHeightfield& chf, int walkableRadius, int borderSize, int minRegionSize, int mergeRegionSize) { rcTimeVal startTime = rcGetPerformanceTimer(); const int w = chf.width; const int h = chf.height; unsigned short* tmp1 = new unsigned short[chf.spanCount*2]; if (!tmp1) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildDistanceField: Out of memory 'tmp1' (%d).", chf.spanCount*2); return false; } unsigned short* tmp2 = new unsigned short[chf.spanCount*2]; if (!tmp2) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildDistanceField: Out of memory 'tmp2' (%d).", chf.spanCount*2); delete [] tmp1; return false; } rcTimeVal regStartTime = rcGetPerformanceTimer(); rcIntArray stack(1024); rcIntArray visited(1024); unsigned short* src = tmp1; unsigned short* dst = tmp2; memset(src, 0, sizeof(unsigned short) * chf.spanCount*2); unsigned short regionId = 1; unsigned short level = (chf.maxDistance+1) & ~1; unsigned short minLevel = (unsigned short)(walkableRadius*2); const int expandIters = 4 + walkableRadius * 2; // Mark border regions. paintRectRegion(0, borderSize, 0, h, regionId|RC_BORDER_REG, minLevel, chf, src); regionId++; paintRectRegion(w-borderSize, w, 0, h, regionId|RC_BORDER_REG, minLevel, chf, src); regionId++; paintRectRegion(0, w, 0, borderSize, regionId|RC_BORDER_REG, minLevel, chf, src); regionId++; paintRectRegion(0, w, h-borderSize, h, regionId|RC_BORDER_REG, minLevel, chf, src); regionId++; rcTimeVal expTime = 0; rcTimeVal floodTime = 0; while (level > minLevel) { level = level >= 2 ? level-2 : 0; rcTimeVal expStartTime = rcGetPerformanceTimer(); // Expand current regions until no empty connected cells found. if (expandRegions(expandIters, level, chf, src, dst, stack) != src) rcSwap(src, dst); expTime += rcGetPerformanceTimer() - expStartTime; rcTimeVal floodStartTime = rcGetPerformanceTimer(); // Mark new regions with IDs. for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { const rcCompactCell& c = chf.cells[x+y*w]; for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) { if (chf.spans[i].dist < level || src[i*2] != 0) continue; if (floodRegion(x, y, i, minLevel, level, regionId, chf, src, stack)) regionId++; } } } floodTime += rcGetPerformanceTimer() - floodStartTime; } // Expand current regions until no empty connected cells found. if (expandRegions(expandIters*8, minLevel, chf, src, dst, stack) != src) rcSwap(src, dst); rcTimeVal regEndTime = rcGetPerformanceTimer(); rcTimeVal filterStartTime = rcGetPerformanceTimer(); // Filter out small regions. chf.maxRegions = regionId; if (!filterSmallRegions(minRegionSize, mergeRegionSize, chf.maxRegions, chf, src)) return false; rcTimeVal filterEndTime = rcGetPerformanceTimer(); // Write the result out. for (int i = 0; i < chf.spanCount; ++i) chf.spans[i].reg = src[i*2]; delete [] tmp1; delete [] tmp2; rcTimeVal endTime = rcGetPerformanceTimer(); /* if (rcGetLog()) { rcGetLog()->log(RC_LOG_PROGRESS, "Build regions: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - reg: %.3f ms", rcGetDeltaTimeUsec(regStartTime, regEndTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - exp: %.3f ms", rcGetDeltaTimeUsec(0, expTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - flood: %.3f ms", rcGetDeltaTimeUsec(0, floodTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - filter: %.3f ms", rcGetDeltaTimeUsec(filterStartTime, filterEndTime)/1000.0f); } */ if (rcGetBuildTimes()) { rcGetBuildTimes()->buildRegions += rcGetDeltaTimeUsec(startTime, endTime); rcGetBuildTimes()->buildRegionsReg += rcGetDeltaTimeUsec(regStartTime, regEndTime); rcGetBuildTimes()->buildRegionsExp += rcGetDeltaTimeUsec(0, expTime); rcGetBuildTimes()->buildRegionsFlood += rcGetDeltaTimeUsec(0, floodTime); rcGetBuildTimes()->buildRegionsFilter += rcGetDeltaTimeUsec(filterStartTime, filterEndTime); } return true; }
void BlockTab::applyT2(void) { vector<bool> visited(curBlockNum + 1, false); applyT2(blockList[1], visited); }
/** * @brief Recreates the land windows. * * @param load Is loading game? * @param changetab Should it change to the last open tab? */ void land_genWindows( int load, int changetab ) { int i, j; const char *names[LAND_NUMWINDOWS]; int w, h; Planet *p; int regen; /* Destroy old window if exists. */ if (land_wid > 0) { land_regen = 2; /* Mark we're regenning. */ window_destroy(land_wid); } land_loaded = 0; /* Get planet. */ p = land_planet; regen = landed; /* Create window. */ if ((gl_screen.rw < 1024) || (gl_screen.rh < 768)) { w = -1; /* Fullscreen. */ h = -1; } else { w = 800 + 0.5 * (SCREEN_W - 800); h = 600 + 0.5 * (SCREEN_H - 600); } land_wid = window_create( p->name, -1, -1, w, h ); window_onClose( land_wid, land_cleanupWindow ); /* Set window map to invalid. */ for (i=0; i<LAND_NUMWINDOWS; i++) land_windowsMap[i] = -1; /* See what is available. */ j = 0; /* Main. */ land_windowsMap[LAND_WINDOW_MAIN] = j; names[j++] = land_windowNames[LAND_WINDOW_MAIN]; /* Bar. */ if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) { land_windowsMap[LAND_WINDOW_BAR] = j; names[j++] = land_windowNames[LAND_WINDOW_BAR]; } /* Missions. */ if (planet_hasService(land_planet, PLANET_SERVICE_MISSIONS)) { land_windowsMap[LAND_WINDOW_MISSION] = j; names[j++] = land_windowNames[LAND_WINDOW_MISSION]; } /* Outfits. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS)) { land_windowsMap[LAND_WINDOW_OUTFITS] = j; names[j++] = land_windowNames[LAND_WINDOW_OUTFITS]; } /* Shipyard. */ if (planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) { land_windowsMap[LAND_WINDOW_SHIPYARD] = j; names[j++] = land_windowNames[LAND_WINDOW_SHIPYARD]; } /* Equipment. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS) || planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) { land_windowsMap[LAND_WINDOW_EQUIPMENT] = j; names[j++] = land_windowNames[LAND_WINDOW_EQUIPMENT]; } /* Commodity. */ if (planet_hasService(land_planet, PLANET_SERVICE_COMMODITY)) { land_windowsMap[LAND_WINDOW_COMMODITY] = j; names[j++] = land_windowNames[LAND_WINDOW_COMMODITY]; } /* Create tabbed window. */ land_windows = window_addTabbedWindow( land_wid, -1, -1, -1, -1, "tabLand", j, names, 0 ); /* * Order here is very important: * * 1) Create main tab - must have decent background. * 2) Set landed, play music and run land hooks - so hooks run well. * 3) Generate missions - so that campaigns are fluid. * 4) Create other tabs - lists depend on NPC and missions. */ /* 1) Create main tab. */ land_createMainTab( land_getWid(LAND_WINDOW_MAIN) ); /* 2) Set as landed and run hooks. */ if (!regen) { landed = 1; music_choose("land"); /* Must be before hooks in case hooks change music. */ if (!load) { hooks_run("land"); } events_trigger( EVENT_TRIGGER_LAND ); /* 3) Generate computer and bar missions. */ if (planet_hasService(land_planet, PLANET_SERVICE_MISSIONS)) mission_computer = missions_genList( &mission_ncomputer, land_planet->faction, land_planet->name, cur_system->name, MIS_AVAIL_COMPUTER ); if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) npc_generate(); /* Generate bar npc. */ } /* 4) Create other tabs. */ /* Basic - bar + missions */ if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) bar_open( land_getWid(LAND_WINDOW_BAR) ); if (planet_hasService(land_planet, PLANET_SERVICE_MISSIONS)) misn_open( land_getWid(LAND_WINDOW_MISSION) ); /* Outfits. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS)) outfits_open( land_getWid(LAND_WINDOW_OUTFITS) ); /* Shipyard. */ if (planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) shipyard_open( land_getWid(LAND_WINDOW_SHIPYARD) ); /* Equipment. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS) || planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) equipment_open( land_getWid(LAND_WINDOW_EQUIPMENT) ); /* Commodity. */ if (planet_hasService(land_planet, PLANET_SERVICE_COMMODITY)) commodity_exchange_open( land_getWid(LAND_WINDOW_COMMODITY) ); if (!regen) { /* Reset markers if needed. */ mission_sysMark(); /* Check land missions. */ if (!has_visited(VISITED_LAND)) { missions_run(MIS_AVAIL_LAND, land_planet->faction, land_planet->name, cur_system->name); visited(VISITED_LAND); } } /* Go to last open tab. */ window_tabWinOnChange( land_wid, "tabLand", land_changeTab ); if (changetab && land_windowsMap[ last_window ] != -1) window_tabWinSetActive( land_wid, "tabLand", land_windowsMap[ last_window ] ); /* Add fuel button if needed - AFTER missions pay :). */ land_checkAddRefuel(); /* Finished loading. */ land_loaded = 1; }
/** Function make_cluster() * * Given a list of fragments denoted by seeds, make pairwise comparison * and clustering conforming max_mismatch criteria * * Output: clusters in 2d vector format, where each row of the vector * stores the clustered fragment IDs. */ void make_cluster (iivec_t& clusters, const ii64vec_t& list_seeds, const ivec_t& init_cluster, int max_mismatch, const ivec_t& uf_clst) { if (list_seeds.size() == 0) { abording ("DuplRm.cpp -- make_cluster(): SC failed"); } //--------- union find: (1) initialize the cluster --------- int sz = init_cluster.size(); bvec_t visited (sz, false); ivec_t clst (sz); for (int i = 0; i < sz; ++ i) clst[i] = i; //--------- pairwise comparison --------- for (int i = 0; i < sz - 1; ++ i) { if (visited[i]) continue; // to speed up int idx_i = init_cluster[i]; for (int j = i + 1; j < sz; ++ j) { if (visited[j]) continue; // to speed up, avoid of comparison // if this is already clustered int idx_j = init_cluster[j]; // check global uf structure according to fragID int root_uf_i = uf_clsfind ((int) list_seeds[idx_i].back(), uf_clst), root_uf_j = uf_clsfind ((int) list_seeds[idx_j].back(), uf_clst); if (root_uf_i != root_uf_j) { int root_i = uf_find (i, clst), root_j = uf_find (j, clst); if (root_i != root_j) { if (is_similar (list_seeds[idx_i], list_seeds[idx_j], max_mismatch)) { clst[root_j] = root_i; visited[j] = true; } } } // if } // for (int j = i + 1 } // for (int i = 0 //----- generate final cluster { clusterID --> fragment IDs } ------ std::map<int, ivec_t> clstID_fragIDs; std::map<int, ivec_t>::iterator it; for (int i = 0; i < sz; ++ i) { int idx_i = init_cluster[i]; int fragID = list_seeds[idx_i].back(); int root_i = uf_clsfind (i, clst); it = clstID_fragIDs.find (root_i); if (it != clstID_fragIDs.end()) it->second.push_back(fragID); else clstID_fragIDs[root_i] = ivec_t (1, fragID); } // for (int i = 0 // go through the map and produce clusters in sorted vector format for (it = clstID_fragIDs.begin(); it != clstID_fragIDs.end(); ++ it) { if (it->second.size() > 1) { std::sort (it->second.begin(), it->second.end()); clusters.push_back(it->second); } } // for (it } // make_cluster
signed char currentNodeVisited() { return visited(currentPosition[0],currentPosition[1]); }
bool AStarPathPlanner::plan(const QPoint &source, const QPoint &terminal, const GridMap &grid_map, const int rows, const int cols, QGraphicsScene *scene, PathI &path) { #if DEBUG qDebug() << rows << " row(s), " << cols << " col(s)"; qDebug() << source; qDebug() << terminal; for (int j = 0; j < cols; ++j) { for (int i = 0; i < rows; ++i) std::cout << (grid_map[i][j] ? 1 : 0) << " "; std::cout << std::endl; } #endif int xs = source.x(); int ys = source.y(); int xt = terminal.x(); int yt = terminal.y(); std::priority_queue<CostNode> cost_nodes; std::vector<std::vector<bool> > visited(rows, std::vector<bool>(cols, false)); CostNode ns(xs, ys, 0, distance(source, terminal)); ns.path.push_back(source); cost_nodes.push(ns); visited[ys][xs] = true; while (true) { const CostNode n_best = cost_nodes.top(); cost_nodes.pop(); int x = n_best.x; int y = n_best.y; if (x == xt && y == yt) { path = n_best.path; break; } // 1 2 3 // 8 4 // 7 6 5 static const double gs[] = {1.414, 1.000, 1.414, 1.000, 1.414, 1.000, 1.414, 1.000}; static const int dx[] = {-1, 0, 1, 1, 1, 0, -1, -1 }; static const int dy[] = {-1 -1, -1, 0, 1, 1, 1, 0 }; for (int i = 0; i < 8; ++i) { int x_new = x + dx[i]; int y_new = y + dy[i]; if ( x_new >= 0 && y_new >= 0 && x_new < cols && y_new < rows && !visited[y_new][x_new] && !grid_map[y_new][x_new]) { CostNode n_new(x_new, y_new, n_best.g + gs[i], distance(QPoint(x_new, y_new), terminal)); n_new.path = n_best.path; n_new.path.push_back(QPoint(x_new, y_new)); cost_nodes.push(n_new); visited[y_new][x_new] = true; } } } return true; }
bool cfgHasLoop(const IRUnit& unit) { boost::dynamic_bitset<> path(unit.numBlocks()); boost::dynamic_bitset<> visited(unit.numBlocks()); return loopVisit(unit.entry(), path, visited); }
void CPlanarSubClusteredGraph::call(const ClusterGraph &CGO, EdgeArray<bool>& inSub, //original edges in subgraph? List<edge>& leftOver, //original edges not in subgraph EdgeArray<double>& edgeWeight) //prefer lightweight edges { leftOver.clear(); //we compute a c-planar subclustered graph by calling //CPlanarSubClusteredST and then perform reinsertion on //a copy of the computed subclustered graph //initialize "call-global" info arrays //edge status const Graph& origG = CGO.constGraph(); m_edgeStatus.init(origG, 0); CPlanarSubClusteredST CPST; if (edgeWeight.valid()) CPST.call(CGO, inSub, edgeWeight); else CPST.call(CGO, inSub); //now construct the copy //we should create a clusterGraph copy function that //builds a clustergraph upon a subgraph of the //original graph, preliminarily use fullcopy and delete edges ClusterArray<cluster> clusterCopy(CGO); NodeArray<node> nodeCopy(origG); EdgeArray<edge> edgeCopy(origG); Graph testG; ClusterGraph CG(CGO, testG, clusterCopy, nodeCopy, edgeCopy); CconnectClusterPlanar CCCP; //------------------------------------- //perform reinsertion of leftover edges //fill list of uninserted edges EdgeArray<bool> visited(origG,false); //delete the non-ST edges edge e; forall_edges(e, origG) { if (!inSub[e]) { leftOver.pushBack(e); //original edges testG.delEdge(edgeCopy[e]); }//if }//foralledges //todo: cope with preferred edges //simple reinsertion strategy: just iterate over list and test ListIterator<edge> itE = leftOver.begin(); while (itE.valid()) { //testG=CG.getGraph() edge newCopy = testG.newEdge(nodeCopy[(*itE)->source()], nodeCopy[(*itE)->target()]); edgeCopy[*itE] = newCopy; bool cplanar = CCCP.call(CG); if (!cplanar) { testG.delEdge(newCopy); itE++; }//if else { ListIterator<edge> itDel = itE; itE++; leftOver.del(itDel); } }//while /* ListConstIterator<edge> it; for(it = preferedEdges.begin(); it.valid(); ++it) { edge eG = *it; visited[eG] = true; edge eH = testG.newEdge(toTestG[eG->source()],toTestG[eG->target()]); if (preferedImplyPlanar == false && isPlanar(H) == false) { testG.delEdge(eH); delEdges.pushBack(eG); } } */ }//call