Bad results using Hopfield network - java

Im writing a program that will recognize traffic signs using neural networks and I have a problem with Hopfield network. I'm using this example to make my own hopfield network.
As an input, I use those traffic signs after normalization and it's a 50x50 matrix of 0 and 1.
The problem that I encounter is that when Hopfield network will learn 2 patterns it recognize them well, but when I try to train it with more than 2 patterns as a result it gives me a pattern that isn't matching any of those that it was trained on and it returns it for any input that I provide.
Here is my code, quite similar to the one from official encog examples:
public BiPolarNeuralData convertPattern(double[][] data, int index)
{
int resultIndex = 0;
BiPolarNeuralData result = new BiPolarNeuralData(WIDTH*HEIGHT);
for(int i=0;i<(WIDTH*HEIGHT);i++)
{
boolean znak=true;
if(data[index][i]==1)znak=true;
else znak=false;
result.setData(resultIndex++,data[index][i]==1.0);
}
return result;
}
public void display(BiPolarNeuralData pattern1,BiPolarNeuralData pattern2)
{
int index1 = 0;
int index2 = 0;
for(int row = 0;row<HEIGHT;row++)
{
StringBuilder line = new StringBuilder();
for(int col = 0;col<WIDTH;col++)
{
if(pattern1.getBoolean(index1++))
line.append('O');
else
line.append(' ');
}
line.append(" -> ");
for(int col = 0;col<WIDTH;col++)
{
if(pattern2.getBoolean(index2++))
line.append('O');
else
line.append(' ');
}
System.out.println(line.toString());
}
}
public void evaluate(HopfieldNetwork hopfieldLogic, double[][] pattern)
{
for(int i=0;i<pattern.length;i++)
{
BiPolarNeuralData pattern1 = convertPattern(pattern,i);
hopfieldLogic.setCurrentState(pattern1);
int cycles = hopfieldLogic.runUntilStable(100);
BiPolarNeuralData pattern2 = hopfieldLogic.getCurrentState();
System.out.println("Cycles until stable(max 100): " + cycles + ", result=");
display( pattern1, pattern2);
System.out.println("----------------------");
}
}
public BasicNetwork trainHopfieldNetwork(){
HopfieldNetwork hopfieldLogic = new HopfieldNetwork(HEIGHT*WIDTH);
for(int i=0;i<inputData.length;i++)
{
hopfieldLogic.addPattern(convertPattern(inputData,i));
System.out.println("Pattern : "+i);
}
evaluate(hopfieldLogic,inputData);
return null;
}
Where inputData is an array[2500] of type double.
What I've tried so far is:
Changing size of patterns to be smaller (10x10, 20x20).
Trying to learn different numbers of patterns (from 2 to 20). I always get strange results that don't match any of patterns that network was trained on.

So afterall the problem was the learning rule of network, since encog framework has implemented only hebb learning rule that isn't quite usefull for complex networks i had to implement pseudoinversion learning rule, and after that hopfield network started to recognize patterns without troubles

Related

Foobar code working in IDE but not in Solution file

