Eight Queens Algorithm for Different Starting Points - java

I am trying to find a solution to the Eight Queens problem regardless of the starting point. Below is my Solver class, however it doesn't work for some reason when I place the queen in a row other than the first one.
import java.util.*;
public class Queens {
private static int x;
private static int y;
private static ArrayList<Integer> rows = new ArrayList<Integer>();
public Queens(int index, int row, int pos) {
for (int i = 0; i<index; i++)
rows.add(i);
rows.remove(row);
x = pos;
y = row;
}
public static boolean solve(int row, int[][] board, int N, int pos) {
board[y][x] = 1;
System.out.println("row: " + row);
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 8; j++) {
if(board[i][j]==1) System.out.print("Q ");
else System.out.print("* ");
}
System.out.println();
}
System.out.println();
if(row>=N-1) return true;
for(int position = pos; position < N; position++) {
if(isValid(board, rows.get(row), position, N)) {
board[rows.get(row)][position] = 1;
if(!solve(row+1, board, N, 0)) {
board[rows.get(row)][position] = 0;
} else
return true;
}
}
return false;
}
public static boolean isValid(int[][] board, int y, int x, int N) {
int i, j;
for(i = 0; i < y; i++)
if(board[i][x]==1)
return false;
i = y - 1;
j = x - 1;
while((i>=0)&&(j>=0))
if(board[i--][j--]==1) return false;
i = y - 1;
j = x + 1;
while((i>=0)&&(j<N))
if(board[i--][j++]==1) return false;
return true;
}
}
For example, when I place the initial queen on board[2][2], this is the solution I get:
Q * * * * * * *
* * Q * * * * *
* * Q * * * * *
* * * * * Q * *
* * * * * * * Q
* Q * * * * * *
* * * Q * * * *
* * * * * * Q *
What is wrong with the code? Why does it disregard the initial piece? Thanks in advance.

What are the bounds for the for loop in isValid? Do they prevent you from placing a queen into a column where there's another queen below?
A similar question applies also to the while loops -- can they detect that there's a queen on the diagonal but below the one you're placing now?

Related

How do I move the star into the place it belongs

That is my homework assignment in the link above. This is what I did so far:
import java.util.Scanner;
public class Bowling {
public static void recursionPins(int n, int t) {
if (n == 1) {
System.out.print("\t\t");
for (int i = 1; i <= t - 1; i++)
System.out.print(" ");
System.out.println("*");
} else {
recursionPins(n - 1, t);
for (int i = 1; i <= t - n; i++)
System.out.print(" ");
for (int i = 1; i <= n; i++)
System.out.print("* ");
System.out.println();
}
}
// main method
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter number of rows of pins: ");
int n = scan.nextInt();
recursionPins(n, n);
}
}
When I run it, the first * is out of place and I'm not sure what the error is. The link below is a sample run of the program.
Enter number of rows of pins: 10
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
* * * * * * * * * *
I'm not sure how to move the star over.
Here in the base case:
if (n == 1) {
System.out.print("\t\t");
for (int i = 1; i <= t - 1; i++)
System.out.print(" ");
System.out.println("*");
}
You are printing two tabs and the required number of spaces. You need to remove System.out.print("\t\t");:
if (n == 1) {
for (int i = 1; i <= t - 1; i++)
System.out.print(" ");
System.out.println("*");
}
Output:
Enter number of rows of pins: 5
*
* *
* * *
* * * *
* * * * *

Neural Network bad convergeance

