예제 #1
0
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++;
		}

}
예제 #2
0
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++;
		}


}
예제 #3
0
/**
 * 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");
        }
    }
}
예제 #4
0
/**
 * 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++;
        }
    }
}
예제 #5
0
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);
		}

	}

}
예제 #6
0
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);
			}
		}

	}
	




}
예제 #7
0
//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;
}