I've written code for a foobar challenge that works in my IDE but not in the solutions file provided by foobar. Also, is there anyway to show the output even if the test fails? Possibly to with it being a static method or the input being {1, 2, 3, 4} whereas mine is working with new int {1,2,3,4,5}? My code is:
public static int solution(int[] l) {
List<Integer> numberList = Arrays.stream(l).boxed().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
while (true) {
StringBuilder number = new StringBuilder();
int i = 0;
while (i < numberList.size()) {
number.append(numberList.get(i));
i++;
}
List<Integer> startingList = Arrays.stream(l).boxed().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
int testValue = numberList.size();
for (Integer integer : numberList) {
if (startingList.contains(integer)) {
startingList.remove(integer);
testValue--;
}
}
if (testValue == 0) {
int f = 0;
int total = 0;
while (f < numberList.size()) {
total = total + numberList.get(f);
f++;
}
if (total % 3 == 0) {
StringBuilder answer = new StringBuilder();
int c = 0;
while (c < numberList.size()) {
answer.append(numberList.get(c));
c++;
}
return Integer.parseInt(answer.toString());
}
}
Integer nextNumber = Integer.parseInt(number.toString()) - 1;
String[] stringArray = valueOf(nextNumber).split("");
numberList = new ArrayList<>();
for (String s : stringArray) {
numberList.add(Integer.parseInt(s));
}
}
}
Pretty rubbish but it does the job (at least in my IDE!)
As mentioned in a comment on the question, you should undoubtedly give some more context for your questions (since it is pretty unclear what your code is intended to do). I'm pretty sure I've inferred the actual question from context though, and I can suggest a couple of problems. In short (and a pretty good assumption for coding in general) the issue is not the environment running your code incorrectly, but rather your code having missed bugs due to lack of comprehensive testing. If you had presented a number of sample inputs and results I would guess you would have seen that your solution does not work locally.
The Java List.remove() method takes an index rather than a value to be removed (https://docs.oracle.com/javase/8/docs/api/java/util/List.html). The way it is used in your sample will result in throwing exceptions in a number of circumstances. Proper testing would have identified this (and will pick up most of your problems if fixed)
What happens if there is no solution? For example, an input of {1, 1} is going to get into a pretty messy state as the 'nextNumber' value slips below 0. You should know what the desired behavior is in this situation, and your tests should cover it before you try to upload a solution
This happened to me as well, but I then realized that my compilation was not successful because I have not imported the package that I am using at the top of the source code file like all java programs are write

How to decrese permutation time?

I don't really hope to get an answer but I think of this more like a brainstorm so give you're best idea please :)
So I want to make a program that makes permutations of all the ASCII characters, and I can't connect 1000 computer to calculate this because unfortunately I have only one computer so I need some kind of algorithm to speed up the process.
I made the algorithm to find the possible combinations but I look online and it will take more then 100 years. PLEASE HELP.
This is the code to find permutations (it doesn't find all ASCII character permutations, but has a string with all letters and numbers and from that string he makes the permutations):
import java.io.*;
public class doIt extends AI {
public void check() {
String letters = "qwertzuioplkjhgfdsayxcvbnm0123456789-_";
permute(letters);
}
public void permute(String letters) {
int length = letters.length();
boolean[] used = new boolean[length];
StringBuffer str = new StringBuffer(length);
permutation(str, letters, used, length, 0);
}
public void permutation(StringBuffer str, String letters, boolean[] used, int length, int position) {
if (position == length) {
try {
File one = new File("G:/AllDateBases/Combinations.txt");
PrintWriter pw = new PrintWriter(new FileWriter("G:/AllDateBases/Combinations.txt", true));
pw.println(str.toString());
pw.close();
} catch (IOException e) {
System.out.println("Error");
}
return;
} else {
for (int i = 0; i < length; i++) {
if (used[i]) continue;
str.append(letters.charAt(i));
used[i] = true;
permutation(str, letters, used, length, position + 1);
str.deleteCharAt(str.length() - 1);
used[i] = false;
}
}
}
}
Going through permutations takes a long time. When solving problems that require looking through all the possible solutions, there are often ways to cut out many permutations, or interesting algorithms to get a solution faster.
Here's an example of a problem like this:
https://projecteuler.net/problem=67
trying all the combinations is impossible (it would take a computer 20 billion years). But using an interesting algorithm, the problem can be solved in under a second.

How can I most efficiently execute this recursive/iterative CPU intensive android task?

Some Background Info: I have made a program that given an arraylist of letters, and an array of integers finds all the combinations of words that can exist inside this arraylist where the words length is one of the integers in the int array (wordSizes).
i.e. given h, o, p, n, c, i, e, t, k and the integers 5 and 4, the solution would be:
phone tick.
My problem right now:
Inputs usually are about 25 characters and the output should usually return 5 word combinations.
I originally made this a console application for dekstop, and runtimes are generally less than 1 minute.
I decided to port it to android and runtimes reach over 35 minutes. I am quite a beginner and not sure about how to run a CPU intensive task on Android.
public void findWordsLimited(ArrayList<Character> letters) {
for (String s1 : first2s) {
for (String s2 : possibleSeconds) {
boolean t = true;
String s1s2 = s1.concat(s2);
ArrayList<Character> tempLetters = new ArrayList<Character>(letters);
for (int i = 0; i < s1s2.length(); i++) {
if (tempLetters.contains(s1s2.charAt(i)))
tempLetters.remove(Character.valueOf(s1s2.charAt(i)));
else
t = false;
}
if (t) {
helperFindWordsL(tempLetters, s1 + " " + s2, 2);
}
}
}
}
public void helperFindWordsL(ArrayList<Character> letters, String prefix , int index) {
boolean r;
if (letters.size() <= 1) {
output += "Success : " + prefix + "\n";
Log.i(TAG, prefix);
}
else if (index < wordSizes.size()){
for (String s : lastCheck) {
if (s.length() == wordSizes.get(index)) {
ArrayList<Character> templetters = new ArrayList<Character>(letters);
r = true;
for (int j = 0; j < s.length(); j++) {
if (templetters.contains(s.charAt(j)))
templetters.remove(Character.valueOf(s.charAt(j)));
else {
r = false;
templetters = new ArrayList<Character>(letters);
}
}
if (r)
helperFindWordsL(templetters, prefix + " " + s, index + 1);
}
}
}
}
I am not too concerned about the algorithm, as this might be confusing because it is part of a bigger project to solve a word game puzzle.
A few questions:
How would I get a CPU intensive task like this finished fastest?
Right now I call the method findWordsLimited() from my MainActivity. On my desktop app (where it says output += Success... in HelperFindWordsL) I would print all solutions to the console, but right now I have made it so that the method adds to and in the end returns a giant string (String output) back to the MainActivity, with all solutions and that String is put inside of a TextView. Is that an inefficient way to display the data? If so, could you please help explain a better way?
Should I be running this as a backgroud/foreground process or thread instead of just calling it from the MainActivity?
How can i get runtimes on my android that are currently 20x slower than my desktop faster?
Try to replace recursion with cycles, and use arrays instead of lists, to avoid inserts etc, direct access to array members is much faster. Pay main attention to the most inner loop which uses templetters.contains(s.charAt(j)), optimization of this part of code will give main effect.
You may add break; after t = false;
String s1s2 = s1.concat(s2); - it's not good to create a new String object for such case - it makes unnecessary work for GC. I would replace it with 2 cycles through s1 then s2
You could use 'letters' instead of ArrayList<Character> tempLetters = new ArrayList<Character>(letters);, just marking some items there as deleted. No need to create local clones.

How to calculate a arithmetic expression (String) and return the answer?

I know how to calculate easy expression without variables. But how to do, when in line we have expression with "x"?
For example
(x+1)*(x-1)
In this example program should to return: x^2 - 1
It's a non-trivial endeavor. I would strongly suggest you look at what's out there. For example Symja
You might want to look at the scripting feature of java. It seems that you can execute Javascript (or other scripting languages) from Java using this scripting engine.
You will find some examples at https://today.java.net/pub/a/today/2006/04/11/scripting-for-java-platform.html.
What you are asking for, is letting a program transform (and possibly solve) mathematical equations. This is of course possible and there are tools and certainly APIs around which do it, but it's definitely beyond hacking a java program by your own.
In case you just like to calculate the result of a given formula, then this is doable. Interestingly, you can just throw an equation at Google (e.g. (5 + 3) * (8-4)) and it will give you the result. So, why not just use it? ;-)
When we go to the interview they asking the this logical type of question. i to met the same problem. but i couldn't able to success the interview because this type of questions. Later i found the result of my own after i search in in the internet. Friends who are all want to do this..
follow this operation. i will give this full of free.
I will enter the equation as string Like.
a*b*c+d/m-x.
get this equation as string object. and use following functions.#
public void calc() throws IOException
{
String equation,store,get;
StringBuilder sb= new StringBuilder();
DataInputStream dis= new DataInputStream(System.in);
System.out.println("Enter the equation");
equation= dis.readLine();
equation="%"+equation+"%";
byte[] buf= equation.getBytes();
for(int i=0;i<equation.length();i++)
{
if(buf[i]>=97&&buf[i]<=122)
{
System.out.println("Enter the value for "+(char)buf[i]);
get=dis.readLine();
sb.append(get);
}
else
sb.append((char)buf[i]);
}
store= sb.toString();
char[] buf1= new char[25];
for(int i=0;i<store.length();i++)
{
buf1[i]=store.charAt(i);
}
for(int i=0;i<buf1.length;i++)
{
no.append(buf1[i]);
}
System.out.println(no.toString());
int m,n=0;
for(int i=0;i<no.length()-1;i++)
{
if('/'==no.charAt(i))
{
leftCount=rightCount=0;
m=findLeftValue(i-1) / findRightValue(i+1);
no.replace(i-leftCount, i+rightCount+1, String.valueOf(m));
i=0;
}
}
for(int i=0;i<no.length()-1;i++)
{
if('*'==no.charAt(i))
{
leftCount=rightCount=0;
m=findLeftValue(i-1) * findRightValue(i+1);
no.replace(i-leftCount, i+rightCount+1, String.valueOf(m));
i=0;
}
}
for(int i=0;i<no.length()-1;i++)
{
if('+'==no.charAt(i))
{
leftCount=rightCount=0;
m=findLeftValue(i-1) + findRightValue(i+1);
no.replace(i-leftCount, i+rightCount+1, String.valueOf(m));
i=0;
}
}
for(int i=0;i<no.length()-1;i++)
{
if('-'==no.charAt(i))
{
leftCount=rightCount=0;
m=findLeftValue(i-1) - findRightValue(i+1);
no.replace(i-leftCount, i+rightCount+1, String.valueOf(m));
i=0;
}
}
for(int i=0;i<no.length();i++)
{
if('%'==no.charAt(i))
{
no.deleteCharAt(i);
i=0;
}
}
System.out.println(no.toString());
}
public int findLeftValue(int i)
{
StringBuilder sb= new StringBuilder();
int x=0;
while(no.charAt(i)!='*'&&no.charAt(i)!='+'&&no.charAt(i)!='-'&&no.charAt(i)!='/' &&no.charAt(i)!='%')
{
leftCount++;
sb.insert(0, no.charAt(i));
i--;
}
x=Integer.parseInt(sb.toString());
return x;
}
public int findRightValue(int i)
{
StringBuilder sb= new StringBuilder();
int x;
while(no.charAt(i)!='*'&&no.charAt(i)!='+'&&no.charAt(i)!='-'&&no.charAt(i)!='/' &&no.charAt(i)!='%')
{
rightCount++;
sb.append(no.charAt(i));
i++;
}
x=Integer.parseInt(sb.toString());
return x;
}
here may be unused variable may be there.please find and remove it.
I didn't set any preferences to the calculation. just i made up with the flow. if you change the flow the answer will be different. so, Keep in mind. and you can do the same for different operators also.
And One more thing is that, Please verify the equation before proceeding the function. because, it will not check whether the equation is correct or wrong.(a+*d++c). it is not correct equation.
The equation should be correct format.. Like a+b*c-d/x.
Enjoy ..Break the interview and get your correct job..