I read a lot about NN last two weeks, I think i saw pretty much every "XOR" approach tutorials on net. But, i wasn't able to make work my own one. I started by a simple "OR" neuron approach. Giving good results. I think my problem is in backpropagation implementation. I did an object approach, so here are the main lines.
Three classes :
Neuron
public class Neuron {
/*
* Attributes
*/
double[] inputs;
double[] weights;
double output;
double error;
double delta;
double deltaWeight;
/*
* Constructors
*/
public Neuron(int nInputs)
{
inputs = new double[nInputs + 1];
inputs[inputs.length - 1] = 1; // bias
weights = new double[nInputs + 1];
}
/*
* Methods
*/
/**
* Reset all weights of the neuron to random values between -1 and 1
*/
public void reset()
{
Random random = new Random();
for (int i = 0; i < weights.length; i++)
weights[i] = (random.nextDouble() * ((0.5d - (-0.5d))) + (-0.5d));
}
/**
* Compute output for given inputs
* #param inputs
*/
public void computeOutput(double inputs[])
{
setInputs(inputs);
output = Sigmoid.activation(getDotProduct());
}
/**
* Compute error for given ideal
* #param ideal
*/
public void computeError(double ideal)
{
error = ideal - output;
delta = error;
}
/**
* Compute error for hidden neurons
*/
public void computeError(FeedForwardLayer previousLayer, int position)
{
double sum = 0;
for (int i = 0; i < previousLayer.neurons.length; i++)
sum += (previousLayer.neurons[i].delta * previousLayer.neurons[i].weights[position]);
delta = Sigmoid.derivative(getDotProduct()) * sum;
error = delta;
}
/**
* Adjust every weight of the neuron
*/
public void adjustWeights(double lambda, double momentum)
{
for (int i = 0; i < weights.length; i++)
{
double lastDeltaWeight = deltaWeight;
deltaWeight = lambda * (delta * inputs[i]) + momentum * lastDeltaWeight;
weights[i] += deltaWeight;
}
}
#Override
public String toString()
{
String str = "";
for (int i = 0; i < weights.length; i++)
str = str.concat(String.format("IN|W --> %.6f | %.6f \n", (float) inputs[i], (float) weights[i]));
str = str.concat("Output = " + output + "\n");
str = str.concat("Error = " + error + "\n");
return str;
}
/*
* Getters & Setters
*/
/**
* #return weights * inputs + bias
*/
public double getDotProduct()
{
double sum = 0;
for (int i = 0; i < inputs.length; i++)
sum += (weights[i] * inputs[i]);
return sum;
}
/**
* Set inputs (keep bias input)
* #param inputs
*/
public void setInputs(double[] inputs)
{
for (int i = 0; i < inputs.length; i++)
this.inputs[i] = inputs[i];
}
/**
* Set every weight to a single value
* #param weight
*/
public void setWeights(double weight)
{
for (int i = 0; i < weights.length; i++)
this.weights[i] = weight;
}
}
FeedForwardLayer (which contain neurons)
public class FeedForwardLayer {
/*
* Attributes
*/
Neuron[] neurons;
LayerTypes type;
/*
* Constructors
*/
/**
* First layer constructor
* #param nNeurons
*/
public FeedForwardLayer(int nInputs, int nNeurons, LayerTypes type)
{
neurons = new Neuron[nNeurons];
for (int i = 0; i < neurons.length; i++)
neurons[i] = new Neuron(nInputs);
this.type = type;
}
/*
* Methods
*/
/**
* Reset all weights of the layer's neurons to random values between -1 and 1
*/
public void reset()
{
for (Neuron neuron : neurons)
neuron.reset();
}
/**
* Compute output, if layer isn't input one, you can pass null into parameter
* #param inputs
*/
public void computeOutputs(double[] inputs)
{
for (int i = 0; i < neurons.length; i++)
neurons[i].computeOutput(inputs);
}
/**
* Compute error, if layer is output one
* #param ideals
*/
public void computeErrors(double[] ideals)
{
for (int i = 0; i < neurons.length; i++)
neurons[i].computeError(ideals[i]);
}
/**
* Compute error, if layer isn't output one
* #param layer n+1
*/
public void computeErrors(FeedForwardLayer next)
{
for (int i = 0; i < neurons.length; i++)
neurons[i].computeError(next, i);
}
/**
* Adjust weights for every neurons
*/
public void adjustWeights(double lambda, double momentum)
{
for (Neuron neuron : neurons)
neuron.adjustWeights(lambda, momentum);
}
#Override
public String toString()
{
String str = "";
for (int i = 0; i < neurons.length; i++)
str = str.concat("Neuron " + i + "\n" + neurons[i]);
return str;
}
/*
* Getters - Setters
*/
/**
* #return true if layer is input, false otherwise
*/
public boolean isInput()
{
if (type == LayerTypes.INPUT)
return true;
return false;
}
/**
* #return true if layer is input, false otherwise
*/
public boolean isOutput()
{
if (type == LayerTypes.OUTPUT)
return true;
return false;
}
/**
* #return an array of layer's outputs
*/
public double[] getOutputs()
{
double[] outputs = new double[neurons.length];
for (int i = 0; i < neurons.length; i++)
outputs[i] = neurons[i].output;
return outputs;
}
/**
* #return array of layer's errors
*/
public double[] getErrors()
{
double[] errors = new double[neurons.length];
for (int i = 0; i < neurons.length; i++)
errors[i] = neurons[i].error;
return errors;
}
/**
* Set all the weights of the layer to given weight
* #param weight
*/
public void setWeights(double weight)
{
for (int i = 0; i < neurons.length; i++)
neurons[i].setWeights(weight);
}
}
FeedForwardNetwork (which contain FeedForwardLayers)
public class FeedForwardNetwork {
static final double lambda = 0.1;
static final double momentum = 0;
/*
* Attributes
*/
private ArrayList<FeedForwardLayer> layers;
/*
* Constructors
*/
public FeedForwardNetwork()
{
layers = new ArrayList<FeedForwardLayer>();
}
/*
* Methods
*/
/**
* Init all the weights to random values
*/
public void reset()
{
for (int i = 0; i < layers.size(); i++)
layers.get(i).reset();;
}
/**
* Compute output for all the neurons of all the layers for given inputs
* #param inputs
*/
public void feedForward(double[] inputs)
{
//System.err.println("FeedForwardNetwork.feedForward(" + inputs[0] + ", " + inputs[1] +")");
for (int i = 0; i < layers.size(); i++)
{
//System.err.println("\n*** COMPUTING OUTPUT FOR LAYER " + i + "***\n");
if (layers.get(i).isInput())
layers.get(i).computeOutputs(inputs);
else
layers.get(i).computeOutputs(layers.get(i - 1).getOutputs());
}
}
/**
* Compute errors for all the neurons of all the layers starting by output layer
* #param ideals
*/
public void feedBackward(double[] ideals)
{
//System.err.println("FeedForwardNetwork.feedBackward(" + ideals[0] + ")");
// For each layers starting by output one
for (int i = layers.size() - 1; i > 0; i--)
{
//System.err.println("*** COMPUTING ERROR FOR LAYER " + i + "***");
if (layers.get(i).isOutput())
layers.get(i).computeErrors(ideals);
else
layers.get(i).computeErrors(layers.get(i + 1));
}
}
/**
* Adjust weights of every layer
*/
public void adjustWeights()
{
for (FeedForwardLayer feedForwardLayer : layers)
feedForwardLayer.adjustWeights(lambda, momentum);
}
/**
* Train the nn with given inputs and outputs
* #param inputs
* #param outputs
*/
public void train(double[] inputs, double... outputs)
{
feedForward(inputs);
feedBackward(outputs);
adjustWeights();
}
/**
* Add a layer to the network
* #param layer
*/
public void addLayer(FeedForwardLayer layer)
{
layers.add(layer);
}
#Override
public String toString()
{
String str = "";
for (int i = 0; i < layers.size(); i++)
str = str.concat("Layer " + LayerTypes.values()[i] + "\n" + layers.get(i));
str = str.concat("\n");
str = str.concat("OUTPUT = " + getOutputs()[0] + "\n");
str = str.concat("ERROR = " + getError(false) + "\n");
return str;
}
/*
* Getters & Setters
*/
public FeedForwardLayer getInputLayer()
{
return layers.get(0);
}
public FeedForwardLayer getOutputLayer()
{
return layers.get(layers.size() - 1);
}
public FeedForwardLayer getLayer(int index)
{
return layers.get(index);
}
public double getError(boolean abs)
{
if (abs)
return Math.abs(getOutputLayer().neurons[0].error);
return getOutputLayer().neurons[0].error;
}
public double[] getOutputs()
{
return getOutputLayer().getOutputs();
}
}
So i train the network by giving it epoch of the xor table
XOR table
X | Y | S
0 0 0
0 1 1
0 1 1
0 0 0
The network will output after thousands epoch approximately 0.5...
Interesting fact is, if i replace the training set by a AND table, a OR table or an NAND table, the nn will output the number of 1 in the S column of the training set.. (it will output 0.25 for AND and NAND table and 0.75 for OR table)
I just want to know if my implementation is good enough to make it work, ty !
So, after some research, i realized that my implementation was good, except that I didn't understand how the input layer works. That was it, the input layer works like In = Out

