void SquareMaze::bottomRemove(int x, int y, DisjointSets & maze,int & count,int rindex) { if (maze.find(rindex) != maze.find(rindex+maze_width)) { setWall(x, y, 1, false); maze.setunion(rindex, rindex+maze_width); count++; } }
void SquareMaze::rightRemove(int x, int y, DisjointSets & maze,int & count,int rindex) { if (maze.find(rindex) != (maze.find(rindex+1))) { setWall(x, y, 0, false); maze.setunion(rindex, rindex+1); count++; } }
/** * Finds a minimal spanning tree on a graph. * THIS FUNCTION IS GRADED. * * @param graph - the graph to find the MST of * * @todo Label the edges of a minimal spanning tree as "MST" * in the graph. They will appear blue when graph.savePNG() is called. * * @note Use your disjoint sets class from MP 7.1 to help you with * Kruskal's algorithm. Copy the files into the libdsets folder. * @note You may call std::sort (http://www.cplusplus.com/reference/algorithm/sort/) * instead of creating a priority queue. */ void GraphTools::findMST(Graph & graph) { vector<Edge> eds = graph.getEdges(); sort(eds.begin(), eds.end(),myfunction); DisjointSets vers; vector <Vertex> vertex_list = graph.getVertices(); vers.addelements(vertex_list.size()); for (int i = 0; i < eds.size(); i++) { Vertex u = eds[i].source; Vertex v = eds[i].dest; if (vers.find(u) != vers.find(v)) { vers.setunion(u,v); graph.setEdgeLabel(u,v,"MST"); } } }
/** * Finds a minimal spanning tree on a graph. * THIS FUNCTION IS GRADED. * * @param graph - the graph to find the MST of * * @todo Label the edges of a minimal spanning tree as "MST" * in the graph. They will appear blue when graph.savePNG() is called. * * @note Use your disjoint sets class from MP 7.1 to help you with * Kruskal's algorithm. Copy the files into the libdsets folder. * @note You may call std::sort (http://www.cplusplus.com/reference/algorithm/sort/) * instead of creating a priority queue. */ void GraphTools::findMST(Graph & graph) { vector<Edge> theEdges = graph.getEdges(); std::sort(theEdges.begin(), theEdges.end()); DisjointSets theVertexSet; vector<Vertex> theVertices = graph.getVertices(); theVertexSet.addelements(theVertices.size()); int size = theVertices.size(); int count = 0; vector<Edge>::iterator iter; for(iter = theEdges.begin(); iter != theEdges.end(); iter++) { if(count == size - 1) break; if(theVertexSet.find(iter->source) != theVertexSet.find(iter->dest)) { theVertexSet.setunion(iter->source, iter->dest); graph.setEdgeLabel(iter->source, iter->dest, "MST"); count++; } } }
void SquareMaze::makeMaze(int width, int height) { right.clear(); bottom.clear(); maze_width = width; maze_height = height; blocks = maze_width * maze_height; right.resize(blocks,true); bottom.resize(blocks,true); DisjointSets maze; maze.addelements(blocks); srand(time(NULL)); //int x, y; bool rightmost=true, bottommost=true; int count = 0; //int rindex; while (count< (blocks - 1)) { int rindex = rand() % blocks; int x = rindex%maze_width; int y = rindex/maze_width; if(x==(maze_width-1)) rightmost=true; else rightmost=false; if(y==(maze_height-1)) bottommost=true; else bottommost=false; if (( rightmost == true ) && ( bottommost == true )) { rightmost=rightmost; } else if (!rightmost && !bottommost) { int action=rand()%3; if (action == 0) rightRemove(x,y, maze,count,rindex); else if (action == 1) bottomRemove(x,y, maze,count,rindex); else { if ((maze.find(rindex) != maze.find(rindex+1)) && (maze.find(rindex) != maze.find(rindex+maze_width))&& (maze.find(rindex+1) != maze.find(rindex+1))) { setWall(x, y, 0, false); setWall(x, y, 1, false); maze.setunion(rindex, rindex+1); maze.setunion(rindex, rindex+maze_width); count+=2; } } } else if(bottommost) { int action=rand()%2; if (action== 1)rightRemove(x,y, maze,count,rindex); } else { int action =rand()%2; if (action == 1)bottomRemove(x,y, maze,count,rindex); } } }
void SquareMaze::makeMaze(int width,int height) { width1=width; height1=height; int size=width*height; right.clear(); down.clear();//clearing right and down walls just in case right=vector<bool>(size, true);//set all walls so they are there we will remove later down=vector<bool>(size, true); vector<int> blocks(size);//vector for indicies // map<int, int> maps; for(int i=0;i<size; i++) { blocks.push_back(i);//pushing back the indidces for the maze // for(int j=0; j<height1; j++) // { // // maps.insert(make_pair(i,j)); // } } DisjointSets set; set.addelements(size);//used to stop cycles from being created srand(time(0)); // std::random_shuffle(maps.begin(), maps.end()); std::random_shuffle(blocks.begin(), blocks.end());//randomly shuffles indicies so it doesnt create the same maze // map<int, int>::iterator it; vector<int> :: iterator it; for(it=blocks.begin(); it!=blocks.end(); it++) { int x=*it%width;//x and y coords for the index int y=*it/width; int index=*it; //actual index if(x!=width1-1 ) //cant go any farther to the right in this case so dont want to do it { int index1=index+1; if(set.find(index)!=set.find(index1)) //checking if the one to the right of the index is in the same set { setWall(x,y,0,false);//if they are not in the same set we can remove the wall set.setunion(index, index1); //we connect them so they are in the same set //works because if we try to remove something in the same set it will create a cycle } } if(y!=height1-1) { int index2=index+width1; if(set.find(index)!= set.find(index2)) { setWall(x,y,1,false); //do the same for if we want to go down set.setunion(index, index2); } } } }
//compute bag affiliation for all vertices //store result in m_bagindex void ClusterAnalysis::computeBags() { const Graph &G = m_C->constGraph(); // Storage structure for results m_bagindex.init(G); // We use Union-Find for chunks and bags DisjointSets<> uf; NodeArray<int> setid(G); // Index mapping for union-find #if 0 node* nn = new node[G.numberOfNodes()]; // dito #endif // Every cluster gets its index ClusterArray<int> cind(*m_C); // We store the lists of cluster vertices List<node>* clists = new List<node>[m_C->numberOfClusters()]; int i = 0; // Store index and detect the current leaf clusters List<cluster> ccleafs; ClusterArray<int> unprocessedChildren(*m_C); //processing below: compute bags for(cluster c : m_C->clusters) { cind[c] = i++; if (c->cCount() == 0) ccleafs.pushBack(c); unprocessedChildren[c] = c->cCount(); } // Now we run through all vertices, storing them in the parent lists, // at the same time, we initialize m_bagindex for(node v : G.nodes) { // setid is constant in the following setid[v] = uf.makeSet(); // Each vertex v gets its own ClusterArray that stores v's bag index per cluster. // See comment on use of ClusterArrays above m_bagindex[v] = new ClusterArray<int>(*m_C,DefaultIndex, m_C->maxClusterIndex()+1);//m_C->numberOfClusters()); cluster c = m_C->clusterOf(v); // Push vertices in parent list clists[cind[c]].pushBack(v); } // Now each clist contains the direct vertex descendants // We process the clusters bottom-up, compute the chunks // of the leafs first. At each level, for a cluster the // vertex lists of all children are concatenated // (could improve this by having an array of size(#leafs) // and concatenating only at child1), then the bags are // updated as follows: chunks may be linked by exactly // the edges with lca(c) ie the ones in m_lcaEdges[c], // and bags may be built by direct child clusters that join chunks. // While concatenating the vertex lists, we can check // for the vertices in each child if the uf number is the same // as the one of a first initial vertex, otherwise we join. // First, lowest level clusters are processed: All chunks are bags OGDF_ASSERT(!ccleafs.empty()); while (!ccleafs.empty()){ const cluster c = ccleafs.popFrontRet(); Skiplist<int*> cbags; //Stores bag indexes ocurring in c auto storeResult = [&] { for (node v : clists[cind[c]]) { int theid = uf.find(setid[v]); (*m_bagindex[v])[c] = theid; if (!cbags.isElement(&theid)) { cbags.add(new int(theid)); } // push into list of outer active vertices if (m_storeoalists && isOuterActive(v, c)) { (*m_oalists)[c].pushBack(v); } } (*m_bags)[c] = cbags.size(); // store number of bags of c }; if (m_storeoalists){ //no outeractive vertices detected so far (*m_oalists)[c].clear(); } //process leafs separately if (c->cCount() == 0) { //Todo could use lcaEdges list here too, see below for (node u : c->nodes) { for(adjEntry adj : u->adjEntries) { node w = adj->twinNode(); if (m_C->clusterOf(w) == c) { uf.link(uf.find(setid[u]),uf.find(setid[w])); } } } // Now all chunks in the leaf cluster are computed // update for parent is done in the else case storeResult(); } else { // ?We construct the vertex list by concatenating // ?the lists of the children to the current list. // We need the lists for storing the results efficiently. // (Should be slightly faster than to call clusterNodes each time) // Bags are either links of chunks by edges with lca==c // or links of chunk by child clusters. // Edge links for(edge e : (*m_lcaEdges)[c]) { uf.link(uf.find(setid[e->source()]),uf.find(setid[e->target()])); } // Cluster links for(cluster cc : c->children) { //Initial id per child cluster cc: Use value of first //vertex, each time we encounter a different value in cc, //we link the chunks //add (*itcc)'s vertices to c's list ListConstIterator<node> itvc = clists[cind[cc]].begin(); int inid; if (itvc.valid()) inid = uf.find(setid[*itvc]); while (itvc.valid()) { int theid = uf.find(setid[*itvc]); if (theid != inid) uf.link(inid,theid); clists[cind[c]].pushBack(*itvc); ++itvc; } } storeResult(); } // Now we update the status of the parent cluster and, // in case all its children are processed, add it to // the process queue. if (c != m_C->rootCluster()) { OGDF_ASSERT(unprocessedChildren[c->parent()] > 0); unprocessedChildren[c->parent()]--; if (unprocessedChildren[c->parent()] == 0) ccleafs.pushBack(c->parent()); } } // clean up delete[] clists; }