Neural Network bad convergeance - java

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

Related

How do I finish writing this sinc low pass filter

I have been trying to code a sinc low pass filter to be used on sound waves in java.
I have been following this code here https://tomroelandts.com/articles/how-to-create-a-simple-low-pass-filter
I then got to the part on convulving the waveform with the filter output and thought convulving had to happen with arrays, but since the sight's code is in python, I cannot tell the arrays from the other variables. Most of what I came up with on convulving needed arrays to function properly and since it seemed to multiply one value with another, that was how I coded it.
What should I be doing and are there other mistakes with my code?
Also, would I be able to apply resonance to this filter?
The method lowPass(double point) is meant to take a sample, low pass filter it and return it.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package effects;
/**
*
* #author Edward Jenkins
*/
public class SincLowPassFilter {
public static final double DEF_BAND = 0;
// instance variables
private double cutoffFrequency;
private double resonance;
private double sampleRate;
private double value;
private double sumnatedValue;
private double cutoffAmount;
private double resonanceAmount;
private double transitionBand;
private double window;
private int n;
private int index;
// constructor
public SincLowPassFilter(double cutoffFrequency, double resonance,
double sampleRate, double band) {
this.cutoffFrequency = cutoffFrequency;
cutoffAmount = cutoffFrequency / sampleRate;
transitionBand = band / sampleRate;
n = (int)Math.ceil(4 / transitionBand);
if (!(n % 2 == 2)) {
n += 1;
}
sumnatedValue = 0;
for(int i = 0; i < n; i++) {
value = sinc(2 * cutoffAmount * (i - (n - 1) / 2));
window = 0.42 - 0.5 * Math.cos(2 * Math.PI * i / (n - 1)
/ 0.08 * Math.cos(4 * Math.PI * i / (n - 1)));
value = value * window;
sumnatedValue += value;
value = value / sumnatedValue;
}
}
// low pass filter
public double lowPass(double point) {
return point * value;
}
// sinc
private double sinc(double value) {
return Math.sin(Math.PI * value) / Math.PI * value;
}
}
Thanks to the folks on stack exchange, I ended up with this. But this uses a sub class to implement
Super class:
package filters;
import sound.generator.waveforms.SamplePlayer;
import sound.generator.waveforms.ISamplePlayer;
/**
*
* #author Edward Jenkins
* #version 1.2
*/
public abstract class SincSpecs implements ISimpleFilter{
// instance variables
private double cutoffFrequency;
private double sampleRate;
private double resonance;
private boolean highPass;
private double value;
private double sumnatedValue;
private double cutoffAmount;
private double transitionBand;
private double window;
private double[] impulseResponce;
private double[] sampleCache;
private int sampleCacheLength;
private int n;
private int order;
private int midPoint;
//private int index;
// constructor for audio sample
public SincSpecs(double cutoffFrequency, double sampleRate, byte resonance,
boolean highPass, int band, SamplePlayer sample) {
this.cutoffFrequency = cutoffFrequency;
this.resonance = (double)resonance / 127;
this.highPass = highPass;
this.sampleRate = sampleRate;
if (highPass) {
this.cutoffFrequency += band / 2;
} else {
this.cutoffFrequency -= band / 2;
}
cutoffAmount = this.cutoffFrequency / this.sampleRate;
transitionBand = band / sampleRate;
//index = 0;
n = (int)(Math.ceil(4 / transitionBand));
// make sure length is odd
if (n % 2 == 0) {
n += 1;
}
order = n;
midPoint = order / 2 + 1;
impulseResponce = new double[n];
sumnatedValue = 0;
updateImpulseResponce();
sampleCache = new double[n];
sampleCacheLength = 0;
double inputPoint;
while (!canOutput()) {
inputPoint = sample.getNextPoint(); // get next sample point
inputFilterPoint(inputPoint);
}
}
// constructor for interface
public SincSpecs(double cutoffFrequency, double sampleRate, byte resonance,
boolean highPass, int band, ISamplePlayer sample) {
this.cutoffFrequency = cutoffFrequency;
this.resonance = (double)resonance / 127;
this.highPass = highPass;
this.sampleRate = sampleRate;
if (highPass) {
this.cutoffFrequency -= band / 2;
} else {
this.cutoffFrequency += band / 2;
}
cutoffAmount = cutoffFrequency / this.sampleRate;
transitionBand = band / sampleRate;
//index = 0;
n = (int)(Math.ceil(4 / transitionBand));
// make sure length is odd
if (n % 2 == 0) {
n += 1;
}
order = n;
midPoint = order / 2 + 1;
impulseResponce = new double[n];
sumnatedValue = 0;
updateImpulseResponce();
sampleCache = new double[n];
sampleCacheLength = 0;
double inputPoint;
while (!canOutput()) {
inputPoint = sample.generateWaveformPoint(); // get next waveform point
inputFilterPoint(inputPoint);
}
}
public double getTransitionBand() {
return transitionBand;
}
#Override
public void setCutoff(double cutoffFrequency) {
this.cutoffFrequency = cutoffFrequency;
cutoffAmount = this.cutoffFrequency / sampleRate;
updateImpulseResponce();
}
public void updateImpulseResponce() {
// get window of filtering
for (int i = 0; i < n; i++) {
impulseResponce[i] = cutoffAmount
* sinc(2 * cutoffAmount * Math.PI * (i - midPoint));
impulseResponce[midPoint] = cutoffAmount;
window = 0.54 - 0.46 * Math.cos(2 * Math.PI * i / order);
impulseResponce[i] *= window;
}
// sumnate all filter kernal values
double sum = 0;
for (int i = 0; i < n; i++) {
sum += impulseResponce[i];
}
for (int i = 0; i < n; i++) {
impulseResponce[i] /= sum;
}
// invert the impulse responce if high pass is true
if (this.highPass) {
invertImpulseForHighPass();
}
}
// input points
protected void inputFilterPoint(double point) {
sampleCache[sampleCacheLength] = point;
sampleCacheLength++;
for (int i = 0, j = n - 1; i < n; i++, j--) {
value += sampleCache[j] * impulseResponce[i];
}
}
protected void incrementCache(double value) {
for (int i = 0; i < sampleCacheLength - 1; i++) {
sampleCache[i] = sampleCache[i + 1];
}
sampleCache[sampleCacheLength - 1] = value;
}
// can output
protected boolean canOutput() {
boolean result = false;
if (sampleCacheLength == n) {
result = true;
}
return result;
}
// sinc
protected double sinc(double value) {
if (value == 0) {
value = 1;
} else {
value = Math.sin(value) / (value) + resonance * Math.sin(value);
}
return value;
}
protected void invertImpulseForHighPass() {
for (int i = 0; i < impulseResponce.length; i++) {
impulseResponce[i] *= -1;
}
impulseResponce[midPoint] += 1;
}
#Override
public double filter(double point) {
//index++;
value = 0;
for (int i = 0, j = n - 1; i < n; i++, j--) {
value += sampleCache[j] * impulseResponce[i];
}
incrementCache(point);
/*if (index == n) {
index = 0;
}*/
return value;
}
}
sub class:
package filters;
import sound.generator.waveforms.ISamplePlayer;
/**
*
* #author Edward Jenkins
*/
public class SincFilter extends SincSpecs {
// constants
public static final byte DEF_RESONANCE = 0;
public static final int DEF_BAND = 400;
// constructor
public SincFilter(double cutoffFrequency, double sampleRate, byte resonance,
boolean highPass, int band, ISamplePlayer sample) {
super(cutoffFrequency, sampleRate, (byte)resonance, highPass,
band, sample);
}
// three args constructor
public SincFilter(double cutoffFrequency, double sampleRate, byte resonance,
boolean highPass, ISamplePlayer sample) {
this(cutoffFrequency, sampleRate, resonance, highPass, DEF_BAND, sample);
}
// two args constructor
public SincFilter(double cutoffFrequency, double sampleRate,
ISamplePlayer sample) {
this(cutoffFrequency, sampleRate, DEF_RESONANCE, false, sample);
}
#Override
public void setCutoff(double cutoffFrequency) {
super.setCutoff(cutoffFrequency + getTransitionBand() / 2);
}
}