Conways Game of life - All Cells dead in the visualiser

For a school project I have to complete a Conways game of life with recourse to some provided skeleton code.
My problem is that all of my cells seem to initialise as dead (and thus do not come alive) when I use the visualiser - I'm not looking for direct answer on the whole project, just some direction on where my code is broken (Apologise for the awful formatting, its my first time on here):
Below is the Cell.class and below that is the CellGrid - the visualiser was provided.
package simulation;
/**
* This class represents a single Cell in the grid.
*
* Complete this class as part of the core of the assessment.
* You must implement the constructor, isAlive, setAlive and isAliveNextStep.
*/
public class Cell
{
// true if the cell is alive and false if it is dead
private boolean alive;
/**
* Cell constructor - all cells should start out dead
*/
public Cell()
{
alive = false;
}
/**
* Accessor method for alive
*
* #return true if the cell is currently alive; false otherwise
*/
public boolean isAlive()
{
if (alive == true)
{
return true;
}
else
return false;
}
/**
* Mutator method for alive
*
* #param alive - the new state of the cell
*/
public void setAlive(boolean alive)
{
if (alive == true)
alive = false;
else alive = true;
}
/**
* Determine whether this cell should be alive in the next step,
* given the number of surrounding neighbours.
*
* See the assignment specification sheet to determine the rules
* for living and dead cells.
*
* #param numNeighbours - the number of living cells surrounding this cell
* #return true if the cell should be alive; false otherwise
*/
public boolean isAliveNextStep(int numNeighbours)
{
if (numNeighbours <= 2)
return false;
if (numNeighbours == 3)
return true;
if (numNeighbours == 4 && alive == true)
return true;
if (numNeighbours == 5)
return false;
if (numNeighbours > 5)
return true;
else return false;
}
}
CellGrid class:
package simulation;
/**
* This class represents an n x n grid of Cells.
*
* Complete this class as part of the core of the assessment.
* You must implement the constructor, simulateStep, isValidCoordinate,
* countNeighbours, getCell and setCell.
*/
public class CellGrid
{
// Store the cells of the game in this 2D array
private Cell[][] cells;
/**
* Constructor for a CellGrid. Populates the grid with cells that will be
* either living or dead. Consider using Math.random() in order to generate
* random numbers between 0.0 and 1.0, in conjunction with lifeChance.
*
* #param size - the size of the grid will be size x size
* #param lifeChance - the probability of each cell starting out
* alive (0.0 = 0%, 1.0 = 100%)
*/
public CellGrid(int size, double lifeChance)
{
cells = new Cell[size][size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
cells[i][j] = new Cell();
if (Math.random() < lifeChance);
{
cells[i][j].setAlive(false);
}
}
}
}
/**
* Run one step in the simulation. This has 2 stages in the following order:
*
* 1. (Core) Update all cells in the grid according to the rules given in the
* assignment specification sheet.
*
* 2. (Extension) Evolve the cells by calculating their new genes - also
* see the assignment specification sheet.
*/
public void simulateStep()
{
for (int i = 0; i < cells.length; i++)
{
for (int j = 0; j < cells.length; j++)
{
int Neighbours = countNeighbours(i, j);
cells[i][j].isAliveNextStep(Neighbours);
}
}
}
/**
* Check if the given coordinates are inside the grid of cells.
*
* #param x - the x coordinate (column) of the cell
* #param y - the y coordinate (row) of the cell
* #return true if the given coordinates are inside the grid of cells; false
* otherwise.
*/
public boolean isValidCoordinate(int x, int y)
{
int validc = 0; //*variable to check for validity of coordinate by traversal *//
for (int i = 0; i < cells.length; i++)
{
for (int j = 0; j > cells.length; j++)
{
if (x == i+1 && y == j+1)
{
validc = 1;
}
}
}
if (validc == 1)
{
return true;
}
else return false;
}
/**
* Count the number of living neighbours in the 8 cells surrounding the
* given coordinates.
*
* #param x - the x coordinate (column) of the cell
* #param y - the y coordinate (row) of the cell
* #return the number of living neighbours of the cell at the given
* coordinates; or 0 if the coordinates are invalid.
*/
public int countNeighbours(int x, int y)
{
int N = 0;
for (int i = 0; i < cells.length; i++)
{
for (int j = 0; j > cells.length; j++)
{
if (i-1 >= 0 && j-1 >= 0 && cells[i-1][j-1].equals(true))
N++;
if (i-1 >= 0 && cells[i-1][j].equals(true))
N++;
if (i-1 >= 0 && j+1 <= cells.length && cells[i-1][j+1].equals(true))
N++;
if (i >= 0 && j-1 >=0 && cells[i][j-1].equals(true))
N++;
if (i >= 0 && j >= 0 && cells[i][j].equals(true))
N++;
if (i >= 0 && j+1 <= cells.length && cells[i][j+1].equals(true))
N++;
if (i+1 <= cells.length && j-1 >= 0 && cells[i+1][j-1].equals(true))
N++;
if (i+1 <= cells.length && j >= 0 && cells[i+1][j].equals(true))
N++;
if (i+1 <= cells.length && j+1 <= cells.length && cells[i+1][j+1].equals(true))
N++;
}
}
return N;
}
/**
* Get the cell at the given coordinates.
*
* #param x - the x coordinate (column) of the cell
* #param y - the y coordinate (row) of the cell
* #return the cell at the given coordinates; or null if the coordinates are
* invalid
*/
public Cell getCell(int x, int y)
{
if (x < cells.length && y < cells.length)
return cells[x][y];
else return null;
}
/**
* Set the cell at the given coordinates to the cell provided, if the
* coordinates are valid.
*
* #param x - the x coordinate (column) of the cell
* #param y - the y coordinate (row) of the cell
* #param cell - the new cell to put at the coordinates given.
*/
public void setCell(int x, int y, Cell cell)
{
cells[x][y] = getCell(x,y);
}
}
Your setAlive method is incorrect.
public void setAlive(boolean alive){
if (alive == true)
alive = false;
else alive = true;
}
Due to variable shadowing, you never really change the field alive. It should look like this:
public void setAlive(boolean alive){
this.alive = alive;
}

