example - there is an unconnected graph with vertices A - B - C - D and E - F - G. (a hyphen means that they are connected). The code below is using depth-first traversal, I need to modify it to display all connected vertices. eg:
list0: ABCD
list1: EFG
etc...
I don't understand how to implement this.
public class Graph {
private final int MAX_VERTS = 20;
private Vertex vertexList[];
private int matrix[][];
private int countV;
private StackX theStack;
// ------------------------------------------------------------
public Graph() {
vertexList = new Vertex[MAX_VERTS];
matrix = new int[MAX_VERTS][MAX_VERTS];
countV = 0;
for (int x = 0; x < MAX_VERTS; x++)
for (int y = 0; y < MAX_VERTS; y++)
matrix[x][y] = 0;
theStack = new StackX();
}
// -------------------------------------------------------------
public void addVertex(char label) {
vertexList[countV++] = new Vertex(label);
}
// -------------------------------------------------------------
public void addEdge(int x, int y) {
matrix[x][y] = 1;
matrix[y][x] = 1;
}
// -------------------------------------------------------------
public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}
public void dfs() {
vertexList[0].wasVisited = true;
displayVertex(0);
theStack.push(0);
while (!theStack.isEmpty()) {
int v = getUnvisitedVertex(theStack.peek());
if (v == -1)
theStack.pop();
else
{
vertexList[v].wasVisited = true;
displayVertex(v);
theStack.push(v);
}
}
for (int j = 0; j < countV; j++)
vertexList[j].wasVisited = false;
}
// ------------------------------------------------------------
public int getUnvisitedVertex(int vertex) {
for (int j = 0; j < countV; j++)
if (matrix[vertex][j] == 1 && !vertexList[j].wasVisited) {
return j;
}
return -1;
}
}
Your DFS does not need to modified. It needs to be put inside a loop so that each pass will discover one of the lists of connected nodes that your are looking for
LOOP
Select arbitrary vertex
DFS, saving each visited vertex in list.
LOOP over visited vertices
remove from graph
LOOP END
IF all vertices removed
BREAK out of loop
Start new list
LOOP END
Output lists
Related
I have two 2d boolean arrays, the smaller array (shape) is going over the larger array (world).
I am having trouble to find a method to find out when the smaller array can "fit" into the larger one.
When I run the code it either just goes through the larger array, never stopping, or stops after one step (incorrectly).
public void solve() {
ArrayList<Boolean> worldList=new ArrayList<>();
ArrayList<Boolean> shapeList=new ArrayList<>();
for (int i = 0; i < world.length; i++) {
for (int k = 0; k < world[i].length; k++) {
worldList.add(world[i][k]);
display(i, k, Orientation.ROTATE_NONE);
for (int j = 0; j < shape.length; j++) {
for (int l = 0; l < shape[j].length; l++) {
shapeList.add(shape[j][l]);
if(shapeList.equals(worldList)) {
return;
}
}
}
}
}
}
A good place to start with a problem like this is brute force for the simplest case. So, for each index in the world list, just check to see if every following index of world and shapes match.
Notice we only iterate to world.size()-shapes.size(), because naturally if shapes is longer than the portion of world we haven't checked, it won't fit.
import java.util.ArrayList;
public class Test {
ArrayList<Boolean> world = new ArrayList<>();
ArrayList<Boolean> shapes = new ArrayList<>();
public static void main(String[] args) {
new Work();
}
public Test() {
world.add(true);
world.add(false);
world.add(false);
world.add(true);
shapes.add(false);
shapes.add(true);
// Arraylists initialized to these values:
// world: T F F T
// shapes: F T
System.out.println(getFitIndex());
}
/**
* Get the index of the fit, -1 if it won't fit.
* #return
*/
public int getFitIndex() {
for (int w = 0; w <= world.size()-shapes.size(); w++) {
boolean fits = true;
for (int s = 0; s < shapes.size(); s++) {
System.out.println("Compare shapes[" + s + "] and world["+ (w+s) + "]: " +
shapes.get(s).equals(world.get(w+s)));
if (!shapes.get(s).equals(world.get(w+s))) fits = false;
}
System.out.println();
if (fits) return w;
}
return -1;
}
}
When we run this code, we get a value of 2 printed to the console, since shapes does indeed fit inside world, starting at world[2].
You can find the row and column of fitting like this
public void fit() {
int h = world.length - shape.length;
int w = world[0].length - shape[0].length;
for (int i = 0; i <= h; i++) {
for (int k = 0; k <= w; k++) {
boolean found = true;
for (int j = 0; j < shape.length && found; j++) {
for (int l = 0; l < shape[j].length && found; l++) {
if (shape[j][l] != world[i + j][k + l])
found = false;
}
}
if (found) {
//Your shape list fit the world list at starting index (i, k)
//You can for example save the i, k variable in instance variable
//Or return then as an object for further use
return;
}
}
}
I attempted to follow this pseudocode on wikipedia https://en.wikipedia.org/wiki/Maze_generation_algorithmRandomized_Prim's_algorithm
but my code just generates a full grid. I seem to be missing something in my understanding of what the algorithm does. Can someone help explain what I'm doing wrong?
I've looked at a few sources but I can't wrap my head around it
public class MazeGen {
private int dimension, nodeCounter;
private Node[][] nodes;
private List<Edge> walls;
public static void main(String[] args) {
MazeGen g = new MazeGen(20);
g.generate();
g.printMaze();
}
private void generate() {
pickCell();
generateMaze();
}
private void generateMaze() {
while (!walls.isEmpty()) {
int v;
Edge wall = walls.get(ThreadLocalRandom.current().nextInt(walls.size()));
if ((!wall.nodes[0].visited && wall.nodes[1].visited)
|| (wall.nodes[0].visited && !wall.nodes[1].visited)) {
if (!wall.nodes[0].visited)
v = 0;
else
v = 1;
includeNode(wall.nodes[v]);
wall.nodes[Math.abs(v - 1)].visited = true;
}
walls.remove(wall);
}
}
private void pickCell() {
int i = ThreadLocalRandom.current().nextInt(dimension);
int j = ThreadLocalRandom.current().nextInt(dimension);
includeNode(nodes[i][j]);
}
private void includeNode(Node node) {
node.visited = true;
node.partOfMaze = true;
walls.addAll(node.edges);
}
public void printMaze() {
for (int i = 0; i < dimension; i++) {
System.out.println();
for (int j = 0; j < dimension; j++) {
if (nodes[i][j].partOfMaze) {
System.out.print(".");
} else
System.out.print("p");
}
}
}
public MazeGen(int n) {
nodes = new Node[n][n];
walls = new ArrayList<Edge>();
dimension = n;
createNodes();
connectAdjacents();
}
private void connectAdjacents() {
for (int i = 0; i < dimension; i++) {
for (int j = 0; j < dimension; j++) {
verifyConnection(i, j, i, j + 1);
verifyConnection(i, j, i + 1, j);
}
}
}
private void verifyConnection(int i, int j, int arg1, int arg2) {
if (arg1 < dimension && arg2 < dimension)
connect(i, j, arg1, arg2);
}
private void createNodes() {
for (int i = 0; i < dimension; i++) {
for (int j = 0; j < dimension; j++) {
nodes[i][j] = new Node();
}
}
}
private void connect(int row, int col, int row2, int col2) {
nodes[row][col].edges.add(new Edge(nodes[row][col], nodes[row2][col2]));
nodes[row2][col2].edges.add(new Edge(nodes[row][col], nodes[row2][col2]));
}
private class Node {
boolean visited, partOfMaze;
int number;
List<Edge> edges;
Node() {
number = nodeCounter++;
edges = new ArrayList<Edge>();
}
#Override
public String toString() {
return String.valueOf(number);
}
}
private class Edge {
Node[] nodes;
Edge(Node n, Node n2) {
nodes = new Node[2];
nodes[0] = n;
nodes[1] = n2;
}
#Override
public String toString() {
return nodes[0] + "-" + nodes[1];
}
}
I think that your algorithm is correct but you don't keep the correct output.
All the nodes should be part of the maze. The walls that should be part of the maze are the walls that connect two visited nodes when you proccess them.
make another array of output walls, and set the values in the generateMaze method.
private void generateMaze() {
while (!walls.isEmpty()) {
int v;
Edge wall = walls.get(ThreadLocalRandom.current().nextInt(walls.size()));
if ((!wall.nodes[0].visited && wall.nodes[1].visited)
|| (wall.nodes[0].visited && !wall.nodes[1].visited)) {
if (!wall.nodes[0].visited)
v = 0;
else
v = 1;
includeNode(wall.nodes[v]);
wall.nodes[Math.abs(v - 1)].visited = true;
/////////////////////////////////////
// remove this wall from the output walls
/////////////////////////////////////
} else {
////////////////////////////////
// add this wall to the output walls
////////////////////////////////
}
walls.remove(wall);
}
}
Forget Wikipedia, they censor free speech and manipulate information, especially in political and social areas. For that reason I also deleted all my additions to the Wikipedia page on "maze generation" (see page history).
The idea of "Prim's" MST algorithm is to maintain a "cut" (a set of edges) between disconnected subgraphs and always select the cheapest edge to connect these subgraphs. Visited vertices are marked to avoid generating cycles.
This can be used for maze generation by using edge random weights in a full grid graph or by starting with an empty grid graph and adding randomly weighted edges on the fly.
See my GitHub repository on maze generation for details:
https://github.com/armin-reichert/mazes
https://github.com/armin-reichert/mazes/blob/master/mazes-algorithms/src/main/java/de/amr/maze/alg/mst/PrimMST.java
public void createMaze(int x, int y) {
cut = new PriorityQueue<>();
expand(grid.cell(x, y));
while (!cut.isEmpty()) {
WeightedEdge<Integer> minEdge = cut.poll();
int u = minEdge.either(), v = minEdge.other();
if (isCellUnvisited(u) || isCellUnvisited(v)) {
grid.addEdge(u, v);
expand(isCellUnvisited(u) ? u : v);
}
}
}
private void expand(int cell) {
grid.set(cell, COMPLETED);
grid.neighbors(cell).filter(this::isCellUnvisited).forEach(neighbor -> {
cut.add(new WeightedEdge<>(cell, neighbor, rnd.nextInt()));
});
}
So I have some code which finds items in an array which are greater than itself in respect to its position. So for example if the list was:
[1,3,2]
2 and 3 would need to be swapped, to be ordered so they would be added to the adjacency list.
However, for slightly larger problems I want to be able to find the vertex cover of the graph such that of a graph is a set of vertices such that each edge of the graph is incident to at least one vertex of the set
Want I'm looking for is something like this for example [4,2,3,1]:
public class VertexCover{
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] row = {4, 2, 1, 5};
Vertex[] adjLists = new Vertex[row.length];
for (int i = 0; i < adjLists.length; i++) {
adjLists[i] = new Vertex(row[i], null);
}
int max = -1;
for (int i = 0; i < row.length; i++) {
for (int j = 0; j < row.length; j++) {
if (adjLists[i].value > adjLists[j].value && i < j) {
adjLists[i].adjList = new Neighbour(j, adjLists[i].adjList);
adjLists[j].adjList = new Neighbour(i, adjLists[j].adjList);
}
}
}
for (int i = 0; i < adjLists.length; i++) {
System.out.print(adjLists[i].value);
for (Neighbour neighbour = adjLists[i].adjList; neighbour != null; neighbour = neighbour.next) {
System.out.print("---->" + adjLists[neighbour.vertexNum].value);
}
System.out.println("");
}
}
}
class Vertex {
int value;
Neighbour adjList;
Vertex(int value, Neighbour neighbours) {
this.value = value;
this.adjList = neighbours;
}
}
class Neighbour {
int vertexNum;
public Neighbour next;
public Neighbour(int vnum, Neighbour next) {
this.vertexNum = vnum;
this.next = next;
}
}
I can't find anything on this, apart from its np complete.
I'm writing a program to find the longest path for a DAG with input from standard in.I finally got it to compile, with it saying it is using unchecked or unsafe operations due to my Array list, but I am getting an index out of bounds error and it feels like I have tried changing every loop I must be missing something, thanks in advanced for any tips.
Here is my code:
import java.io.*;
import java.util.*;
public class countLongPaths
{
static final int NINF = Integer.MIN_VALUE;
public class AdjListNode
{
private int v;
private int weight;
AdjListNode(int inV, int inW)
{
v = inV;
weight = inW;
}
int getV()
{
return v;
}
int getWeight()
{
return weight;
}
}//end of adj list class
public class Graph
{
private int V;
private LinkedList<AdjListNode>adj[];
//set up graph with given number of verticies
Graph(int v)
{
V=v;
adj = new LinkedList[V];
for (int i = 0; i < v; ++i)
adj[i] = new LinkedList<AdjListNode>();
}
//function to add edges to graph
void addEdge(int u, int v, int weight)
{
AdjListNode node = new AdjListNode(v,weight);
adj[u].add(node);// Add v to u's list
}
//function to set order to go through vertices
void setOrder(int v, Boolean visited[], Stack stack)
{
//Set node to visited when on it
visited[v] = true;
Integer i;
//for all nodes connected to current repeat
Iterator<AdjListNode> it = adj[v].iterator();
while (it.hasNext())
{
AdjListNode node =it.next();
if (!visited[node.getV()])
setOrder(node.getV(), visited, stack);
}
//Once done with current add it to the stack
stack.push(new Integer(v));
}
//function to find longest paths from s
int longestPath()
{
Stack stack = new Stack();
int LP[] = new int[V];
//set all vertices to unvisited
Boolean visited[] = new Boolean[V];
for(int i = 1; i <= V; i++)
visited[i] = false;
//call set order function from each vertex
for (int i = 1; i <= V; i++)
{
if(visited[i] == false)
setOrder(i, visited, stack);
}
//initialize distaces to all verices as negative infinity
//set distace to source to 0
LP[1] = 0;
for(int i = 2; i <= V; i++)
LP[i] = NINF;
//go through vertices in order
while(stack.empty() == false)
{
int u = (int)stack.pop();
//update LP for adj vertices
Iterator<AdjListNode> it;
if (LP[u] != NINF)
{
it = adj[u].iterator();
while (it.hasNext())
{
AdjListNode i = it.next();
if(LP[i.getV()] < LP[u] + i.getWeight())
LP[i.getV()] = LP[u] + i.getWeight();
}
}
}
return LP[V];
}
}//end of graph class
//Method to make a new graph
public Graph newGraph(int number)
{
return new Graph(number);
}
public static void main(String[]args)
{
countLongPaths n = new countLongPaths();
int GN = 0;
int count = 1;
Scanner scan = new Scanner(System.in);
GN = scan.nextInt();
while (count<= GN)
{
int N = 0;// nodes
int M = 0;//edges
N = scan.nextInt();
M = scan.nextInt();
//setup a new graph
Graph g = n.newGraph(N);
//set edges for new graph
for(int i = 1; i <= M; i ++)
{
int I = scan.nextInt();
int J = scan.nextInt();
int W = scan.nextInt();
g.addEdge(I, J, W);
}
int dist = 0;
dist = g.longestPath();
System.out.println("graph number: " + count);
System.out.println("longest path: " + dist);
System.out.println("number of longest paths: ");
System.out.println();
count++;
}//end of while
}//end main
}//end program
EDIT 1
with current code this is the error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at countLongPaths$Graph.<init>(countLongPaths.java:36)
at countLongPaths.newGraph(countLongPaths.java:108)
at countLongPaths.main(countLongPaths.java:127)
As your stack trace says, the exception occurs in your Graph class constructor.
More specifically it happens inside the only line in your loop:
adj = new LinkedList[V];
for (int i = 0; i <= v; ++i)
adj[i] = new LinkedList<AdjListNode>();
Assuming you've meant both lowercase v and uppercase V to be the same variable, you're defining an array of size V which is indexed from 0 to V-1, but you're running on it from 0 to V (your condition is i <= V), which is why you're getting an IndexOutOfBoundsException.
Simply change the loop's condition (remove the =):
for (int i = 0; i < v; ++i)
I tried writing a maze solution method using DFS to find a path through a maze that's generated. But I'm having trouble with it. It doesn't even look like it ever finishes the traversal. Here is some output from a sample run. The maze looks like this:
+ +--+--+--+
| | |
+ +--+ + +
| | |
+--+--+--+ +
| | |
+ + + +--+
| | |
+--+--+--+ +
And my DFS method produces this:
0 1 5 9
In the end, I want to display that same maze but with numbers inside of it's path that represent the order which I have visited and ran through it.
Anyway, here's my code:
public static void depthFirstSearch(){
boolean[] visited = new boolean[totalCells]; // marks which vertices have been visited during the search
Stack<Vertex> st = new Stack<Vertex>();
st.push(graph[0][0]);
while(!st.isEmpty()){
Vertex v = st.pop();
if(!visited[v.label]){
visited[v.label] = true;
System.out.print(v.label + " ");
// auxiliary stack to visit neighbors in the order which they appear
Stack<Vertex> auxStack = new Stack<Vertex>();
for(Vertex w : v.neighbors){
if(!visited[w.label]){
auxStack.push(w);
}
}
while(!auxStack.isEmpty()){
st.push(auxStack.pop());
}
}
}
System.out.println();
}
Here is also the Vertex:
class Vertex{
int label;
int x;
int y;
boolean isVisited = false;
boolean hasNorthWall = true;
boolean hasSouthWall = true;
boolean hasEastWall = true;
boolean hasWestWall = true;
boolean hasAllWalls = true;
ArrayList<Vertex> neighbors = new ArrayList<Vertex>();
public Vertex(int x, int y){
this.x = x;
this.y = y;
}
}
And my constructor:
public Maze(int size)
{
this.SIZE = size;
totalCells = SIZE * SIZE;
cellStack = new Stack<Vertex>();
graph = new Vertex[SIZE][SIZE];
}
Thank you in advance for any help!
EDIT: Adding how neighbors are assigned.
public void assignNeighbors(Vertex v)
{
//This handles the cell north of current cell
if(v.y != 0)
{
v.neighbors.add(graph[v.x][v.y-1]);
}
//This handles the cell south of the current cell
if(v.y != (SIZE-1))
{
v.neighbors.add(graph[v.x][v.y+1]);
}
//This handles the cell left of the current cell
if(v.x != 0)
{
v.neighbors.add(graph[v.x -1][v.y]);
}
//right of the current
if(v.x != SIZE-1)
{
v.neighbors.add(graph[v.x + 1][v.y]);
}
}
EDIT2: Adding in how the label is assigned (it just stores the vertex number)
public void fill()
{
int vertexNumber = 0;
//This loop creates a new vertex
for(int i=0; i < SIZE; i++)
{
for(int j = 0; j < SIZE; j++)
{
Vertex v = new Vertex(j,i);
graph[j][i] = v;
}
}
//adds values to vertex
for(int i = 0; i < SIZE; i++)
{
for(int j = 0; j < SIZE; j++)
{
graph[j][i].label = vertexNumber;
vertexNumber++;
}
}
//This loop assigns the neighbors
for(int i = 0; i < SIZE; i++)
{
for(int j = 0; j < SIZE; j++)
{
assignNeighbors(graph[j][i]);
}
}
mazeGenerator();
}
I'm not quite sure about this part
for(Vertex w : v.neighbors){
if(!visited[w.label]){
auxStack.push(w);
}
}
while(!auxStack.isEmpty()){
st.push(auxStack.pop());
}
If I'm correct you can replace this with just one loop but this shouldn't be the problem. Have you tried debugging it step by step? You know how the maze looks like and thus you know how the alghoritm should behave in every step. I suggest you try it and then maybe update your post and describe at which step your algorithm behaves weird.
I wanted to add this as comment but I lack the reputation.