Im attempting to find the shortest path to all the nodes of a graph using the floyd warshall algorithm for a class. I was given the base code for the graph, and have tried implementing the algorithm through pseudocode, but havent figured out how to pick the specific edge based on the iteration im in.
Here is the code for the algorithm. the part that im trying to change is "initialize with adjacency matrix weight values" im not sure how to select that specific edge weight.
public static void FloydWarshall(Graph g) {
int V = g.getvCount();
// to store the calculated distances
float dist[][] = new float[V][V];
// initialize with adjacency matrix weight values
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
for(int k = 0; k<=g.edgeList.size(); k++){
if(g.edgeList.get(i).head.equals(i) && g.edgeList.get(j).tail.equals(j)){
int label = Integer.parseInt(g.edgeList.get(k).label);
dist[i][j] = label;
}}
}
}
// loop through all vertices one by one
for (int k = 0; k < V; k++) {
// pick all as source
for (int i = 0; i < V; i++) {
// pick all as destination
for (int j = 0; j < V; j++) {
// If k is on the shortest path from i to j
if (dist[i][k] + dist[k][j] < dist[i][j]) {
// update the value of dist[i][j]
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
// shortest path matrix
for (int z = 0; z < V; z++) {
for (int j = 0; j < V; j++) {
// if value is infinity
if (dist[z][j] == Float.MAX_VALUE)
System.out.print("INF ");
else
System.out.print(dist[z][j] + " ");
}
System.out.println();
}
And here is the code for the edge
public class Edge implements Comparable<Edge> {
String label;
Node tail;
Node head;
public Edge(Node tailNode, Node headNode, String theLabel) {
setLabel(theLabel);
setTail(tailNode);
setHead(headNode);
}
public String getLabel() {
return label;
}
public Node getTail() {
return tail;
}
public Node getHead() {
return head;
}
public void setLabel(String s) {
label = s;
}
public void setTail(Node n) {
tail = n;
}
public void setHead(Node n) {
head = n;
}
#Override
public int compareTo(Edge edge) {
try {
int edge1 = Integer.parseInt(edge.label);
int edge2 = Integer.parseInt(edge.label);
return Integer.compare(edge1, edge2);
} catch (NumberFormatException e) {
System.out.println(e);
}
return 0;
}
}
Additionally here is the code for the graph class that i have.
import java.util.*;
public class Graph {
ArrayList<Node> nodeList;
ArrayList<Edge> edgeList;
public Graph() {
nodeList = new ArrayList<Node>();
edgeList = new ArrayList<Edge>();
}
public ArrayList<Node> getNodeList() {
return nodeList;
}
public ArrayList<Edge> getEdgeList() {
return edgeList;
}
public void addNode(Node n) {
nodeList.add(n);
}
public void addEdge(Edge e) {
edgeList.add(e);
}
public String toString() {
String s = "Graph g.\n";
if (nodeList.size() > 0) {
for (Node n : nodeList) {
// Print node info
String t = "\nNode " + n.getName() + ", abbrev " + n.getAbbrev() + ", value " + n.getVal() + "\n";
s = s.concat(t);
}
s = s.concat("\n");
}
return s;
}
public void sortNodes(){
Collections.sort(nodeList);
}
private int vCount;
private float[][] adj;
public int getvCount() {
return vCount;
}
public float[][] getAdj() {
return adj;
}
public Graph(int vCount) {
this.vCount = vCount;
adj = new float[vCount][vCount];
for (int i = 0; i < vCount; i++) {
for (int j = 0; j < vCount; j++) {
if (i != j) {
adj[i][j] = Float.MAX_VALUE;
}
}
}
}
public void addEdge(int i, int j, float weight) {
adj[i][j] = weight;
}
public void removeEdge(int i, int j) {
adj[i][j] = Float.MAX_VALUE;
}
public boolean hasEdge(int i, int j) {
if (adj[i][j] != Float.MAX_VALUE && adj[i][j] != 0) {
return true;
}
return false;
}
public List<Integer> neighbours(int vertex) {
List<Integer> edges = new ArrayList<Integer>();
for (int i = 0; i < vCount; i++)
if (hasEdge(vertex, i))
edges.add(i);
return edges;
}
}
You can initialize all cells to be infinity, and then for each cell [i][j] where there is an edge from vertex i to vertex j, set its distance to be the edge weight. You could do this by iterating through all edges afterwards.
// initialize with adjacency matrix weight values
// set all to be initially infinity
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
dist[i][j] = Float.MAX_VALUE;
}
}
// set all edge weights
for(int k = 0; k <= g.edgeList.size(); k++){
Edge e = g.edgeList.get(k);
int i = Integer.parseInt(e.getHead().label);
int j = Integer.parseInt(e.getTail().label);
dist[i][j] = Integer.parseInt(e.getLabel());
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 9 days ago.
Improve this question
I'm trying to implement the A* algorithm in Java in order to solve the 15-Puzzle, but I get an infinite loop and I don't understand why.
I tried with the removal of the openList.clear(); statement, but in this way I get another problem: the tiles begin to do some erroneous movements.
Here is the code of the Board:
public class BoardPrototype implements Prototype, Cloneable {
public Box[][] board;
public int manhattanDistance = 0;
public int g_n = 0;
public final List<Integer> finalList = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0);
#Override
public Object clone() {
try {
BoardPrototype cloned = (BoardPrototype) super.clone();
cloned.board = new Box[board.length][board[0].length];
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
cloned.board[i][j] = new BoxBuilder()
.setX(board[i][j].getX())
.setY(board[i][j].getY())
.setValue(board[i][j].getValue())
.setG_n(board[i][j].getG_n())
.setInitialX(board[i][j].getInitialX())
.setInitialY(board[i][j].getInitialY())
.setManhattanDistance(board[i][j].getManhattanDistance())
.build();
}
}
return cloned;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
#Override
public boolean equals(Object o) {
if (o instanceof BoardPrototype that) {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
if (board[i][j].getValue() != that.board[i][j].getValue())
return false;
}
}
return true;
} else {
return false;
}
}
#Override
public int hashCode() {
int result = Arrays.hashCode(board[0]);
for (int i = 1; i < board.length; i++) {
result = 31 * result + Arrays.hashCode(board[i]);
}
return result;
}
public void setBoard(Box[][] board) {
this.board = board;
}
public void setManhattanDistance(int manhattanDistance) {
this.manhattanDistance = manhattanDistance;
}
public int getManhattanDistance() {
manhattanDistance = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
manhattanDistance += board[i][j].getManhattanDistance();
}
}
return manhattanDistance;
}
public void setG_n(int g_n) {
this.g_n = g_n;
}
public int getG_n() {
return this.g_n;
}
public BoardPrototype swap(int index1, int index2) {
BoardPrototype copy = (BoardPrototype) this.clone();
int row1 = index1 / 4;
int col1 = index1 % 4;
int row2 = index2 / 4;
int col2 = index2 % 4;
copy.board[row1][col1].setManhattanDistance(copy.board[row1][col1].getManhattan(index2, copy.board[row1][col1].getValue()));
copy.board[row2][col2].setManhattanDistance(copy.board[row2][col2].getManhattan(index1, copy.board[row2][col2].getValue()));
copy.board[row1][col1].setValue(copy.board[row2][col2].getValue());
copy.board[row2][col2].setValue(0);
copy.board[row1][col1].setInitialX(copy.board[row2][col2].getInitialX());
copy.board[row2][col2].setInitialX(copy.board[row1][col1].getInitialX());
copy.board[row1][col1].setInitialY(copy.board[row2][col2].getInitialY());
copy.board[row2][col2].setInitialY(copy.board[row1][col1].getInitialY());
copy.board[row1][col1].setG_n(copy.board[row2][col2].getG_n() + 1);
copy.board[row2][col2].setG_n(copy.board[row1][col1].getG_n() + 1);
copy.board[row1][col1].update();
copy.board[row2][col2].update();
return copy;
}
public List<BoardPrototype> neighbors(BoardPrototype board) {
ArrayList<BoardPrototype> neighbors = new ArrayList<>();
int blankIndex = board.getBlankIndex();
int row = blankIndex / 4;
int col = blankIndex % 4;
if (row > 0) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex - 4);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (col > 0) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex - 1);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (row < 3) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex + 4);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (col < 3) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex + 1);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
return neighbors;
}
public int getBlankIndex() {
int index = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(this.board[i][j].getValue() == 0) {
index = i * 4 + j;
}
}
}
return index;
}
public boolean isSolved() {
int count = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(board[i][j].getValue() == finalList.get(count)) {
count++;
if (count == 16) {
return true;
}
} else {
return false;
}
}
}
return false;
}
}
And this one is the code of the class that implements the A* algorithm:
public class Game15Solver {
private static Game15Solver game15Solver;
ManhattanComparator manhattanComparator = new ManhattanComparator();
private Game15Solver() {}
public static Game15Solver getInstance() {
if(game15Solver == null) {
game15Solver = new Game15Solver();
}
return game15Solver;
}
public List<BoardPrototype> AStar(BoardPrototype board) {
PriorityQueue<BoardPrototype> openList = new PriorityQueue<>(manhattanComparator);
List<BoardPrototype> closeList = new ArrayList<>();
openList.add(board);
while (!openList.isEmpty()) {
BoardPrototype current = openList.poll();
closeList.add(current);
openList.clear();
if (current.isSolved()) {
System.out.println("Solved");
} else {
for (BoardPrototype neighbor : current.neighbors(current)) {
if (!closeList.contains(neighbor)) {
if(!openList.contains(neighbor)) {
neighbor.setG_n(current.getG_n() + 1);
openList.add(neighbor);
} else {
var tmpList = (Arrays.asList(openList.toArray()));
int ind = tmpList.indexOf(neighbor);
BoardPrototype boardPrototype = (BoardPrototype) tmpList.get(ind);
if(neighbor.getG_n() + 1 < boardPrototype.getG_n()) {
openList.remove(neighbor);
neighbor.setG_n(current.getG_n() + 1);
openList.add(neighbor);
}
}
}
}
}
}
return closeList;
}
}
Do you know how can I solve this problem? Thank you.
I am trying to write a code of adjacency list implementation of the graph ADT.
private ArrayList<LinkedList<Integer>> adjLists ;
but I don't know how to iterate through the vertices of the graph...
errr... You just go through every elements...
for(int i = 0;i<adjLists.size();i++){
for(int j = 0;j<adjLists.size();j++){
int element = adjLists.get(i).get(j);
//Then do whatever you want
}
}
Here's a complete Graph class implemented using ArrayList<LinkedList>
import java.util.*;
public class Graphs {
private ArrayList<LinkedList<Integer>> list;
public Graphs(int vertices) {
list = new ArrayList<>(vertices);
for (int i = 0; i < vertices; i++) {
list.add(i, new LinkedList<>());
}
}
public void addEdge(int v1, int v2) {
list.get(v1).add(v2);
list.get(v2).add(v1);
}
public void print() {
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.get(0).size(); j++) {
System.out.print(list.get(i).get(j) + " -> ");
}
System.out.print("null");
System.out.println("");
}
}
public void bfs(int soucevertex) {
ArrayList<Boolean> visited = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
visited.add(false);
}
Queue<Integer> queue = new LinkedList<>();
queue.add(soucevertex);
visited.set(soucevertex, true);
while (!queue.isEmpty()) {
for (int i = 0; i < list.get(queue.peek()).size(); i++) {
if (visited.get(list.get(queue.peek()).get(i)) == false) {
visited.set(list.get(queue.peek()).get(i), true);
queue.add(list.get(queue.peek()).get(i));
}
}
System.out.print(queue.poll() + " ");
}
}
public void dfs(int sourcevertex) {
ArrayList<Boolean> visited = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
visited.add(false);
}
dfsutil(sourcevertex, visited);
}
private void dfsutil(int source, ArrayList<Boolean> visited) {
visited.set(source, true);
System.out.print(source + " ");
for (int i = 0; i < list.get(source).size(); i++) {
if (visited.get(list.get(source).get(i)) == false) {
dfsutil(list.get(source).get(i), visited);
}
}
}
}
The code still error, even though I have already fixed almost half the program
this initialized at main class:
Getting the below error:
Exception in thread "main"
java.lang.NullPointerException
at Tugas7.No3.seqSearch(No3.java:72)
at Tugas7.No3Main.main(No3Main.java:27)
what are you expecting to get out?
I excepting the code when run can search the number
package Tugas7;
public class No3 {
public int[] data;
public int jumData,min,max;
;
public int baris, kolom, posisiBar, posisiKol, posisi;
public void No3(int[] data) {
sort(data, 0, 8);
}
private void merge(int[] data, int left, int middle, int right) {
int[] temp = new int[data.length];
for (int i = left; i <= right; i++) {
temp[i] = data[i];
}
int a = left;
int b = middle + 1;
int c = left;
while (a <= middle && b <= right) {
if (temp[a] <= temp[b]) {
data[c] = temp[a];
a++;
} else {
data[c] = temp[b];
b++;
}
c++;
}
int s = middle - a;
for (int i = 0; i <= s; i++) {
data[c + i] = temp[a + i];
}
}
private void sort(int data[], int left, int right) {
if (left < right) {
int middle = (left + right) / 2;
sort(data, left, middle);
sort(data, middle + 1, right);
merge(data, left, middle, right);
}
}
public void printArray(int arr[]) {
int n = arr.length;
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public int[] Searching(int[] Data, int jmlData) {
this.jumData = 10;
data = new int[jumData];
for (int i = 0; i < jumData; i++) {
data[i] = Data[i];
}
return data;
}
public int seqSearch(int cari) {
this.posisi = -1;
for (int j = 0; j < 11; j++) {
if (data[j] == cari) {
posisi = j;
break;
}
}
return posisi;
}
public void TampilData() {
for (int i = 0; i < 10; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
public void searchMax(int[] data) {
min = data[0];
max = data[0];
for (int i = 0; i < 10; i++) {
if (data[i] < min) {
min = data[i];
} else if (data[i] > max) {
max = data[i];
}
}
}
}
I have implemented AdjacencyMatrix in java, but I am having hard time implementing the distance() method to be able to find the distance between two nodes.
Any idea how I an do that?
I have tried a lot of things but I don't seem to be able to get right answer.
Here's my implementation
public class AdjacencyMatrix implements Representation {
private Node[] nodes;
private int[][] adjacencyMatrix;
private int numberOfNodes =0;
public AdjacencyMatrix(File file) {
Scanner inFile;
int numNodes;
try {
inFile = new Scanner(file);
numNodes = Integer.parseInt(inFile.nextLine());
adjacencyMatrix = new int[20][20];
nodes = new Node[20];
String[] line;
while (inFile.hasNextLine()) {
line = inFile.nextLine().split(":");
Node from = new Node(Integer.parseInt(line[0]));
Node to = new Node(Integer.parseInt(line[1]));
int value = Integer.parseInt(line[2]);
if(!Arrays.asList(nodes).contains(from))
addNode(from);
if(!Arrays.asList(nodes).contains(to))
addNode(to);
addEdge(new Edge(from, to, value));
}
} catch (FileNotFoundException e) {
System.out.print(e.getCause());
}
}
public AdjacencyMatrix() {
}
#Override
public boolean adjacent(Node x, Node y) {
int fromIndex = findIndex(x);
int toIndex = findIndex(y);
if(adjacencyMatrix[fromIndex][toIndex] == 1 || adjacencyMatrix[toIndex][fromIndex] ==1){
return true;
}
return false;
}
#Override
public List<Node> neighbors(Node x) {
ArrayList<Node> neighbors = new ArrayList<>();
int fromIndex = findIndex(x);
if(x.getData().toString().equals("4")) {
System.out.println("FromIndex is: " + fromIndex);
}
if(x.getData().toString().equals("4")){
for(int i =0; i < nodes.length; ++i){
System.out.println(nodes[i] + " ");
}
}
for (int i = 0; i <= numberOfNodes; i++){
if(adjacencyMatrix[fromIndex][i] == 1){
neighbors.add(nodes[i]);
if(x.getData().toString().equals("4")) {
System.out.println("Match!: " + i);
System.out.println("Adding NODE: " + nodes[i]);
}
}
}
int [] nums = new int[neighbors.size()];
for(int i =0; i < nums.length; ++i){
nums[i] = Integer.parseInt(neighbors.get(i).getData().toString());
}
Arrays.sort(nums);
ArrayList<Node> newNeighbors = new ArrayList<>();
for(int i =0; i < nums.length; ++i){
newNeighbors.add(new Node(nums[i]));
}
return newNeighbors;
}
#Override
public boolean addNode(Node x) {
if(Arrays.asList(nodes).contains(x)){
return false;
}
nodes[numberOfNodes] = x;
for (int i = 0; i <= numberOfNodes; i++){
adjacencyMatrix[numberOfNodes][i] = 0;
adjacencyMatrix[i][numberOfNodes] = 0;
}
numberOfNodes++;
return true;
}
#Override
public boolean removeNode(Node x) {
if (!Arrays.asList(nodes).contains(x)) {
return false;
}
for (int k = 0; k < numberOfNodes; k++) {
if (x.equals(nodes[k])) {
//decrement the number of nodes
numberOfNodes--;
for (int i = k; i < numberOfNodes; i++) {
nodes[i] = nodes[i + 1];
}
for (int i = k; i < numberOfNodes; i++) {
for (int j = 0; j <= numberOfNodes; j++) {
adjacencyMatrix[i][j] = adjacencyMatrix[i + 1][j];
}
}
for (int i = k; i < numberOfNodes; i++) {
for (int j = 0; j < numberOfNodes; j++) {
adjacencyMatrix[j][i] = adjacencyMatrix[j][i + 1];
}
}
}
//
}
return true;
}
#Override
public boolean addEdge(Edge x){
int from = Integer.parseInt(x.getFrom().getData().toString());
int to = Integer.parseInt(x.getTo().getData().toString());
int fromIndex = findIndex(x.getFrom());
int toIndex = findIndex(x.getTo());
if(from == 4){
System.out.println("Adding adjecent to 4 -> " + to);
}
if(adjacencyMatrix[fromIndex][toIndex] == 1 ){
return false;
}
adjacencyMatrix[fromIndex][toIndex] = 1;
return true;
}
#Override
public boolean removeEdge(Edge x) {
int from = Integer.parseInt(x.getFrom().getData().toString());
int to = Integer.parseInt(x.getTo().getData().toString());
int fromIndex = findIndex(x.getFrom());
int toIndex = findIndex(x.getTo());
if(adjacencyMatrix[fromIndex][toIndex] == 0 && adjacencyMatrix[toIndex][fromIndex] ==0){
return false;
}
adjacencyMatrix[fromIndex][toIndex] = 0;
return true;
}
#Override
public int distance(Node from, Node to) {
return 0;
}
#Override
public Optional<Node> getNode(int index) {
return null;
}
#Override
public Collection<Node> getNodes() {
return Arrays.asList(nodes);
}
public int findIndex(Node node)
{
for (int i = 0; i < numberOfNodes; ++i)
if (nodes[i].equals(node))
return i;
return -1;
}}
All my methods are working except distance().
I am returning 0 in the distance() method since I don't know how to implement it correctly.
Any help would be greatly appreciated.
I figured it out.
Basically I made an array to keep track of my Edges:
private Edge [] edges;
Then I populated the array with my graph edges.
Now, in my distance method I just find the edge with the give To and From Nodes, and extract it's value which is the distance I'm looking for :)
public int distance(Node from, Node to) {
for(Edge edge: edges){
if(edge.getFrom().equals(from) && edge.getTo().equals(to)){
return edge.getValue();
}
}
return 1;
}
I must have thought about this simple solution earlier!
I think I have most of the code figured out, there is just one part that is giving me grief. When I use printList(list) it prints out 1, 2, 3,... up to 9 when it is supposed to be printing the squares of these numbers. If I print out the createSquaresList(10) it is correctly printed. Any help is appreciated :-).
import java.util.*;
public class Lab8a
{
public static void main(String args[])
{
ArrayList<Double> list = createSquaresList(10);
printList(list);
removeElement(list, 4);
printList(list);
swapElements(list, 2, 6);
printList(list);
double max = getMaxValue(list);
double ave = getAverage(list);
System.out.println("Max Value = " + max);
System.out.println("Average = " + ave);
int idx1 = linearSearch(list, 4);
int idx2 = linearSearch(list, 75);
System.out.println("idx 1 = " + idx1);
System.out.println("idx 2 = " + idx2);
}
public static ArrayList<Double> createSquaresList(int n)
{
ArrayList<Double> squares= new ArrayList<>();
double s = 0.0;
for (double i = 0.0; i <= n-1; i++)
{
s = i*i;
squares.add(s);
}
return squares;
}
public static double getMaxValue(ArrayList<Double> list)
{
double largest = list.get(0);
for (int i = 1; i < list.size(); i++)
{
if (list.get(i) > largest)
{
largest = list.get(i);
}
}
return largest;
}
public static double getAverage(ArrayList<Double> list)
{
double avg = 0.0;
double sum = 0.0;
for (int i =0; i < list.size(); i++)
{
sum += list.get(i);
}
avg = sum / list.size();
return avg;
}
public static void removeElement(ArrayList<Double> list, double index)
{
double temp = 0.0;
int lastPos = list.size() - 1;
double last = list.get(lastPos);
index = temp;
temp = last;
last = index;
list.remove(lastPos);
}
public static void swapElements(ArrayList<Double> list, int a, int b)
{
int temp = 0;
a = temp;
temp = b;
b = a;
}
public static int linearSearch(ArrayList<Double> list, double val)
{
int pos = 0;
boolean found = false;
while (pos < list.size() && !found)
{
if (list.get(pos) == val)
{
found = true;
}
else
{
pos++;
}
}
if (found)
{
return pos;
}
else
{
return -1;
}
}
public static void printList(ArrayList<Double> list)
{
for(int i = 0; i < list.size(); i++)
{
System.out.print(i);
if(i < list.size()-1)
{
System.out.print(", ");
}
}
System.out.println("");
}
}
Change
System.out.print(i);
to
System.out.print(list.get(i));
it is because you are print the int not the contents of the list,
try changing the 3 line of the function printList to:
System.out.print(list.get(i));