Generate formatted diff output in Java

Are there any libraries out there for Java that will accept two strings, and return a string with formatted output as per the *nix diff command?
e.g. feed in
test 1,2,3,4
test 5,6,7,8
test 9,10,11,12
test 13,14,15,16
and
test 1,2,3,4
test 5,6,7,8
test 9,10,11,12,13
test 13,14,15,16
as input, and it would give you
test 1,2,3,4 test 1,2,3,4
test 5,6,7,8 test 5,6,7,8
test 9,10,11,12 | test 9,10,11,12,13
test 13,14,15,16 test 13,14,15,16
Exactly the same as if I had passed the files to diff -y expected actual
I found this question, and it gives some good advice on general libraries for giving you programmatic output, but I'm wanting the straight string results.
I could call diff directly as a system call, but this particular app will be running on unix and windows and I can't be sure that the environment will actually have diff available.
java-diff-utils
The DiffUtils library for computing
diffs, applying patches, generationg
side-by-side view in Java
Diff Utils library is an OpenSource
library for performing the comparison
operations between texts: computing
diffs, applying patches, generating
unified diffs or parsing them,
generating diff output for easy future
displaying (like side-by-side view)
and so on.
Main reason to build this library was
the lack of easy-to-use libraries with
all the usual stuff you need while
working with diff files. Originally it
was inspired by JRCS library and it's
nice design of diff module.
Main Features
computing the difference between two texts.
capable to hand more than plain ascci. Arrays or List of any type that
implements hashCode() and equals()
correctly can be subject to
differencing using this library
patch and unpatch the text with the given patch
parsing the unified diff format
producing human-readable differences
I ended up rolling my own. Not sure if it's the best implementation, and it's ugly as hell, but it passes against test input.
It uses java-diff to do the heavy diff lifting (any apache commons StrBuilder and StringUtils instead of stock Java StringBuilder)
public static String diffSideBySide(String fromStr, String toStr){
// this is equivalent of running unix diff -y command
// not pretty, but it works. Feel free to refactor against unit test.
String[] fromLines = fromStr.split("\n");
String[] toLines = toStr.split("\n");
List<Difference> diffs = (new Diff(fromLines, toLines)).diff();
int padding = 3;
int maxStrWidth = Math.max(maxLength(fromLines), maxLength(toLines)) + padding;
StrBuilder diffOut = new StrBuilder();
diffOut.setNewLineText("\n");
int fromLineNum = 0;
int toLineNum = 0;
for(Difference diff : diffs) {
int delStart = diff.getDeletedStart();
int delEnd = diff.getDeletedEnd();
int addStart = diff.getAddedStart();
int addEnd = diff.getAddedEnd();
boolean isAdd = (delEnd == Difference.NONE && addEnd != Difference.NONE);
boolean isDel = (addEnd == Difference.NONE && delEnd != Difference.NONE);
boolean isMod = (delEnd != Difference.NONE && addEnd != Difference.NONE);
//write out unchanged lines between diffs
while(true) {
String left = "";
String right = "";
if (fromLineNum < (delStart)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum < (addStart)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append(" "); // no operator to display
diffOut.appendln(right);
if( (fromLineNum == (delStart)) && (toLineNum == (addStart))) {
break;
}
}
if (isDel) {
//write out a deletion
for(int i=delStart; i <= delEnd; i++) {
diffOut.append(StringUtils.rightPad(fromLines[i], maxStrWidth));
diffOut.appendln("<");
}
fromLineNum = delEnd + 1;
} else if (isAdd) {
//write out an addition
for(int i=addStart; i <= addEnd; i++) {
diffOut.append(StringUtils.rightPad("", maxStrWidth));
diffOut.append("> ");
diffOut.appendln(toLines[i]);
}
toLineNum = addEnd + 1;
} else if (isMod) {
// write out a modification
while(true){
String left = "";
String right = "";
if (fromLineNum <= (delEnd)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum <= (addEnd)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append("| ");
diffOut.appendln(right);
if( (fromLineNum > (delEnd)) && (toLineNum > (addEnd))) {
break;
}
}
}
}
//we've finished displaying the diffs, now we just need to run out all the remaining unchanged lines
while(true) {
String left = "";
String right = "";
if (fromLineNum < (fromLines.length)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum < (toLines.length)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append(" "); // no operator to display
diffOut.appendln(right);
if( (fromLineNum == (fromLines.length)) && (toLineNum == (toLines.length))) {
break;
}
}
return diffOut.toString();
}
private static int maxLength(String[] fromLines) {
int maxLength = 0;
for (int i = 0; i < fromLines.length; i++) {
if (fromLines[i].length() > maxLength) {
maxLength = fromLines[i].length();
}
}
return maxLength;
}
Busybox has a diff implementation that is very lean, should not be hard to convert to java, but you would have to add the two-column functionality.
http://c2.com/cgi/wiki?DiffAlgorithm I found this on Google and it gives some good background and links. If you care about the algorithm beyond just doing the project, a book on basic algorithm that covers Dynamic Programming or a book just on it. Algorithm knowledge is always good:)
You can use Apache Commons Text library to achieve this. This library provides 'diff' capability based on "very efficient algorithm from Eugene W. Myers".
This provides you ability to create your own visitor so that you can process the diff in the way you want & may be output to console or HTML etc. Here is one article which walks through nice & simple example to output side by side diff in HTML format using Apache Commons Text library & simple Java code.

Categories

Resources