private void testListIterator(List <DSInteger> the_list) { ListIterator <DSInteger> it = the_list.listIterator(); int count = 0; while (it.hasNext()) { count++; it.next(); } //you are at the last item, not one before the first item when the //initial loop begins count--; while (it.hasPrevious()) { count--; it.previous(); } Assert.AreEqual(0, count); //test values returned it = the_list.listIterator(); Assert.AreEqual(30, it.next().value); Assert.AreEqual(60, it.next().value); //test removal DSInteger removed = it.remove(); Assert.AreEqual(60, removed.value); Assert.AreEqual(90, it.next().value); it.next(); //120 it.next(); //150 //test removing the last item Assert.AreEqual(false, it.hasNext()); Assert.AreEqual(150, it.remove().value); Assert.AreEqual(false, it.hasNext()); Assert.AreEqual(90, it.previous().value); Assert.AreEqual(true, it.hasNext()); Assert.AreEqual(120, it.next().value); //test removing the first item the_list.clear(); addInitialItems(the_list); it = the_list.listIterator(); Assert.AreEqual(false, it.hasPrevious()); Assert.AreEqual(30, it.next().value); it.remove(); Assert.AreEqual(false, it.hasPrevious()); Assert.AreEqual(60, it.next().value); Assert.AreEqual(90, it.next().value); Assert.AreEqual(60, it.previous().value); Assert.AreEqual(false, it.hasPrevious()); }
//inform the user that they reaced the finish of the maze. private void userReachsFinish(DSInteger the_check) { //this checks for the last cell's index in the maze if (the_check.value == my_rows * my_cols - 1) { MessageBox.Show("Congratulations on reaching the finish node. See if you can " + "reach the finish node faster than the shortest path algorithm used."); } }
/// <summary> /// Sets up the drawn vertex with a location and label. /// </summary> /// <param name="the_x">x coordinate of the vertex location.</param> /// <param name="the_y">y coordinate of the vertex location.</param> /// <param name="the_label">the label of the vertex.</param> public DrawnVertex(float the_x, float the_y, DSInteger the_label) { Preconditions.checkNull(the_label); //heading can begin as null x = the_x; y = the_y; label = the_label; draw_heading = false; }
//get an array where every value is the same integer. private DSInteger[] getSingleIntegerList() { DSInteger[] return_value = new DSInteger[NUMBER_OF_ELEMENTS]; for (int i = 0; i < NUMBER_OF_ELEMENTS; i++) { //all elements are the integer zero return_value[i] = new DSInteger(0); } return(return_value); }
//draws a list of user/algorithm moves through the maze. private void drawList(List <DSInteger> the_list, Color the_color, Graphics the_g) { //loop through the path to the correct solution and draw the path Iterator <DSInteger> it = the_list.iterator(); while (it.hasNext()) { DSInteger next = it.next(); drawHighlight(next, the_color, the_g); } }
//builds the vertex drawn elements after generating the graph. private void generateVisual() { //add vertices for (int i = 0; i < hscrVertices.Value; i++) { DSInteger vertex = new DSInteger(i); float x = my_rand.Next(VERTEX_SIZE, pnlDraw.Width - OUTER_EDGE); float y = my_rand.Next(VERTEX_SIZE, pnlDraw.Height - OUTER_EDGE); my_drawables.put(vertex, new DrawnVertex(x, y, vertex)); } }
private void testEnqueue(BasicQueue <DSInteger> the_queue) { //make sure the last element removed is the last one added DSInteger next = null, last = null; while ((next = the_queue.dequeue()) != null) { last = next; } Assert.AreEqual(400, last.value); }
/// <summary> /// Puts the first n integers into an array and then returns a random permutation of them. /// </summary> /// <typeparam name="T">the reference type of elements in the returned array.</typeparam> /// <param name="the_max_number">the number of integer n.</param> /// <returns>a random permutation of the first n integers.</returns> public static DSInteger[] randomPermutation <T>(int the_max_number) { //add the first n integers to and array. DSInteger[] return_value = new DSInteger[the_max_number]; for (int i = 0; i < return_value.Length; i++) { return_value[i] = new DSInteger(i); } //get a random permutation and return shuffleArray <DSInteger>(ref return_value); return(return_value); }
private void testGet(Map <DSString, DSInteger> the_map) { //check some entries for valid return values DSInteger check = the_map.get(new DSString("Bobby")); Assert.AreEqual(20, check.value); check = the_map.get(new DSString("Foran")); Assert.AreEqual(52, check.value); //check for something that is not in the map check = the_map.get(new DSString("Susan")); Assert.AreEqual(null, check); }
//checks whether a list of simple edges contains a second label. private bool checkContains(List <SimpleEdge <DSInteger> > the_adjacent, DSInteger the_check) { Iterator <SimpleEdge <DSInteger> > it = the_adjacent.iterator(); while (it.hasNext()) { if (it.next().second_label.Equals(the_check)) { return(true); } } return(false); }
//draws a single move in the maze. private void drawHighlight(DSInteger the_element, Color the_color, Graphics the_g) { //get the x, y coordinates float x, y; getXY(the_element.value, out x, out y); //draw the highlight the_g.FillRectangle(new SolidBrush(the_color), MAZE_OFFSET + x * my_cell_width + my_single_w_cell_spacer, MAZE_OFFSET + y * my_cell_height + my_single_h_cell_spacer, my_cell_width - my_double_w_cell_spacer, my_cell_height - my_double_h_cell_spacer); }
//removes the highlighting from a single cell (for user back-tracking). private void removeCellHighlight(DSInteger the_removal, Graphics the_g) { float x, y; getXY(the_removal.value, out x, out y); //draw over the removed highlight the_g.DrawImage(my_clip, MAZE_OFFSET + x * my_cell_width + my_single_w_cell_spacer, MAZE_OFFSET + y * my_cell_height + my_single_h_cell_spacer, new RectangleF(MAZE_OFFSET + x * my_cell_width + my_single_w_cell_spacer, MAZE_OFFSET + y * my_cell_height + my_single_h_cell_spacer, my_cell_width - my_double_w_cell_spacer, my_cell_height - my_double_h_cell_spacer), GraphicsUnit.Pixel); }
//gives a permutation of the first n integers in array form. private DSInteger[] getPermutation() { //create a permutation of the first n integers DSInteger[] return_value = new DSInteger[NUMBER_OF_ELEMENTS]; for (int i = 0; i < NUMBER_OF_ELEMENTS; i++) { return_value[i] = new DSInteger(i); } //randomize them Randomization.shuffleArray <DSInteger>(ref return_value); return(return_value); }
//gets an array of integers within a small range of values. private DSInteger[] getRandomIntegersSmall() { //get an array of random integers DSInteger[] return_value = new DSInteger[NUMBER_OF_ELEMENTS]; for (int i = 0; i < NUMBER_OF_ELEMENTS; i++) { return_value[i] = new DSInteger(my_rand.Next(0, SMALL_MAX)); } //randomize them Randomization.shuffleArray <DSInteger>(ref return_value); return(return_value); }
private void testAdd(List <DSInteger> the_list) { //assert they are in the correct order DSInteger added = the_list.get(0); Assert.AreEqual(30, added.value); added = the_list.get(1); Assert.AreEqual(60, added.value); added = the_list.get(2); Assert.AreEqual(90, added.value); //assert they are all in the list Assert.AreEqual(5, the_list.size()); }
//gives a permutation of the first n integers in array form. private DSInteger[] getInputArray(int the_max_value) { //create a permutation of the first n integers DSInteger[] return_value = new DSInteger[the_max_value]; for (int i = 0; i < the_max_value; i++) { return_value[i] = new DSInteger(i); } //randomize them Randomization.shuffleArray <DSInteger>(ref return_value); return(return_value); }
//creates an array that is a sorted permutation of the first n integers (in ascending order). private DSInteger[] getSortedIntegersASC() { //create a permutation of the first n integers DSInteger[] return_value = new DSInteger[NUMBER_OF_ELEMENTS]; for (int i = 0; i < NUMBER_OF_ELEMENTS; i++) { return_value[i] = new DSInteger(i); } //sort them Sorting <DSInteger> .Sort(Sorts.QuickSort, ref return_value); return(return_value); }
//updates all vertex headings after the shortest path algorithms are run. private void updateAfterShortestPath() { //go through each vertex DirectedGraph <DSInteger> graph = getCurrentGraph(); Iterator <DrawnVertex> it = my_drawables.values().iterator(); while (it.hasNext()) { DrawnVertex dv = it.next(); dv.draw_heading = true; //make them show their headings bool found = false; double total_edge_cost = 0.0; //make sure the source vertex is found if (dv.label.Equals(my_last_highlighted)) { found = true; } //get the shortest path Iterator <DSInteger> it_vertices = graph.getShortestPath(dv.label).iterator(); if (it_vertices.hasNext()) { //add up the shortest path DSInteger last = it_vertices.next(); while (it_vertices.hasNext()) { found = true; DSInteger next = it_vertices.next(); total_edge_cost += graph.getEdgeCost(last, next); last = next; } } //check for no shortest path if (!found) { dv.heading = "Inf"; } else { dv.heading = total_edge_cost.ToString(); } } //redraw the visual pnlDraw.Refresh(); }
//creates an array that is a sorted permutation of the first n integers (in descending order). private DSInteger[] getSortedIntegersDEC() { //create a permutation of the first n integers DSInteger[] return_value = new DSInteger[NUMBER_OF_ELEMENTS]; for (int i = 0; i < NUMBER_OF_ELEMENTS; i++) { return_value[i] = new DSInteger(i); } //sort them and then reverse them (descending order) Sorting <DSInteger> .Sort(Sorts.QuickSort, ref return_value); Arrays.reverse <DSInteger>(return_value); return(return_value); }
/// <summary> /// Sets up the disjoint sets with an initial array of set /// elements. /// </summary> /// <param name="the_values">array of set elements.</param> public DisjointSets(T[] the_values) { setupDS(the_values.Length); my_set_size = the_values.Length; //add all elements to the structure for (int i = 0; i < the_values.Length; i++) { DSInteger index = new DSInteger(i); T value = the_values[i]; my_index_map.put(value, index); //map to index my_value_map.put(index, value); //map to value } my_sets = new int[the_values.Length]; Helpers.initializeArray <int>(my_sets, -1); }
private void testIterator(List <DSInteger> the_list) { Iterator <DSInteger> it = the_list.iterator(); int count = 0; while (it.hasNext()) { count++; it.next(); } Assert.AreEqual(5, count); //test removal at the end of the list DSInteger removed = it.remove(); Assert.AreEqual(150, removed.value); Assert.AreEqual(false, it.hasNext()); //test removal of two items at once try { it.remove(); Assert.Fail(); //should throw an error before here } catch (IllegalStateException the_ex) { //good } //test values returned it = the_list.iterator(); Assert.AreEqual(30, it.next().value); Assert.AreEqual(60, it.next().value); //test removal at a middle index removed = it.remove(); Assert.AreEqual(60, removed.value); Assert.AreEqual(90, it.next().value); it = the_list.iterator(); it.next(); Assert.AreEqual(30, it.remove().value); Assert.AreEqual(true, it.hasNext()); Assert.AreEqual(90, it.next().value); }
//cleanup after generating the graph. private void cleanupGeneration() { //update graph information for the user updateGraphInformation(); //visual generateVisual(); //select the first vertex in the graph my_last_highlighted = new DSInteger(0); hscrChosenVertex.Value = 1; hscrChosenVertex_ValueChanged(hscrChosenVertex, new EventArgs()); //make sure the right range of vertice indexes is selectable hscrChosenVertex.Maximum = hscrVertices.Value; //mark as done my_generated = true; //show the new graph pnlDraw.Refresh(); }
//handles the value change for which vertex the user wants to use as source vertex for shortest //path problems. private void hscrChosenVertex_ValueChanged(object sender, EventArgs e) { int index = hscrChosenVertex.Value - 1; lblVertex.Text = index.ToString(); if (my_last_highlighted != null) { //if some drawing objects are ready if (my_drawables != null) { my_drawables.get(my_last_highlighted).draw(pnlDraw.CreateGraphics()); } } my_last_highlighted = new DSInteger(index); //if some drawing objects are ready if (my_drawables != null) { my_drawables.get(my_last_highlighted).highlight(pnlDraw.CreateGraphics()); } }
//draws the trail of user moves in the maze. private void drawUserSolution(bool the_full_redraw, DSInteger the_removed) { //draw solution if there if (my_user_solution_path != null) { if (the_full_redraw) { drawList(my_user_solution_path, Color.Green, pnlDraw.CreateGraphics()); } else { //only draw the new move if (the_removed == null) { drawHighlight(my_user_solution_path.last(), Color.Green, pnlDraw.CreateGraphics()); } else //remove that retraced move { removeCellHighlight(the_removed, pnlDraw.CreateGraphics()); } } } }
//adds random edges to the graph. private void addEdges(DirectedGraph <DSInteger> the_graph) { //add random edges //percentage multiplied by LOAD_FACTOR multiplied by the number of vertices double percent = (hscrEdgeDensity.Value / ONE_HUNDRED_PERCENT); int max_edges = (int)(percent * (the_graph.vertexSize() * (the_graph.vertexSize() - 1) / 2)); int connected_edges = the_graph.vertexSize() / 2 + the_graph.vertexSize() % 2; //show user the progress pbrProgress.Maximum = max_edges; pbrProgress.Value = 0; //set Set <DSInteger> not_added = new HashSet <DSInteger>(the_graph.vertexSize()); Set <DSInteger> added = new HashSet <DSInteger>(the_graph.vertexSize()); Iterator <DSInteger> it = the_graph.getVertices().iterator(); while (it.hasNext()) { not_added.add(it.next()); } //loop until you have added all edges while (the_graph.edgeSize() < max_edges) { DSInteger first_vertex = new DSInteger(my_rand.Next(0, hscrVertices.Value)); DSInteger second_vertex = new DSInteger(my_rand.Next(0, hscrVertices.Value)); //check if the edge added is not a loop if (!first_vertex.Equals(second_vertex)) { double edge_cost = 0.0; if (chkEdgeWeights.Checked) { edge_cost = my_rand.Next(0, MAX_EDGE_VALUE) / ONE_HUNDRED_PERCENT; } //make sure you are adding edges to unconnected vertices first int degree_one = the_graph.degree(first_vertex); int degree_two = the_graph.degree(second_vertex); if (newEdgeCheck(the_graph, degree_one, degree_two, added) && !the_graph.containsEdge(first_vertex, second_vertex)) { the_graph.addEdge(first_vertex, second_vertex, edge_cost); //track changes not_added.remove(first_vertex); not_added.remove(second_vertex); added.add(first_vertex); added.add(second_vertex); //show user progress pbrProgress.Value += 1; //update periodically or rapidly if near the end of edge generation //this rapid update is due to the high cost of random selection with //graphs whose edge count is near the complete graph Kn if (pbrProgress.Value % EVENT_UPDATE_THRESHOLD == 0 || max_edges - the_graph.edgeSize() < MAXIMUM_EDGE_THRESHOLD) { Application.DoEvents(); } } } } }
/// <summary> /// Sets up the wall with two cells adjacent to it. /// </summary> /// <param name="the_cell_one">the first cell.</param> /// <param name="the_cell_two">the second cell.</param> public Wall(DSInteger the_cell_one, DSInteger the_cell_two) { my_cell_one = the_cell_one; my_cell_two = the_cell_two; }
//moves the user through the maze depending on the input received. private void move(MazeMove the_move) { //if the user pull up the hint, then remove it if (my_solution_path != null) { my_solution_path = null; pnlDraw.Refresh(); } //generate graph if necessary generateGraph(); DSInteger current_move = my_user_solution_path.last(); List <SimpleEdge <DSInteger> > next_moves = my_maze_graph.getEdgesIncidentTo(current_move); //get the next moves in the graph (adjacent vertices) DSInteger check; bool found = false; //which move was chosen switch (the_move) { case MazeMove.Up: check = new DSInteger(current_move.value - my_cols); if (checkContains(next_moves, check)) { found = true; } break; case MazeMove.Down: check = new DSInteger(current_move.value + my_cols); if (checkContains(next_moves, check)) { found = true; } break; case MazeMove.Left: check = new DSInteger(current_move.value - 1); if (checkContains(next_moves, check)) { found = true; } break; default: //right check = new DSInteger(current_move.value + 1); if (checkContains(next_moves, check)) { found = true; } break; } //if the user can move in that direction (no wall - an edge exists in the graph) if (found) { //check for backtracking (the second to last element was the last move if (my_user_solution_path.size() > 1 && my_user_solution_path.get(my_user_solution_path.size() - 2).Equals(check)) { //the last element is my_current_move DSInteger removed = my_user_solution_path.removeAt(my_user_solution_path.size() - 1); //update the maze drawUserSolution(false, removed); } else { my_user_solution_path.add(check); drawUserSolution(false, null); } //check for reaching the finish node userReachsFinish(my_user_solution_path.last()); } }
/// <summary> /// Given a number of elements, this method will return all subsets and the /// permutations for each subset. The list returned contains lists of indices /// which can be used on an original list/array of data elements. /// </summary> /// <typeparam name="T">the reference type of elements.</typeparam> /// <param name="the_number_of_elements">the number of elements to find subsets of.</param> /// <returns>a list containing lists of unique subsets and their permutations.</returns> public List <List <DSInteger> > getUniquePermutationIndices <T>(int the_number_of_elements) where T : class { //this method builds an M-ary tree of unique subsets and their permutations //where M is the number of elements given to the method // -------------------- STEPS ----------------------- //1. The algorithm first adds a dummy root node and each of the element's // indices as a child to the root. //2. The algorithm then begins a depth first search adding child elements // to existing elements where there are no duplications. The indices of // the elements at any node in the tree are stored in a list as the value // for the tree node. //3. Lastly a second breadth-first search is performed on the tree to extract // all unique permutations from the nodes. if (the_number_of_elements == 0) { return(new ArrayList <List <DSInteger> >()); } //updates int tree_elements = getTotalTreeElements(the_number_of_elements); tree_elements = tree_elements + tree_elements; int update_count = 0; int depth = 0; List <List <DSInteger> > return_value = new ArrayList <List <DSInteger> >(the_number_of_elements); MAryNode <List <DSInteger> > root = new MAryNode <List <DSInteger> >(null); //build the first level of the tree for (int i = 0; i < the_number_of_elements; i++) { List <DSInteger> list = new LinkedList <DSInteger>(); list.add(new DSInteger(i)); root.addChild(list); } depth = 1; int row_count, new_row_count; BasicQueue <MAryNode <List <DSInteger> > > queue = new Queue <MAryNode <List <DSInteger> > >(); for (int i = 0; i < root.children.size(); i++) { queue.add(root.children.get(i)); showChanges(tree_elements, ++update_count); } //for each level while (depth < the_number_of_elements) { row_count = queue.size(); new_row_count = 0; //for each element in the row while (row_count > 0) { MAryNode <List <DSInteger> > node = queue.dequeue(); row_count--; for (int i = 0; i < the_number_of_elements; i++) { DSInteger check = new DSInteger(i); if (!node.value.contains(check)) { //copy across old values List <DSInteger> new_list = new LinkedList <DSInteger>(); for (int j = 0; j < node.value.size(); j++) { new_list.add(node.value.get(j)); } //add new value new_list.add(check); //add the new node node.addChild(new_list); //ready the next row new_row_count++; //enqueue the new child queue.enqueue(node.children.get(node.children.size() - 1)); //show the change showChanges(tree_elements, ++update_count); } } } depth++; } queue.clear(); //perform a breadth-first search and record the lists for (int i = 0; i < root.children.size(); i++) { queue.enqueue(root.children.get(i)); } //loop while searching while (!queue.isEmpty()) { //record the current nodes list MAryNode <List <DSInteger> > node = queue.dequeue(); return_value.add(node.value); //add all children to the queue if (node.children != null) { for (int i = 0; i < node.children.size(); i++) { queue.enqueue(node.children.get(i)); } } //show the change showChanges(tree_elements, ++update_count); } return(return_value); }