I was just wondering, is it possible to change the direction of depth first search? I have to find the path from the starting node to the goal node. Here's how my depth first search result looks like. 0 5 7 8 9 10 6 4 1 3 2 11. The starting node is 0 and my goal node is 1. The path I want is 0 5 4 1. Does direction really matters in depth first search?
Here's my code:
public void performIterativeDFS(Graph G, int node, int goal) {
ArrayBasedStack arrayStack = new ArrayBasedStack();
arrayStack.push(node);
visited[node] = true;
while (!arrayStack.isEmpty()) {
int n = arrayStack.pop();
System.out.print(n + " ");
for (int w : G.adjList(n)) {
if (!visited[w]) {
visited[w] = true;
arrayStack.push(w);
if (w == goal) {
goal = w;
System.out.print(" Goal Found: ");
}
}
}
}
}
Structure:
11 3
2 3
0 3
1 4
5 4
5 7
6 7
7 8
8 9
9 10
0 5
DFS randomly selects a direction whenever a choice is possible and continues in that direction, marking previous positions, until it hits a roadblock. I am not sure how and why you would control that direction. However, If you are looking for the shortest path use Breadth first search(BFS) to do that. It will systematically explore nearby nodes before moving ahead and will give you the most optimal path.
Related
Given a matrix of N * M. Find the minimum path sum in matrix. The minimum path is sum of all elements from first row to last row where you are allowed to move only down or diagonally to left or right. You can start from any element in first row.
I've written the code,but what is wrong in my code/logic?
here in my algorithm I am starting from the element of the top row, now I'm going to the second row and algorithm is finding the minimum value and add with the first element and thus it makes way to the bottom(a element can only add with the elment which is under it and also can move diagonally right and left)
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int row, column, i, j,temp=0;
System.out.print("Please enter the desire grid dimension: ");
row = sc.nextInt();
column = sc.nextInt();
int array[][] = new int[row][column];
System.out.println("Please enter the desired input:");
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
array[i][j] = sc.nextInt();
}
}
for(i=1;i<row;i++){
for(j=0;j<column;j++){
array[i][j] += Math.min((j==0)?0:array[i-1][j-1],Math.min(array[i-1][j],(j==column-1)?0:array[i-1][j+1]));
}
}
for(i=0;i<row;i++){
for(j=0;j<column;j++){
System.out.print(array[i][j] + " ");
}
System.out.println();
}
for(j=0;j<column-1;j++){
temp = Math.min(array[row-1][j],array[row-1][j+1]);
}
System.out.println(temp);
}
}
let your input is
1 5 1 5 1* 5
3 3 2 3 3* 4
2 3 4 4 3 2*
2 2 3 2 2* 4
2 2 4 3 4 2*
4 4 4 4 2* 3
your output should be 12,path is marked with(*) 1+3+2+2+2+2=12
I'm getting 3,because after running my algorithm the matrix became
1 5 1 5 1 5
3 4 3 4 4 4
2 6 7 7 7 2
2 4 9 9 4 4
2 4 8 7 8 2
4 6 8 11 4 3
I am not giving you a complete answer. You will learn more from finding out yourself. At the same time this will be more gratifying for you. So I will just guide you slightly on the way and trust you to do the rest yourself. It’s not that hard.
First, however, for other readers to follow what I write I need to give the explanation that you should have given in the question of how your algorithm was supposed to work. You are modifying the matrix in a way so that each cell instead of its original number gets to contain the minimum sum of a path from the top to that cell inclusive. For example:
We see from your matrix after the algorithm has run that the top line is unchanged. This is correct since you can go directly into each cell, so the sum is equal to the original cell value.
In the second line, the second (index 1) cell has been changed from 3 to 4. This is correct since to go to that cell we need to go through 1 or 5 or 1 in the first line. 1 gives the minimal sum, so 1 is added to 3, hence 4.
In the same line, the leftmost cell is unchanged 3. The is incorrect. To get to this cell you also need to go through either 1 or 5 in the first line, so this 3 too should have been changed to 4. I will give you one piece of information: the cell was not forgotten. Your loop assigns a value to the cell, only not the correct value. 1 should have been added, instead 0 was added. Where does this 0 come from? Your turn! Happy debugging.
I had to implement an 8 puzzle solver utilizing the A* algorithm with two heuristics. The first heuristic was just the sum of the out-of-place tiles, the second is the sum of the Manhattan distances of all tiles from the goal state, which we are defining as:
0 1 2
3 4 5
6 7 8
We given were sample tests of varying depths. My implementation using the first heuristic passes all of these cases, but the second heuristic does not pass certain test cases once it reaches depths of 14:
(52) !Test Case failed! for initialState:
3 1 5
6 0 7
8 2 4
Expected depth of 14 but got 16
(12) !Test Case failed! for initialState:
4 1 5
3 2 7
0 8 6
Expected depth of 16 but got 18
(39) !Test Case failed! for initialState:
2 5 7
3 4 1
6 8 0
Expected depth of 16 but got 18
(There are more failed tests, these are just the first three) Since it seems to work for all cases when I use the first heuristic, I'm guessing it's something wrong with the second heuristic. Here is my abstract "node" class:
public EightPuzzleState(int[] state, EightPuzzleState goalState, EightPuzzleState previousState) {
this.state = new int[NUM_SPACES];
try {
System.arraycopy(state, 0, this.state, 0, NUM_SPACES);
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
this.previousState = previousState;
setCost(goalState);
}
private void setCost(EightPuzzleState goalState) {
if(goalState == null) {
System.out.println("Cost is 0- no goal state defined");
cost = 0;
}
else {
cost = calcCost(goalState);
}
}
private int calcCost(EightPuzzleState goalState) {
int sum = 0;
for(int i = 0; i < NUM_SPACES; i++) {
sum+=heuristic(goalState, i);
}
if(previousState == null) {
//System.out.println("No previous parent defined, 0 pathCost");
pathCost = 0;
}
else {
pathCost = previousState.getPathCost()+1;
}
return sum + pathCost;
And here is the node class that utilizes the second heuristic:
//In EightPuzzleStateH2 class, which extends EightPuzzleState
#Override
protected int heuristic(EightPuzzleState goalState, int currentIndex) {
int currentValue = this.getState()[currentIndex];
int[] goalStateArray = goalState.getState();
int i = 0;
while(currentValue != goalStateArray[i]) {
i++;
}
return calcManhattenDistance(currentIndex,i);
}
private int calcManhattenDistance(int currentIndex, int goalIndex) {
int xDistance = Math.abs((currentIndex % NUM_SPACES_PER_ROW) - (goalIndex % NUM_SPACES_PER_ROW));
int yDistance = Math.abs((currentIndex / NUM_SPACES_PER_ROW) - (goalIndex / NUM_SPACES_PER_ROW));
return (xDistance+yDistance);
}
Any insight would be helpful- if the issue isn't within the second heuristic, then I'm really going to be stumped since the first heuristic worked flawlessly!
I was able to fix this issue by modifying my hashcode function for my EightPuzzleState class.
Also, when calculating the heuristic, I was including the hole in the calculation, but the hole should not be included in the cost calculation. This was not related to the problem I was having, but for the sake of other readers I am addressing it here.
I have a sudoku puzzle 9x9 in a text file and I wondering how can we create a Graph from sudoku puzzle.Sudoku puzzle is a int[][] Example puzzle
0 0 0 0 9 8 0 4 5
0 0 4 3 2 0 7 0 0
7 9 0 5 0 0 0 3 0
0 0 0 9 0 0 4 0 0
0 4 5 0 0 2 8 0 0
8 7 9 6 0 4 0 1 0
0 3 0 0 7 9 0 6 4
4 5 0 2 1 3 9 0 8
0 8 7 4 6 5 0 0 0
and class Graph
class Graph
{
private int V;
private LinkedList<Integer> adj[];
Graph(int v)
{
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i)
adj[i] = new LinkedList();
}
void addEdge(int v,int w)
{
adj[v].add(w);
adj[w].add(v);
}
public int getV()
{
return V;
}
public LinkedList<Integer> getListAdj(int u)
{
return adj[u];
}
I write a function to read puzzle from a text file and implement it to graph
public boolean readGraph(String input_name, int result[])
{
return true;
}
But I stuck in this step.
Here goes:
First, I already know that the puzzle is 9x9, so the newlines in the text file are meaningless to me. I can ignore them. Also, I know that each element of the puzzle is only ever going to be a single character long so (after getting the text file into memory like so: Reading a plain text file in Java):
I get my String puzzle which is that text file into memory. Now I want to iterate over that String like so:
Graph graph = new Graph(81); //9x9 graph with 81 verticies
int whichVertextAreWeOn = 0;
for (int i = 0; i < puzzle.length(); i++){
char c = puzzle.charAt(i);
if(c>'0' && c > '9'){
int integer = Integer.parseInt(c);
//now I need to add this to my Graph... Saving my work now, comments are appreciated
//Turns out you simply add edges to each vertex in a graph, the vertex itself has no value...
//so I'm going to keep track of which vertex I'm on, this is starting to seem like a bad data structure for this purpose, but I shall carry on. -Adding an iterator to keep track of which vertex I'm on.
for(int w = 0; w < graph.V(); w++;){
if(vertextIsLinked(whichVertextAreWeOn, w))
graph.addEdge(whichVertextAreWeOn, w);
}
//hum... from here I need to add an edge to this vertex for each connected vertex...
}
}
private boolean vertextIsLinked(int vertexWeAreOn, int possibleVertext){
//use rules of Sukdoku to figure out if these two verticies should be linked. This would return true for any vertex in horizontal or vertical alignment to the vertexWeAreOn.
}
I have an array list containing 5 bulbs. I can iterate throuh them like this
for(Bulb bul : list){
System.out.println(bul.id);
}
No a bulb is switched off/on. The effect is that its neighbourg bulbs a switch too.
My problem is that when the last or 4th bulb are switched I need to determine its neighbours. Since I have 5 bulbs this would work.
int bulbIdClicked = 3;
if(bul.id == (bulbIdClicked + 1)%5)
if(bul.id == (bulbIdClicked - 1)%5)
For 3 it would give me 2 and 4 as neighbours. But when 4 is switched it gives me 3 and 0 ans neighbours where 0 should be 5.
How can I solve that problem?
If it should go from 0 to 5 you should use %6
If you have a bulb ID ranging from 0 to 4, the best way to get the next and previous IDs is to use:
next = (id + 1) % 5
prev = (id + 4) % 5
This is language-agnostic since not all languages treat modulus operators on negative numbers the same. You can see that stepping forward 4 from 4 (for example) gives you: 0, 1, 2, 3 which is the same as a step backwards.
However. modulus really only works on zero-based values. Since you have one-based values, you can subtract one first, do the relevant addition/modulo, then add one again.
next = ((id - 1) + 1) % 5 + 1
prev = ((id - 1) + 4) % 5 + 1
These simplify down to:
next = id % 5 + 1
prev = (id + 3) % 5 + 1
Using those formula, you get:
id next prev
-- ---- ----
1 2 5
2 3 1
3 4 2
4 5 3
5 1 4
as expected.
That's about as optimised as you're likely to get without a lookup table. You can use the same approach for any roll-over size (not just 5), you just have to change the modulo and what you add.
If the indexes range from 1 to N, its:
next = id % [N] + 1
prev = (id + [N-2]) % [N] + 1
where the figures inside [] are constant based on the number of indexes.
the array index starts from 0, so if you have 5 elements, then they are in position 0,1,2,3,4..
By using 0..4 as your bulb IDs instead of 1..5. This is in fact the main reason why programmers prefer zero-based counting: it simplifies indexing.
Check whether this is the last bulb. The last bulb will have only the left neighbor
if(bul.id == numBulbs)
{
//Check only left side
if(bul.id == (bulbIdClicked - 1)%5)
...
}
You have do the same for the first bulb
if(bul.id == 0)
{
//Check only right side
if(bul.id == (bulbIdClicked + 1)%5)
...
}
If you need to navigate a List backwards and forwards, use ListIterator (available through the list.listIterator() or list.listIterator(index) methods. Here's some sample code:
List<Bulb> bulbs = new ArrayList<Bulb>();
int amount = 500;
for(int i = 0; i < amount; i++){bulbs.add(new Bulb());}
// which one to switch off
int offset = new Random().nextInt(amount);
ListIterator<Bulb> li = bulbs.listIterator(offset);
li.next().switchOff();
if(li.hasNext()){
li.next().switchOff();
// go back to selected offset
li.previous();
}
if(li.hasPrevious()){
li.previous().switchOff();
}
Before the Floyd–Warshall/Dijkstra replies flood comes in please let me explain the situation as i'm sure either algorithm can be tuned for this case, and it has to be as this is not a toy example program (mind you, in java so have to keep it manageable memory-wise)
What i have is a web graph generated from node 0 to node n, node 3 cannot link to node 5, because node 5 didnt exist when node 3 was choosing it's out links. Every "node" is represented as in_neighbours[nodeID] and out_neighbours[nodeID] say nodeId=3, so we're talking about node 3. Note also that in_/out_ are both sorted, (in_ is naturally sorted as 5 will have chosen its out links all at once, only then 6 will choose out_links so 3's in_'s can never contain {6, 5, 7}) and ofc both can contain duplicates. (in/out are ArrayList arrays of size n, where out_ is always of size d or m, which along with n is specified at startup by the user)
No weights. What i must do is find the averageDistance()
public double getAvgDistance() {
int sum = 0;
for (int i=1; i<n; i++) {
for (int j=0; j < i; j++) {
sum += dist(i, j); // there are duplicates, make sure i skip
}
}
return (double)sum / (double)( ((n*(n-1)) / 2) );
}
What I have so far is the best case. Note i want only to find the distance between j & i, not all distances at the same time (not enough memory, it will be tested at m=20 d=1 000 000)
private int dist(int i, int j) {
int dist = 0;
for (int link : in_neighbours[j]) {
System.out.print("\nIs "+j+" linked to by "+i);
if (out_neighbours[i].contains(link)) {
System.out.print(" - yes!");
dist = 1;
}
}
return dist;
}
So im asking if the "fresher" (ofc at this point the graph is completed) node i is linking to any of its older buddies directly if so, distance is 1 hop.
Is it just me or the 'shortest' path will always be the first found path if nodes are traversed backwards?
How do i check if its not 1, the "else" after the base case? My math is fairly weak please be gentle :)
Any hints how to make use of the fact that the links are sorted?
It's not homework or something that im trying to cheat around from, it's not about the code itself, this has to be a useful tool, the "learning" comes by itself along the way.
here's how a graph looks nodeID, out links, in links for m=7 n=13, (note the 0 cycles is just how the graph is initialized):
0 | 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 3 4 5 6 6 7 8 9
1 | 0 0 0 0 0 0 0 | 2 2 3 4 5 5 8 12
2 | 0 0 0 0 0 1 1 | 3 3 3 3 3 4 4 4 6 7 8 10
3 | 0 1 2 2 2 2 2 | 4 4 5 5 6 6 7 11
4 | 0 1 2 2 2 3 3 | 5 5 6 8 9 10
5 | 0 1 1 3 3 4 4 | 6 7 8 9 9 11 12
6 | 0 0 2 3 3 4 5 | 7 7 7 8 9 9 12
7 | 0 2 3 5 6 6 6 | 8 9 10 11 11 12
8 | 0 1 2 4 5 6 7 | 10 10 10 11 12
9 | 0 4 5 5 6 6 7 | 10 11 11
10 | 2 4 7 8 8 8 9 | 12 12
11 | 3 5 7 7 8 9 9 |
12 | 1 5 6 7 8 10 10 |
Sorry for the agonising long read.
EDIT: Wrong code in the methods, this is what i think is correct now.
Revision of dist nr2, just try and find if theres a path at all:
private int dist(int i, int j) {
int dist = 0, c = 0, count = 0;
boolean linkExists = false;
for (int link : in_neighbours[j]) {
//System.out.print("\nIs "+j+" linked to by "+i);
if (out_neighbours[i].contains(link)) {
//System.out.print(" - yes!");
dist = 1; // there is a direct link
} else {
while ( c < j ) {
// if there's a path from 0 up to j, check if 'i' links to a node which eventually links to 'j'
if (out_neighbours[i].contains(c) &&
(out_neighbours[c].contains(link) || in_neighbours[c].contains(link) )) {
count++; // yes. and this is one node we had to step through to get closer
linkExists = true;
} else {
linkExists = false; // unreachable, the path was interrupted somewhere on the way
break;
}
c++;
}
if (linkExists) {
dist = count-1; // as 2 nodes are linked with 1 edge
} else {
dist = 0; // no path was found
}
}
}
return dist;
}
Since all edges have the same weight in your model, you can use a BFS search to find the shortest path from S to T.
This is an iterative process, starting with set #0, containing only the source node ({S}).
At each step i, you create set #i by finding all nodes achievable from set (i-1) in one step.
The iteration terminates in two cases:
1) When you detect that set #k contains T. In this case you return k-1.
2) When the set is empty, meaning that the two nodes are unreachable.
The memory consumption is about twice the number of nodes, since at each step i you are working with two sets (i-1 and i), bounded by the total number of nodes.
--EDIT--
Here is a possible implementation (I made some tests on it):
private Integer getDist(int i, int j) {
Set<Integer> currentSet = new HashSet<Integer>();
currentSet.add(i);
int dist = 0;
while (true) {
Set<Integer> nextSet = new HashSet<Integer>();
for (Integer currNode : currentSet)
nextSet.addAll(out[currNode]);
if (nextSet.isEmpty())
return null; //i.e. infinite
if (nextSet.contains(j))
return dist;
dist++;
currentSet = nextSet;
}
}
The implementation assumes that in and out are defined as List<Integer>[], and nodes are identified by numbers starting from 0. The minimal distance is counted as the number of intermediate nodes in the path, and not as the number of edges.
The duplicates you have in the lists do not break anything here, but they are irrelevant for the algorithm.