2 Dimensional Arrays (Java) - Printing a Triangle with Alphabets in Cyclic order

The query was to write a Java method which prints the following triangle based on the input given (of the number of alphabets, on each side of the triangle).
public void triangle(int side);
Output expected:
triangle(3)
* * A * *
* F * B *
E * D * C
triangle(4)
* * * A * * *
* * I * B * *
* H * * * C *
G * F * E * D
I've come up with a method which does just that, but the code that I've written with my limited experience is with more number of for loops. Can any of you can review my code and come up with suggestions or optimized code for the same problem?
public void triangle(int input) {
int x = input;
int y = 2 * input - 1;
int mid = y / 2;
char character = 'A';
String[][] partitionArray1 = new String[x][y];
\\Following for loop will add letters on the side-1
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
if (i + mid == j) {
partitionArray1[i][j] = "" + character++;
} else {
partitionArray1[i][j] = "*";
}
}
}
\\Following for loop will add letters on the side-2 (horizontal)
for (int j = y - 2; j >= 0; j--) {
j--;
if (j >= 0) {
partitionArray1[x - 1][j] = "" + character++;
} else {
break;
}
}
\\Following for loop will add letters on the side-3
for (int i = x - 2; i >= 0; i--) {
for (int j = 0; j < y; j++) {
if ((i == mid - j) && (j < mid)) {
partitionArray1[i][j] = "" + character++;
}
}
}
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
System.out.print(partitionArray1[i][j] + "");
}
System.out.println();
}
}
Is there an algorithm available to answer such problems?
Try:
public static void triangle(int n) {
for (int i = 0; i < n; ++i) {
if (i == n-1) {
for (int j = 0; j < 2*n-1; ++j)
if (j % 2 == 0)
System.out.printf("%c ", 'A' + 2*n-2-j/2);
else
System.out.printf("* ");
System.out.println();
break;
}
for (int j = 0; j < 2*n-1; ++j) {
if (j == n-1+i)
System.out.printf("%c ", 'A'+i);
else if (j == n-1-i)
System.out.printf("%c ", 'A'+3*n-i-3);
else
System.out.printf("* ");
}
System.out.println();
}
}
The idea is to print row #n separately from the other. The rest of the row have exactly two element(except the first one which is a degenerated case) symmetrical with respect the center.
triangle(9);
* * * * * * * * A * * * * * * * *
* * * * * * * X * B * * * * * * *
* * * * * * W * * * C * * * * * *
* * * * * V * * * * * D * * * * *
* * * * U * * * * * * * E * * * *
* * * T * * * * * * * * * F * * *
* * S * * * * * * * * * * * G * *
* R * * * * * * * * * * * * * H *
Q * P * O * N * M * L * K * J * I
I was bored so i did it with one array
public static void mimi(int size){
int sizetab=size*size*2;
char res[] = new char[sizetab];
Arrays.fill(res,'*');
int pos=size-1;
int JumpGoRight=(2*size)+1;
int JumpGoLeft=2;
char letter='A';
boolean changed = false;
int nbLetters = size -1;
for (int s=size;s>1;s--)
nbLetters+=2;
int i=0;
while(i<(size-1)){
res[pos]=letter++;
pos+=JumpGoRight;
i++;
}
int limit=(sizetab-(size*2))+1;
while(i<nbLetters){
res[pos]=letter++;
pos-=JumpGoLeft;
if( !changed && (pos<limit) ){
JumpGoLeft=(size*2)-1 ;
changed=true;
}
i++;
}
int index = 0;
int doublesize=size*2;
for(char c: res){
if( ((++index)%doublesize)==0)
System.out.print('\n');
else
System.out.print(c);
}
}