get combinations of sets created after combinations in java

I've come to a dead end and need your help!!
I've managed to get combinations of a list of numbers(Double) that give a specific sum.I also have a hashtable which values are the numbers of the previous list and keys are some Strings eg. numbers(Double)[2.45,2.65,4.67,5.25,2.45,2.65....] and table[(E-40=2.45),(E-45=2.45),(E-56=2.65),(E-34=2.65),(E-24=4.67),(E-14=5.25)....].So after the numbers combinations for a specific sum I get: For sum: 5.10 ---> 2.45 - 2.65 which corresponds to (E-40,E-45) - (E-56,E-34).I would like to get now the combinations of these sets.
eg
[(E-40)-(E-56)],[(E-40)-(E-34)],
[(E-45)-(E-56)],[(E-45)-(E-34)]
And here is my code:`
public class TestTheCombinations {
public static void main(String[] args) {
ArrayList<Double> numbers = new ArrayList<>(Arrays.asList(2.45,2.45,2.65,2.65,4.67,5.25));
LinkedHashSet<Double> targets = new LinkedHashSet<Double>() {{
add(5.10);
}};
for (Double target: targets) {
Combinations combinations = new Combinations(numbers, target, false);
combinations.calculateCombinations();
for (String solution: combinations.getCombinations()) {
System.out.println(solution);
}
}
}
public static class Combinations {
private boolean allowRepetitions;
private int[] repetitions;
private ArrayList<Double> numbers;
private Hashtable<String,Double> table;
private Double target;
private Double sum;
private boolean hasNext;
private Set<String> combinations;
/**
* Constructor.
*
* #param numbers Numbers that can be used to calculate the sum.
* #param target Target value for sum.
*/
public Combinations(ArrayList<Double> numbers, Double target) {
this(numbers, target, true);
}
/**
* Constructor.
*
* #param numbers Numbers that can be used to calculate the sum.
* #param target Target value for sum.
*/
public Combinations(ArrayList<Double> numbers, Double target, boolean allowRepetitions) {
this.allowRepetitions = allowRepetitions;
if (this.allowRepetitions) {
Set<Double> numbersSet = new HashSet<>(numbers);
this.numbers = new ArrayList<>(numbersSet);
} else {
this.numbers = numbers;
}
this.numbers.removeAll(Arrays.asList(0));
Collections.sort(this.numbers);
this.target = target;
this.repetitions = new int[this.numbers.size()];
this.combinations = new LinkedHashSet<>();
this.sum = 0.0;
if (this.repetitions.length > 0)
this.hasNext = true;
else
this.hasNext = false;
}
/**
* Calculate and return the sum of the current combination.
*
* #return The sum.
*/
private Double calculateSum() {
this.sum = 0.0;
for (int i = 0; i < repetitions.length; ++i) {
this.sum += repetitions[i] * numbers.get(i);
}
return this.sum;
}
/**
* Redistribute picks when only one of each number is allowed in the sum.
*/
private void redistribute() {
for (int i = 1; i < this.repetitions.length; ++i) {
if (this.repetitions[i - 1] > 1) {
this.repetitions[i - 1] = 0;
this.repetitions[i] += 1;
}
}
if (this.repetitions[this.repetitions.length - 1] > 1)
this.repetitions[this.repetitions.length - 1] = 0;
}
/**
* Get the sum of the next combination. When 0 is returned, there's no other combinations to check.
*
* #return The sum.
*/
private Double next() {
if (this.hasNext && this.repetitions.length > 0) {
this.repetitions[0] += 1;
if (!this.allowRepetitions)
this.redistribute();
this.calculateSum();
for (int i = 0; i < this.repetitions.length && this.sum != 0; ++i) {
if (this.sum > this.target) {
this.repetitions[i] = 0;
if (i + 1 < this.repetitions.length) {
this.repetitions[i + 1] += 1;
if (!this.allowRepetitions)
this.redistribute();
}
this.calculateSum();
}
}
if (this.sum.compareTo(0.0) == 0.0)
this.hasNext = false;
}
return this.sum;
}
/**
* Calculate all combinations whose sum equals target.
*/
public void calculateCombinations() {
while (this.hasNext) {
if (this.next().compareTo(target) == 0)
this.combinations.add(this.toString());
}
}
/**
* Return all combinations whose sum equals target.
*
* #return Combinations as a set of strings.
*/
public Set<String> getCombinations() {
return this.combinations;
}
#SuppressWarnings({ "rawtypes", "unchecked" })
#Override
public String toString() {
Hashtable<String,Double> table = new Hashtable<String,Double>();
table.put("E-40",2.45);
table.put("E-45",2.45);
table.put("E-56",2.65);
table.put("E-34",2.65);
table.put("E-24",4.67);
table.put("E-14",5.25);
StringBuilder stringBuilder = new StringBuilder("For SUM " + sum + ": "+"\n");
StringBuilder stringBuilder2 = new StringBuilder();
for (int i = 0; i < repetitions.length; ++i) {
for (int j = 0; j < repetitions[i]; ++j) {
Set keys = new HashSet();
Double value = numbers.get(i);
for(Map.Entry entry: table.entrySet()){
if(value.equals(entry.getValue())){
keys.add(entry.getKey());
}
}
stringBuilder.append(numbers.get(i)+ " Corresponds WorkCode "+ keys+"\n");
}
}
return stringBuilder.toString() ;
}
}
}
`
Thanks for any help!!!

