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!!!
Related
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);
}
}
My program doesn't show each of the correct list it's being sorted, number of comparison and number of assignment except bubble sorting method. I think I missed to reset the input string but could not figure out the way to reset input.
Is there any way to sort one input in different sorting method.
Here is my code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;
/**
* Create a program that does head-to-head comparisons between four sorting
* methods: improved bubble sort; selection sort; insertion sort; and Shell
* sort.
*
*/
public class SortAlgorithms {
private static char tracing;
private static char list;
private static int numAsgn = 0;
private static int numComp = 0;
private static int size;
private static int min;
private static int max;
private static final Scanner KBD = new Scanner(System.in);
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("How many elements do you want in the list? ");
size = KBD.nextInt();
System.out.print("What are the smallest and largest values for lsit elements? ");
min = KBD.nextInt();
max = KBD.nextInt();
KBD.nextLine();
pause();
System.out.print("Would you like to see the list before it's sorted? ");
list = Character.toUpperCase(br.readLine().charAt(0));
System.out.print("Would you like to see the list as it's being sorted? ");
tracing = Character.toUpperCase(br.readLine().charAt(0));
pause();
sortNumbers();
}
// prompt the user and wait for them to press enter
private static void pause() {
System.out.print("\n...Press enter...");
KBD.nextLine();
System.out.println();
}
/**
* Sort a list of integer values, generated randomly.
*/
public static void sortNumbers() {
resetCounts();
Integer[] numbers = randomNumbers(size, min, max);
if (list == 'Y') {
System.out.println("Here is the list: " + Arrays.toString(numbers));
pause();
}
System.out.printf("\n%1s%25s%20s%20s\n", "Method", "#COMP", "#ASGN", "#OPS");
bubbleSort(numbers);
System.out.printf("%1s%25d%20d%20d\n", "Bubble", numComp, numAsgn, numAsgn + numComp);
selectionSort(numbers);
System.out.printf("%1s%22d%20d%20d\n", "Selection", numComp, numAsgn, numAsgn + numComp);
insertionSort(numbers);
System.out.printf("%1s%22d%20d%20d\n", "Insertion", numComp, numAsgn, numAsgn + numComp);
shellSort(numbers);
System.out.printf("%1s%26d%20d%20d\n", "Shell", numComp, numAsgn, numAsgn + numComp);
}
/**
* Reset the operation counts to zero.
*/
public static void resetCounts() {
numAsgn = 0;
numComp = 0;
}
/**
* Generate an array of random values.
*
* #param howMany the length of the list to be generated.
* #param lo the smallest value allowed in the list
* #param hi the largest value allowed in the list
*/
public static Integer[] randomNumbers(int size, int min, int max) {
int range = max - min + 1;
Integer[] result = new Integer[size];
for (int i = 0; i < size; ++i) {
result[i] = (int) (min + range * Math.random());
}
return result;
}
/**
* Perform bubble sort on the given array.
*
* #param a the array to sort.
*/
public static <T extends Comparable<? super T>>
void bubbleSort(T[] a) {
for (int i = a.length - 1; i > 0; --i) {
boolean elementSwapped = false;
//numComp++;
for (int j = 0; j < i; ++j) {
numComp++;
if (a[j].compareTo(a[j + 1]) > 0) {
numAsgn += 3;
T temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
elementSwapped = true;
}
}
if (!elementSwapped) {
break;
}
//if (tracing == 'Y') {
System.out.println("one more bubbled up: "
+ Arrays.toString(a));
//}
}
}
/**
* Perform insertion sort on the given array.
*
* #param a the array to sort.
*/
public static <T extends Comparable<? super T>>
void insertionSort(T[] a) {
for (int i = 0; i < a.length - 1; ++i) {
int p = i + 1;
T temp = a[p];
++numAsgn;
while (p > 0 && a[p - 1].compareTo(temp) > 0) {
++numComp;
a[p] = a[p - 1];
++numAsgn;
--p;
}
if (p > 0) {
++numComp; // count the last a[p-1] comparison
}
a[p] = temp;
++numAsgn;
//if (tracing == 'Y') {
System.out.println("one more inserted: " + Arrays.toString(a));
//}
}
}
/**
* Perform selection sort on the given array. if tracing, show the array
* after each selection round.
*
* #param a the array to sort
*/
public static <T extends Comparable<? super T>>
void selectionSort(T[] a) {
for (int i = 0; i < a.length - 1; ++i) {
int p = i;
++numAsgn;
for (int j = i + 1; j < a.length; ++j) {
++numComp;
if (a[j].compareTo(a[p]) < 0) {
p = j;
++numAsgn;
}
}
T temp = a[i];
a[i] = a[p];
a[p] = temp;
++numAsgn;
//if (tracing == 'Y') {
System.out.println("one more selected: " + Arrays.toString(a));
//}
}
}
/**
* Perform shell sort on the given array.
*
* #param a the array to sort.
*/
public static <T extends Comparable<? super T>>
void shellSort(T[] a) {
int gap = a.length / 2;
++numComp;
while (gap >= 1) {
if (gap % 2 == 0) {
++gap;
}
++numComp;
for (int i = gap; i < a.length; ++i) {
++numAsgn;
int p = i;
T temp = a[p];
++numComp;
while (p >= gap && a[p - gap].compareTo(temp) > 0) {
a[p] = a[p - gap];
p -= gap;
++numAsgn;
}
a[p] = temp;
++numAsgn;
}
//if (tracing == 'Y') {
System.out.println("...gap=" + gap + ": " + Arrays.toString(a));
// }
gap /= 2;
}
}
/**
* Calculate how many operations a list of the given length should take.
*
* #param numItems the number of elements in a list.
* #return the number of operations expected (on average) to sort that list
*/
private static int expect(int numItems) {
return (numItems * numItems + numItems) * 5 / 4;
}
}
You are overriding array numbers each time you sort, so since bubbleSort is the first sorting method, you only get to see that one. Each consecutive sorting method just operates on a sorted array. Also since you've defined your counts as member variables, you need to call resetCounts() right before each method to get a fresh count. Making a copy of the array before you pass it to each sorting method, and resetting the counts should fix this.
System.out.printf("\n%1s%25s%20s%20s\n", "Method", "#COMP", "#ASGN", "#OPS");
resetCounts();
bubbleSort(Arrays.copyOf(numbers, numbers.length));
System.out.printf("%1s%25d%20d%20d\n", "Bubble", numComp, numAsgn, numAsgn + numComp);
resetCounts();
selectionSort(Arrays.copyOf(numbers, numbers.length));
System.out.printf("%1s%22d%20d%20d\n", "Selection", numComp, numAsgn, numAsgn + numComp);
resetCounts();
insertionSort(Arrays.copyOf(numbers, numbers.length));
System.out.printf("%1s%22d%20d%20d\n", "Insertion", numComp, numAsgn, numAsgn + numComp);
resetCounts();
shellSort(numbers);
System.out.printf("%1s%26d%20d%20d\n", "Shell", numComp, numAsgn, numAsgn + numComp);
I'm trying to add two DNumber objects in the add(DNumber b) method. The point is to be able to do binary arithmetic. The elements are stored normally. How should I handle ArrayLists that are not even? Fill the one with fewer elements with 0s?. Then how should I retrieve each element? Also what would be a good way to convert to decimal without using the convert to decimal method:
public class DNumber{
ArrayList<Digit> binary = new ArrayList<Digit>();
/**
* Constructor for objects of class DNumber
*/
public DNumber()
{
Digit num = new Digit(0);
binary.add(num);
}
public DNumber(int val){
int num = val;
if(num > 0){
while (num > 0){
Digit bin = new Digit(num%2);
num /= 2;
binary.add(0, bin);
}
}
else{
Digit bin = new Digit(0);
binary.add(0,bin);
}
}
/**
* An example of a method - replace this comment with your own
*
* #param y a sample parameter for a method
* #return the sum of x and y
*/
public String toString(){
String s = "";
for(Digit d : binary){
s = s + d.toString();
}
return s;
}
public void add(DNumber b){
int ArraySize1 = binary.size() -1;
int ArraySize2 = b.binary.size() -1;
}
public void toDecimal(){
/**
*
* String s = "";
int result = 0;
int power = 0;
for(Digit d : binary){
s = s + d.toString();
result = Integer.parseInt(s);
}
*/
}
}
public class Digit {
int x = 0;
/**
* Constructor for objects of class Digit
*/
public Digit(int val) {
if (val != 0 && val != 1) {
System.out.println("Error Must be either 1 or 0");
x = 0;
} else {
x = val;
}
}
/**
* An example of a method - replace this comment with your own
*
* #param y a sample parameter for a method
* #return the sum of x and y
*/
public int getValue() {
return x;
}
public void setValue(int num) {
if (num != 0 && num != 1) {
System.out.println("Error Must be either 1 or 0");
System.out.println("Old Value Retained");
} else {
x = num;
}
}
public String toString() {
return Integer.toString(x);
}
public Digit add(Digit b) {
int returnInt = getValue() + b.getValue();
Digit carry = new Digit(0);
if (returnInt == 2) {
carry = new Digit(1);
setValue(0);
} else if (returnInt == 1) {
carry = new Digit(0);
setValue(1);
} else if (returnInt == 0) {
carry = new Digit(0);
setValue(0);
}
return carry;
}
public Digit add(Digit b, Digit c) {
int returnInt = getValue() + b.getValue() + c.getValue();
Digit carry = new Digit(0);
if (returnInt == 2) {
carry = new Digit(1);
setValue(0);
} else if (returnInt == 1) {
carry = new Digit(0);
setValue(1);
} else if (returnInt == 0) {
carry = new Digit(0);
setValue(0);
} else if (returnInt == 3) {
carry = new Digit(1);
setValue(1);
}
return carry;
}
}
Consider this small change to your constructor.
while (num > 0){
Digit bin = new Digit(num%2);
num /= 2;
binary.add(bin);
}
This might seem strange at first, new DNumber(6) gives you a list (0,1,1) which seems backwards, but is much easier to work with.
You can easily convert this to a decimal:
public int toDecimal() {
int total = 0;
int power = 1;
for (int i = 0; i < binary.size(); i++) {
total += binary.get(i).getValue() * power;
power *= 2;
}
return total;
}
When it comes to adding you start at the 0th element with a carry of 0, if one array is longer than the other it's much easier to handle.
Consider adding 6 and 4
carry = 0
a = (0,1,1)
b = (0,0,1)
answer = ()
at start, it's 0+0+0 = 0, carry 0
carry=0
a = (1,1)
b = (0,1)
answer = (0)
the next interation, it's 0+1+0 = 1, carry 0
carry=0
a = (1)
b = (1)
answer = (0,1)
the next iteration, it's 0+1+1 = 0, carry 1
carry=1
a = ()
b = ()
answer = (0,1,0)
The next iteration both input lists are empty, so we just add the carry bit
answer = (0,1,0,1) which if you run through toDecimal is 10
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
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.)