Finding Shortest Path of Graph and print Routing Table

This is for a data structures class in java, and I need to create a graph that reads text input, converts this information into a graph, and from there print the adjacency list and print a max spanning tree, which I have done. However, the final aspect is to
The full routing table that your program must produce will have for every pair [i,j] (i != j) of computers in the network, the first computer on an optimum route from i to j. If i and j have a direct connection, then j will be the result (table entry) for that route (pair [i,j]). If the optimum route from i to j is i -> a -> b -> j, then a will be the result (table entry) for that route. One could then construct the route by looking at the value from [i,j] (=a), then [a,j] (=b), then [b,j] (=j).
So basically Dijksta's algorithm. However, I cannot use any Java APIs that deal with graphs (all others are allowed). So far I have
import java.util.ArrayList;
//import java.util.Stack;
public class Graph2 {
ArrayList<Vertex> vert = new ArrayList<Vertex>();
private static int counter = 0;
private int edges;
private Edge[] allEdges = new Edge[50];
private class Vertex{
String ip;
private int id;
ArrayList<Edge> nb = new ArrayList<Edge>();
/**
* Constructor for Vertex
* #param String of IP
*/
public Vertex(String s){
ip = s;
id = counter;
counter++;
}
/**
* Gets the ID of a vertex
* #return unique ID
*/
public int getId(){
return id;
}
/*
public boolean isSame(Vertex v){
if(this.ip.equals(v.getIp()))
return true;
else
return false;
}
*/
/**
* Gets the IP of a vertex
* #return the IP of the vertex
*/
public String getIp(){
return this.ip;
}
/**
* Adds an edge to nb
* #param edge to be added
*/
public void addList(Edge e){
nb.add(e);
}
/**
* Determines if an edge exists
* #param edge to be checked
* #return true if exists, false if not
*/
public boolean exists(Edge e){
if(nb.indexOf(e) != -1){
return true;
}
else
return false;
}
/**
* Gets the size of an edge
* #return size of edge
*/
public int edgeSize(){
return nb.size();
}
/**
* Gets the edges
* #return String of edges
*/
public String getEdges(){
String all = "";
Edge e;
for(int i = 0; i < nb.size(); i++){
e = nb.get(i);
int ti = this.getId();
int fin = e.getFinish().getId();
if(ti == fin)
all += e.getStart().getId() + " ";
else
all += e.getFinish().getId() + " ";
}
return all;
}
/**
* Overrides toString method
* #return ID and IP of vertex
*/
public String toString(){
return id + " " + " " + ip;
}
}
private class Edge{
int weight;
Vertex finish;
Vertex start;
/**
* Constructor of Edge
* #param vertex 1, start vertex
* #param vertex 2, endpoint vertex
* #param weight of edge
*/
public Edge(Vertex v, Vertex v2, int w){
start = v;
finish = v2;
weight = w;
}
/**
* Gets the start of an edge
* #return edge start
*/
public Vertex getStart(){
return start;
}
/**
* Gets the endpoint of an edge
* #return endpoint of edge
*/
public Vertex getFinish(){
return finish;
}
/**
* Gets the weight of an edge
* #return weight of edge
*/
public int getWeight(){
return weight;
}
/**
* Overrides toString
* #return start of edge and endpoint of edge
*/
public String toString(){
return start + " " + finish;
}
}
/**
* Adds an edge to 2 verticies
* #param s, starting vertex IP
* #param t, enpoint vertex IP
* #param w, weight of edge
*/
public void add(String s, String t, int w){
Vertex v3, v4;
v3 = exists(new Vertex(s));
v4 = exists(new Vertex(t));
Edge e;
if(v3 == null && v4 == null){
v3 = new Vertex(s);
v4 = new Vertex(t);
vert.add(v3);
vert.add(v4);
e = new Edge(v3, v4, w);
v3.addList(e);
v4.addList(e);
}
else if(v3 != null && v4 == null){
counter--;
v4 = new Vertex(t);
vert.add(v4);
e = new Edge(v3, v4, w);
v3.addList(e);
v4.addList(e);
}
else if(v3 == null && v4 !=null){
counter--;
v3 = new Vertex(s);
vert.add(v3);
e = new Edge(v3, v4, w);
v3.addList(e);
v4.addList(e);
}
else{
counter -= 2;
e = new Edge(v3, v4, w);
if(!v3.exists(e)){
v3.addList(e);
v4.addList(e);
}
}
allEdges[edges] = e;
edges++;
}
/**
* Determines if an edge already exists
* #param vertex to be checked
* #return vertex if exists, null if not
*/
public Vertex exists(Vertex v){
for(int i = 0; i < vert.size(); i++){
if(v.getIp().equals(vert.get(i).getIp()))
return vert.get(i);
}
counter--;
return null;
}
/**
* Puts vert ArrayList into an array
* #return String array of vert
*/
public String[] toArray(){
String[] all = new String[vert.size()];
for(int i = 0; i < vert.size(); i++){
all[i] = vert.get(i).toString();
}
return all;
}
/**
* Determines if a vertex is adjacent to another vertex
* #return String array of adjacent verticies
*/
public String[] adjaceny(){
String[] all = new String[vert.size()];
Vertex v1;
for(int i = 0; i < vert.size(); i++){
v1 = vert.get(i);
all[i] = v1.getEdges();
}
return all;
}
/**
* Determines which vertex is in which cluster
* #return String array of clusters
*/
/*
public String[] cluster(){
Vertex[] temp = (Vertex[]) vert.toArray();
Sorter sort = new Sorter();
sort.heapsort(temp);
String[] cluster = new String[vert.size()];
int[] verts = new int[vert.size()];
for(int i = 0; i < vert.size();i++)
verts[i] = i;
return null;
}
*/
/**
* Gets the max spanning tree of the graph
* #return spanning tree of graph
*/
public String[] maxTree(){
sortEdges();
String[] max = new String[vert.size() -1];
Edge e;
for(int i = 0; i < vert.size()-1; i++){
e = allEdges[i];
max[i] = e.getStart().getId() + ", " + e.getFinish().getId() + ", " + e.getWeight();
}
return max;
}
/**
* Sorts edges by max weight
*/
private void sortEdges(){
Sorter sort = new Sorter();
sort.heapsort(allEdges);
}
public class Sorter{
/**
* Heapsorts the Object array
* #param Object array to be sorted
*/
public void heapsort(Object[] a)
{
for(int i = edges / 2; i >= 0; i-- ) /* buildHeap */
percDown(a, i, edges);
for( int i = edges - 1; i > 0; i-- )
{
swapReferences( a, 0, i ); /* deleteMax */
percDown( a, 0, i );
}
}
/**
* Performs swapping of elements
* #param Object array
* #param index1
* #param index2
*/
public void swapReferences(Object[] a, int index1, int index2 )
{
if(a[0] instanceof Edge){
Edge tmp = (Edge)a[index1];
a[index1] = a[index2];
a[index2] = tmp;
}
else if(a[0] instanceof Vertex){
Vertex temp = (Vertex)a[index1];
a[index1] = a[index2];
a[index2] = temp;
}
}
/**
* Internal method for heapsort.
* #param i the index of an item in the heap.
* #return the index of the left child.
*/
private int leftChild(int i)
{
return 2 * i + 1;
}
/**
* Internal method for heapsort that is used in
* deleteMax and buildHeap.
* #param a an array of Comparable items.
* #int i the position from which to percolate down.
* #int n the logical size of the binary heap.
*/
private void percDown(Object[] a, int i, int n)
{
int child;
if(a[0] instanceof Edge){
Edge tmp;
for( tmp = (Edge) a[i]; leftChild(i) < n; i = child )
{
child = leftChild(i);
if( child != n - 1 && ((Edge)a[child]).getWeight() - ((Edge)(a[child + 1])).getWeight() > 0 )
child++;
if(tmp.getWeight() - ((Edge)a[child]).getWeight() > 0 )
a[i] = a[child];
else
break;
}
a[i] = tmp;
}
else if(a[0] instanceof Vertex){
Vertex temp;
for(temp = (Vertex) a[i]; leftChild(i) < n; i = child){
child = leftChild(i);
if(child != n-1 && ((Vertex)a[child]).edgeSize() - ((Vertex)a[child+1]).edgeSize() > 0)
child++;
if(temp.edgeSize() - ((Vertex)a[child]).edgeSize() > 0)
a[i] = a[child];
else
break;
}
a[i] = temp;
}
}
}
}
}
With a main consisting of:
import java.util.*;
import java.io.*;
public class pg6main {
public static void main(String[] args) throws IOException{
String filename;
String first, second;
int weight;
Graph2 graph = new Graph2();
Scanner kb = new Scanner(System.in);
boolean go = false;
Scanner infile = null;
PrintWriter outfile = new PrintWriter(new FileWriter("results.txt"));
do{
try{
System.out.print("Enter a file to read from: ");
filename = kb.nextLine();
infile = new Scanner(new FileReader(filename));
}catch(Exception e){
go = true;
System.out.println("file doesn't exist");
}
}while(go);
while(infile.hasNext()){
first = infile.next().trim();
second = infile.next().trim();
weight = Integer.parseInt(infile.nextLine().trim());
graph.add(first, second, weight);
}
outfile.println("IP and their unique IDs: ");
String[] a = graph.toArray();
for(int i = 0; i < a.length; i++)
outfile.println(a[i]);
outfile.println("Adjaceny List: ");
String[] adj = graph.adjaceny();
for(int j = 0; j < adj.length; j++)
outfile.println(j + ": " + adj[j]);
outfile.println("Max spanning tree: ");
String[] max = graph.maxTree();
for(int k = 0; k < max.length; k++)
outfile.println("(" + max[k] + ") ");
/*
//Attempting to do clusters based on length of string of neighbors, does not work
for(int x = 0; x < adj.length; x++){
if(adj[x].length() > adj[x+1].length()){
outfile.println("WHAT I DID: " + adj[x]);
}
else if(adj[x].length() == adj[x+1].length()){
adj[x] = adj[x+1];
outfile.println("WHAT I DID: " + adj[x]);
}
else if(adj[x].length() < adj[x+1].length()){
adj[x] = adj[x+1];
outfile.println("WHAT I DID: " + adj[x]);
}
*/
/*//Attempted to do neighbors slighly different way
String[] cluster = graph.cluster();
for(int x = 0; x < cluster.length; x++){
if(cluster[x] != null)
outfile.println(cluster[x]);
*/
outfile.close();
}//end main
}//end pg6main
I was wondering if anyone could help, I've never worked with graphs until today. So far, I believe my code works as intended, but there could potentially be some errors with my logic. Basically my issue is most of the implementations of Dijkstra's have parameters as a graph, and I am unsure if this is actually how I should be doing this. Thanks for any help.
You should use the Floyd algorithm instead, it gives you a full table of shortest routes, exactly as you described in the requirements.
As you can see from the pseudocode, it's really simple and all you need is to create a two-dimensional array and initialise it with the edges. (So basically it's your weighted adjacency table.)

Categories