If statement not running correctly

What I'm trying to do is get my program to run a method to make lemonade (makeLemonade) if and only if I have enough ingredients to make the lemonade, but I keep getting an error from the tests provided for me that tells my lemonade is being made even when I don't have enough ingredients.
Here's the code I have right now for the if statement that's giving me some trouble. I've tried using && and || along with different mixes of >= and > to no avail so far.
public int makeLemonade() {
if (lemons >= 6 && gallonsOfWater >= 1 && cupsOfSugar >= 1 && emptyGlasses >= 8) {
lemons = lemons - 6;
gallonsOfWater = gallonsOfWater - 1;
cupsOfSugar = cupsOfSugar - 1;
emptyGlasses = emptyGlasses - 8;
glassesOfLemonade = glassesOfLemonade + 8;
return glassesOfLemonade;
} else {
return 0;
}
}
This is the error my test is giving me right now
"Test of method makeLemonade failed for activty 3.
The following code was executed:
LemonadeStand ls = new LemonadeStand(5, 2, 2, 16, 1.1);
ls.makeLemonade();
Fields were modified even though there was not enough lemons available to make lemonade."
Here is the entire code so far
/**
* LemonadeStand.java
*
*/
//Put any imports below this line.
/**
* Short, one-line description of LemonadeStand class here.
*
* Optionally, include a paragraph that provides a more
* detailed description.
*
* #author Nicholas Thomas
* #version 2/19/2018
*/
public class LemonadeStand
{
//Put instance variables below this line.
private int lemons;
private int gallonsOfWater;
private int cupsOfSugar;
private int emptyGlasses;
private double price;
private double income;
private int glassesOfLemonade;
/** No arg constructor.
* LemonadeStand Constructor
*
*/
public LemonadeStand()
{
lemons = 0;
gallonsOfWater = 0;
cupsOfSugar = 0;
glassesOfLemonade = 0;
emptyGlasses = 0;
price = 0;
income = 0;
}
/** Contructor.
* LemonadeStand Constructor
*
* #param newLemons A parameter
* #param newGallonsOfWater A parameter
* #param newCupsOfSugar A parameter
* #param newEmptyGlasses A parameter
* #param newPrice A parameter
*/
public LemonadeStand(int newLemons, int newGallonsOfWater,
int newCupsOfSugar, int newEmptyGlasses, double newPrice)
{
setLemons(newLemons);
setGallonsOfWater(newGallonsOfWater);
setCupsOfSugar(newCupsOfSugar);
setEmptyGlasses(newEmptyGlasses);
setPrice(newPrice);
glassesOfLemonade = 0;
income = 0;
}
/** Main method of the program.
* Method main
*
* #param args A parameter
*/
public static void main(String[] args)
{
LemonadeStand lemonadeStand = new LemonadeStand(15, 3, 4, 20, 1.5);
lemonadeStand.makeLemonade();
System.out.println(lemonadeStand.getLemons());
System.out.println(lemonadeStand.getGallonsOfWater());
System.out.println(lemonadeStand.getCupsOfSugar());
System.out.println(lemonadeStand.getGlassesOfLemonade());
}
/** Mutator to change the amount of lemons.
* Method setLemons
*
* #param newLemons A parameter
* #return newLemons
*/
public int setLemons(int newLemons)
{
if (lemons < 0)
{
lemons = newLemons;
return newLemons;
}
else
{
return 0;
}
}
/** Mutator to change gallons of water.
* Method setGallonsOfWater
*
* #param newGallonsOfWater A parameter
* #return gallonsOfWater
*/
public int setGallonsOfWater(int newGallonsOfWater)
{
if (gallonsOfWater < 0)
{
gallonsOfWater = newGallonsOfWater;
return gallonsOfWater;
}
else
{
return 0;
}
}
/** Mutator to set cups of sugar.
* Method setCupsOfSugar
*
* #param newCupsOfSugar A parameter
* #return cupsOfSugar
*/
public int setCupsOfSugar(int newCupsOfSugar)
{
if (cupsOfSugar < 0)
{
cupsOfSugar = newCupsOfSugar;
return cupsOfSugar;
}
else
{
return 0;
}
}
/** Mutator to modify the number of empty glasses.
* Method setEmptyGlasses
*
* #param newEmptyGlasses A parameter
* #return emptyGlasses
*/
public int setEmptyGlasses(int newEmptyGlasses)
{
if (emptyGlasses < 0)
{
emptyGlasses = newEmptyGlasses;
return emptyGlasses;
}
else
{
return 0;
}
}
/** Mutator to modify the glasses of lemonade.
* Method setGlassesOfLemonade
*
* #param newGlassesOfLemonade A parameter
* #return glassesOfLemonade
*/
public int setGlassesOfLemonade(int newGlassesOfLemonade)
{
if (glassesOfLemonade < 0)
{
glassesOfLemonade = newGlassesOfLemonade;
return glassesOfLemonade;
}
else
{
return 0;
}
}
/** Mutator to change the price.
* Method setPrice
*
* #param newPrice A parameter
* #return price
*/
public double setPrice(double newPrice)
{
if (price < 0)
{
price = newPrice;
return price;
}
else
{
return 0;
}
}
/** Mutator to set the income.
* Method setIncome
*
* #param newIncome A parameter
* #return income
*/
public double setIncome(double newIncome)
{
if (income < 0)
{
income = newIncome;
return income;
}
else
{
return 0;
}
}
/** Accessor to make lemonade.
* Method makeLemonade
*
* #return The return value
**/
public int makeLemonade()
{
if (lemons >= 6 && gallonsOfWater >= 1 && cupsOfSugar >= 1
&& emptyGlasses >= 8)
{
lemons -= 6;
gallonsOfWater -= 1;
cupsOfSugar -= 1;
emptyGlasses -= 8;
glassesOfLemonade += 8;
return glassesOfLemonade;
}
else
{
return 0;
}
}
/** Accessor to lemonade selling.
* Method sellLemonade
*
* #return The return value
*/
public int sellLemonade()
{
if (glassesOfLemonade <= 1)
{
makeLemonade();
return 0;}
else
{
glassesOfLemonade = glassesOfLemonade - 1;
income = income + price;
return glassesOfLemonade;
}
}
/** Accessor to get number of lemons.
* Method getLemons
*
* #return The return value
*/
public int getLemons()
{
return lemons;
}
/** Accessor to return gallons of water.
* Method getGallonsOfWater
*
* #return The return value
*/
public int getGallonsOfWater()
{
return gallonsOfWater;
}
/** Accessor to return cups of sugar.
* Method getCupsOfSugar
*
* #return The return value
*/
public int getCupsOfSugar()
{
return cupsOfSugar;
}
/** Accessor to return the value of empty glasses.
* Method getEmptyGlasses
*
* #return The return value
*/
public int getEmptyGlasses()
{
return emptyGlasses;
}
/** Accessor to return glasses of lemonade.
* Method getGlassesOfLemonade
*
* #return The return value
*/
public int getGlassesOfLemonade()
{
return glassesOfLemonade;
}
/** Accessor to return the price.
* Method getPrice
*
* #return The return value
*/
public double getPrice()
{
return price;
}
/** Accesor to return the income rate.
* Method getIncome
*
* #return The return value
*/
public double getIncome()
{
return income;
}
/** Accessor for lemonade selling.
* Method sellMoreLemonade
*
* #param requestedGlasses A parameter
* #return The return value
*/
public int sellMoreLemonade(int requestedGlasses)
{
return 0;
}
}
The main issue with the code is the setter-usage. For example:
if (gallonsOfWater < 0) {
gallonsOfWater = newGallonsOfWater;
return gallonsOfWater;
} else {
return 0;
}
The gallonsOfWater field of LemonadeStand is initialized e.g. in the 2nd constructor by the call setGallonsOfWater(newGallonsOfWater);.
Let us assume that you pass the value 3 to this constructor, so it will be setGallonsOfWater(3);. In the setter this leads to 3 < 0 and hence
the return value of 0 for the setter.
not setting the value for the field gallonsOfWater.
(I assume that debugging would have helped here also)

