int main() { try { ifstream fin; // Read the maze from the file. string fileName = "maze0.txt"; fin.open(fileName.c_str()); if (!fin) { cerr << "Cannot open " << fileName << endl; exit(1); } maze m(fin); fin.close(); m.print(m.numRows()-1,m.numCols()-1,0,0); Graph g(m.numRows() * m.numCols()); // initializes the graph as the size of the maze m.mapMazeToGraph(g); // graph g is created from the maze Graph::vertex_descriptor startOfMaze = vertex(0, g); // beginning vertex of the maze pair<int, int> endOfMaze(m.numRows() - 1, m.numCols() - 1); // initializes the end of the maze int totalVertices = num_vertices(g); // gets total # of vertices stack<Graph::vertex_descriptor> testPath; // create path that can be used to for print path clearVisited(g); // clears visited vertices testPath = findPathDFSRecursively(g, startOfMaze, endOfMaze); // gets a path to complete the maze m.printPath(totalVertices, testPath, g); // prints path using DFS system("cls"); clearVisited(g); testPath = findShortestPathDFSRecursively(g, startOfMaze, endOfMaze); // gets the shortest path to complete the maze m.printPath(totalVertices, testPath, g); // prints shortest path using DFS system("cls"); clearVisited(g); testPath = findPathDFSStack(g,startOfMaze,endOfMaze); // gets path using DFS stack logic m.printPath(totalVertices, testPath, g); // prints path using DFS with a stack system("cls"); clearVisited(g); testPath = findPathBFS(g, startOfMaze, endOfMaze); // BFS finds shortest path from start to every node m.printPath(totalVertices, testPath, g); // prints shortest path using BFS // cout << g << endl; may be used in later implementations but unnecessary for this project } catch (indexRangeError &ex) { cout << ex.what() << endl; exit(1); } }
/* This function should return a boolean (encoded as an int) indicating * whether or not a path exists between the argument vertices. * param: g Graph to perform the search in * param: source Vertex to originate the search from * param: destination Vertex to stop the search from (if it is found) * ret: boolean indicating whether or not a path exists */ int BFS(Graph* g, Vertex* source, Vertex* destination) { /* FIXME you will write this */ struct cirListDeque *que = malloc(sizeof(struct cirListDeque)); struct Vertex *cur = malloc(sizeof(struct Vertex)); clearVisited(g); initCirListDeque(que); addFrontCirListDeque(que, source); while(!isEmptyCirListDeque(que)){ cur = frontCirListDeque(que); removeFrontCirListDeque(que); if(cur == destination){ return 1; } else if(!cur->isVisited){ int i; for(i=0; i<cur->numNeighbors; ++i){ if(!cur->neighbors[i]->isVisited){ addBackCirListDeque(que, cur->neighbors[i]); cur->neighbors[i]->isVisited = 1; } } cur->isVisited =1; } } return 0; }
string Maze::dispayMaze() { string mazeDsp = ""; string* maze = new string[height*3]; for (int y = 0; y < height*3;y++) { maze[y] = ""; // populate the string for (int x = 0; x < width * 3;x++) maze[y] += "#"; maze[y] += "\n"; } clearVisited(root); buildCell(*root, maze); // append the lines into one string for (int y = 0; y < height * 3; y++) mazeDsp += maze[y]; delete[] maze; maze = 0; return mazeDsp; }
unsigned int sum(unsigned int lowerBound, unsigned int upperBound, int row, int col){ clearVisited(); return recursiveSum(lowerBound, upperBound, row, col); }
/** * Determines if there is a path from the source to the destination using an * iterative breadth-first search starting at the source. * * Remember to call clearVisited() before starting the search. * * @param graph * @param source * @param destination * @return 1 if there is a path, 0 otherwise. */ int bfsIterative(Graph* graph, Vertex* source, Vertex* destination) { clearVisited(graph); int i; int found = 0; // queue Deque *collection = malloc(sizeof(Deque)); Vertex *current; // initialize queue and add source collection = dequeNew(); dequePushBack(collection, source); // search until destination is found or we run out of edges while (!(found == 1) && !dequeIsEmpty(collection)) { // current vertex is the one first added to collection current = dequeFront(collection); dequePopFront(collection); current->isVisited = 1; // if the current node is the destination, we're done if (current == destination) found = 1; // otherwise add its neighbors to the queue else { for (i = 0; i < current->numNeighbors; ++i) if (!(current->neighbors[i]->isVisited)) dequePushBack(collection, current->neighbors[i]); } } // clean things up clearVisited(graph); dequeClear(collection); free(collection); // return if path was found return found; }
/* * Method used to test a maze to make sure all cells * are reachable. * */ bool Maze::allCellsReachable() { int r, c; int rows = getRows(); int cols = getCols(); // Set all cells to a unique value (starting with 1) and unvisit them clearVisited(); for (r=0; r<rows; r++) { for (c=0; c<cols; c++) { getCell(r,c)->setValue(r*cols+c+1); } } // Now keep reducing connected cells to lowest value. // If all are connected, then all cells should end up as 1. bool changed = true, modify = false; vector<direction> lst; int min, v = 0, i; while (changed) { changed = false; for (r=0; r<rows; r++) { for (c=0; c<cols; c++) { modify = false; Cell* cell = getCell(r,c); getConnectedNeighbors(cell, lst); // Get minimum value for connected cells min = v = cell->getValue(); for (i=0; i<(int)lst.size(); i++) { v = getAdjacentCell(cell, lst.at(i))->getValue(); if (v < min) { modify = true; min = v; } } // Change values in connected cells if needed if (modify) { changed = true; cell->setValue(min); for (i=0; i<(int)lst.size(); i++) { getAdjacentCell(cell, lst.at(i))->setValue(min); } } } } } // Now find out if all cells have value 1 (all connected) for (r=0; r<rows; r++) { for (c=0; c<cols; c++) { if (getCell(r,c)->getValue() != 1) return false; } } return true; }
/* This function should return a boolean (encoded as an int) indicating * whether or not a path exists between the argument vertices. * param: g Graph to perform the search in * param: source Vertex to originate the search from * param: destination Vertex to stop the search from (if it is found) * ret: boolean indicating whether or not a path exists */ int BFS(Graph* g, Vertex* source, Vertex* destination) { /* FIXME you will write this */ //use queue int contains = 0; struct cirListDeque *queue = malloc(sizeof(struct cirListDeque)); initCirListDeque(queue); clearVisited(g); struct Vertex *current; current = source; while(current != destination) { if(current->isVisited == 0) { current->isVisited = 1; for(int x = 0; x < current->numNeighbors; x++) { if(current->neighbors[x]->isVisited == 0) { addBackCirListDeque(queue, current->neighbors[x]); } } if(!isEmptyCirListDeque(queue)) { current = frontCirListDeque(queue); removeFrontCirListDeque(queue); } else return contains; } else { if(!isEmptyCirListDeque(queue)) { current = frontCirListDeque(queue); removeFrontCirListDeque(queue); } else return contains; } } if(current == destination) {contains = 1;} removeAllCirListDeque(queue); return contains; }
void Maze::clearVisited(MazeNode * node) { if (node == 0) return; // clear the current node node->clearVisited(); // traverse all visited node for (int index = 0; index < node->getNumOfConnections(); index++) { if (node->getNode(index) != 0 && node->getNode(index)->isVisited()) clearVisited(node->getNode(index)); } }
// FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc. // can vary based on the value of the input arguments. If so, we should restrict those as well. void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& graph) { mNumErrors = 0; // FIXME(mvujovic): The dependency graph does not support user defined function calls right now, // so we generate errors for them. validateUserDefinedFunctionCallUsage(graph); // Starting from each sampler, traverse the dependency graph and generate an error each time we // hit a node where sampler dependent values are not allowed. for (auto samplerSymbol : graph.samplerSymbols()) { clearVisited(); samplerSymbol->traverse(this); } }
unsigned int count(unsigned int lowerBound, unsigned int upperBound){ clearVisited(); int sum = 0, _count = 0; for (int rows = 0 ; rows <= _rows; rows++){ for(int cols = 0; cols <= _cols; cols++){ sum = recursiveSum(lowerBound, upperBound, rows, cols); if (sum > 0) _count++; } } return _count; }
/* This function should return a boolean (encoded as an int) indicating * whether or not a path exists between the argument vertices. * param: g Graph to perform the search in * param: source Vertex to originate the search from * param: destination Vertex to stop the search from (if it is found) * ret: boolean indicating whether or not a path exists */ int BFS(Graph* g, Vertex* source, Vertex* destination){ /* FIXME you will write this */ /* create and initialize circular list deque pointer */ struct cirListDeque *stack = malloc(sizeof(struct cirListDeque)); initCirListDeque(stack); /*/ create vertex pointer and clear visited nodes */ struct Vertex *temp = source; clearVisited(g); /* add to front */ addFrontCirListDeque(stack, temp); /* if not empty, use BFS */ while(!isEmptyCirListDeque(stack)){ /*remove back(top) value */ temp = backCirListDeque(stack); removeBackCirListDeque(stack); /* check if visited, mark, and return true */ if(!temp -> isVisited){ temp -> isVisited = 1; } if(temp == destination){ removeAllCirListDeque(stack); return 1; } /* check is the neighboring nodes have been visited. add to stack if not */ for(int i = 0; i < temp->numNeighbors; i++){ if(!temp->neighbors[i]->isVisited){ addFrontCirListDeque(stack, temp->neighbors[i]); } } } return 0; }
/* This function should return a boolean (encoded as an int) indicating * whether or not a path exists between the argument vertices. * param: g Graph to perform the search in * param: source Vertex to originate the search from * param: destination Vertex to stop the search from (if it is found) * ret: boolean indicating whether or not a path exists */ int DFS(Graph* g, Vertex* source, Vertex* destination){ /* FIXME you will write this */ struct cirListDeque *stack = malloc(sizeof(struct cirListDeque)); initCirListDeque(stack); struct Vertex *temp = source; clearVisited(g); /* add to the front of the circular list deque */ addFrontCirListDeque(stack, temp); /*if it isn't empty, use DFS */ while(!isEmptyCirListDeque(stack)){ temp = backCirListDeque(stack); removeBackCirListDeque(stack); /* check if visited, mark if it hasn't been visited */ if(!temp -> isVisited){ temp ->isVisited = 1; } if(temp == destination){ /* if you reach the destination, remove from the list to free memory, return 1 */ removeAllCirListDeque(stack); return 1; } /* check is the neighboring nodes have been visited. add to stack if not */ for(int i = 0; i < temp->numNeighbors; i++){ if(!temp->neighbors[i] -> isVisited){ addFrontCirListDeque(stack, temp->neighbors[i]); } } } return 0; }
/* This function should return a boolean (encoded as an int) indicating * whether or not a path exists between the argument vertices. * param: g Graph to perform the search in * param: source Vertex to originate the search from * param: destination Vertex to stop the search from (if it is found) * ret: boolean indicating whether or not a path exists */ int BFS(Graph* g, Vertex* source, Vertex* destination) { /* FIXME you will write this */ clearVisited(g); cirListDeque queue; Vertex *currentVertex; int i; initCirListDeque(&queue); addBackCirListDeque(&queue, source); while(!isEmptyCirListDeque(&queue)) { currentVertex = frontCirListDeque(&queue); removeFrontCirListDeque(&queue); if(currentVertex->label == destination->label) return 1; else { if(currentVertex->isVisited == 0) currentVertex->isVisited = 1; for (i = 0; i < currentVertex->numNeighbors; i++) { if(currentVertex->label == destination->label) return 1; else { if(currentVertex->neighbors[i]->isVisited == 0) addBackCirListDeque(&queue, currentVertex->neighbors[i]); } } } } return 0; }
/* This function should return a boolean (encoded as an int) indicating * whether or not a path exists between the argument vertices. * param: g Graph to perform the search in * param: source Vertex to originate the search from * param: destination Vertex to stop the search from (if it is found) * ret: boolean indicating whether or not a path exists */ int BFS(Graph* g, Vertex* source, Vertex* destination) { /* DONE you will write this */ /* use a queue */ clearVisited(g); cirListDeque *queue = malloc(sizeof(cirListDeque)); initCirListDeque(queue); Vertex *current = source; int i; for (i = 0; i < current->numNeighbors; i++) { addFrontCirListDeque(queue, current->neighbors[i]); } current->isVisited = 1; while (! isEmptyCirListDeque(queue)) { current = backCirListDeque(queue); removeBackCirListDeque(queue); if (current == destination) { return 1; } current->isVisited = 1; for (i = 0; i < current->numNeighbors; i++) { if (! current->neighbors[i]->isVisited) { addFrontCirListDeque(queue, current->neighbors[i]); } } } return 0; }
int DFSRecursive(Graph* g, Vertex* source, Vertex* destination) { clearVisited(g); return DFSRecursiveHelper(g, source, destination); }
/** * Determines if there is a path from the source to the destination using a * recursive depth-first search starting at the source. * * You can use this function to test the correctness of the others. * * @param graph * @param source * @param destination * @return 1 if there is a path, 0 otherwise. */ int dfsRecursive(Graph* graph, Vertex* source, Vertex* destination) { clearVisited(graph); return DfsRecursiveHelper(graph, source, destination); }
/* This function should return a boolean (encoded as an int) indicating * whether or not a path exists between the argument vertices. * param: g Graph to perform the search in * param: source Vertex to originate the search from * param: destination Vertex to stop the search from (if it is found) * ret: boolean indicating whether or not a path exists */ int DFS(Graph* g, Vertex* source, Vertex* destination) { /* FIXME you will write this */ /* DFSRecursive (g, source, destination) */ assert( g != NULL ); assert( source != NULL ); assert( destination != NULL ); clearVisited(g); /* printf("Searching for %c from %c\n",destination->label,source->label); */ cirListDeque stack; /* a stack can be a special instance of deque */ /* can't use a pointer for 'stack' because there's nothing for it to point at */ Vertex* current; int i; /* C99 isn't included on this assignment for some reason */ initCirListDeque(&stack); addBackCirListDeque(&stack,source); /* push vertex source to top of stack */ /* printf("pushed %c\n",source->label); */ while( !isEmptyCirListDeque(&stack) ) /* loop until &stack is empty */ { /* printf("(SOL) current stack: "); */ /* printCirListDeque(&stack); */ /* printf("\n"); */ current = backCirListDeque(&stack); /* pop vertex from &stack */ removeBackCirListDeque(&stack); /* printf("removed %c\n", current->label); */ /* printf("current->label = %c\n",current->label); */ if ( current->label == destination->label ) { /* printf("found %c\n",destination->label); */ return 1; } else { if ( current->isVisited == 0 ) /* mark as visited if not already */ { current->isVisited = 1; /* printf("marked %c as visited\n",current->label); */ } else { /* printf("Skipping %c because it visited already.\n",current->label); */ } /* printf("checking %d neighbors\n",current->numNeighbors); */ for ( i = 0; i < current->numNeighbors; i++ ) /* push neighbors if necessary */ { if ( current->label == destination->label ) { /* printf("found %c\n",destination->label); */ return 1; } else { if ( current->neighbors[i]->isVisited == 0 ) { addBackCirListDeque( &stack,current->neighbors[i] ); /* printf("pushed %c\n",current->neighbors[i]->label); */ } /* else */ /* printf("Skipping %c because it visited already.\n",current->neighbors[i]->label); */ } } } } return 0; }
Maze::~Maze() { clearVisited(root); destroyMaze(root); }