How to fix Tic Tac Toe winner determination

Every time I run my Tic Tac Toe program I can create the board and do my first turn.
After the first turn, the game just ends as: "IT'S A DRAW", which is one of the three ending possibilities. This just happens before the computer can even make his own turn.
Another problem in my program is that the scanner user input limit(er) is not working (at the end of the code). If user inputs i.e a letter instead of int, the program crashes.
package newtictactoe;
import java.util.Scanner;
import java.util.Random;
public class NewTicTacToe {
public static final int DRAW = 0;
public static final int COMPUTER = 1;
public static final int PLAYER = 2;
public static int size;
public static char[][] board;
public static int score = 0;
public static Scanner scan = new Scanner(System.in);
/**
* Creates base for the game.
*
* #param args the command line parameters. Not used.
*/
public static void main(String[] args) {
System.out.println("Select board size");
System.out.print("[int]: ");
size = Integer.parseInt(scan.nextLine());
board = new char[size][size];
setupBoard();
int i = 1;
loop:
while (true) {
if (i % 2 == 1) {
displayBoard();
getMove();
} else {
computerTurn();
}
switch (isGameFinished()) {
case PLAYER:
System.err.println("YOU WIN!");
break loop;
case COMPUTER:
System.err.println("Computer WINS!\nYOU LOOSE!!");
break loop;
case DRAW:
System.err.println("IT'S A DRAW");
break loop;
}
i++;
}
}
private static int isGameFinished() {
if (isDraw()) {
return DRAW;
} else if (computerHasWon()) {
return COMPUTER;
} else if (playerHasWon()) {
return PLAYER;
}
return 0;
}
/**
* Checks for computer's win.
*
* #return if this game is won by computer.
*/
public static boolean playerHasWon() {
boolean hasWon = false;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
// check if 5 in a line
}
}
return hasWon;
}
/**
* Checks for player's win.
*
* #return if this game is won by computer.
*/
public static boolean computerHasWon() {
boolean hasWon = false;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
// check if 5 in a line
}
}
return hasWon;
}
/**
* Checks for draws.
*
* #return if this game is a draw
*/
public static boolean isDraw() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (board[i][j] == ' ') {
return false;
}
}
}
return true;
}
/**
* Displays the board.
*
*
*/
public static void displayBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
System.out.printf("[%s]", board[i][j]);
}
System.out.println();
}
}
/**
* Displays the board.
*
*
*/
public static void setupBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
board[i][j] = ' ';
}
}
}
/*
* Checks if the move is allowed.
*
*
*/
public static void getMove() {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.printf("ROW: [0-%d]: ", size - 1);
int x = Integer.parseInt(sc.nextLine());
System.out.printf("COL: [0-%d]: ", size - 1);
int y = Integer.parseInt(sc.nextLine());
if (isValidPlay(x, y)) {
board[x][y] = 'X';
break;
}
}
}
/*
* Randomizes computer's turn - where it inputs the mark 'O'.
*
*
*/
public static void computerTurn() {
Random rgen = new Random(); // Random number generator
while (true) {
int x = (int) (Math.random() * size);
int y = (int) (Math.random() * size);
if (isValidPlay(x, y)) {
board[x][y] = 'O';
break;
}
}
}
/**
* Checks if the move is possible.
*
* #param inX
* #param inY
* #return
*/
public static boolean isValidPlay(int inX, int inY) {
// Play is out of bounds and thus not valid.
if ((inX >= size) || (inY >= size)) {
return false;
}
// Checks if a play have already been made at the location,
// and the location is thus invalid.
return (board[inX][inY] == ' ');
}
These last two methods in the code check if the scanner input is valid but they don't work and I don't know why.
/**
* Checks if user input is valid
*
* #param scan
* #param prompt
* #return
*/
public static String getInput(Scanner scan, String prompt) {
System.out.print(prompt); // Tell user what to input
String text = "Enter one integer value i.e 5.";
while (true) { // Keeps on looping until valid input
text = scan.nextLine();
if (isInteger(text)) // Checks input is int
{
break; // Exit loop
}
System.out.print("Try again, " + prompt); // If invalid
}
return text; // Return valid user input
}
/**
* Checks if input string is int.
*
* #param str
* #return
*/
public static boolean isInteger(String str) {
try {
Integer.parseInt(str); // If this succeeds the input is int
return true;
} catch (NumberFormatException e) {
return false; // If not int
}
}
}
Your isGameFinished() method returns 0 by default (when the game is not over), but your DRAW constant is also 0. Try to change it to return (for example) -1 when the game is not over.
A nicer solution would be to have one method isGameFinished() that would return boolean to indicate if the game is over, and another method getWinner() which would return the winner (DRAW or COMPUTER or PLAYER), and will only be called if isGameFinished() returns true.
Your getMove method should catch NumberFormatException, which can be thrown by Integer.parseInt.

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