Converting an iterative function to recursive - java

I am trying to convert an iterative function to Recursion.
But once I tried to do that it is runnning continuously like an infinite loop.
This is my iterative code
private static Node buildModelTree(String[] args) {
// TODO Auto-generated method stub
String clsIndex = args[3];
splitted.add(currentsplit);
double entropy = 0;
int total_attributes = (Integer.parseInt(clsIndex));// class index
int split_size = splitted.size();
GainRatio gainObj = new GainRatio();
while (split_size > current_index) { //iterate through all distinct pair for building children
currentsplit = (SplitInfo) splitted.get(current_index);
System.out.println("After currentsplit --->" + currentsplit);
gainObj = new GainRatio();
int res = 0;
res = ToolRunner.run(new Configuration(),new CopyOfFunID3Driver(), args);
gainObj.getcount(current_index);
entropy = gainObj.currNodeEntophy();
clsIndex = gainObj.majorityLabel();
currentsplit.classIndex = clsIndex;
if (entropy != 0.0 && currentsplit.attr_index.size() != total_attributes) { //calculate gain ration
bestGain(total_attributes,entropy,gainObj);
} else {
//When entropy is zero build tree
Node branch = new Node();
String rule = "";
Gson gson = new Gson();
int temp_size = currentsplit.attr_index.size();
for (int val = 0; val < temp_size; val++) {
int g = 0;
g = (Integer) currentsplit.attr_index.get(val);
if (val == 0) {
rule = g + " " + currentsplit.attr_value.get(val);
//JSON
// branch.add(g, currentsplit.attr_value.get(val).toString(), new Node(currentsplit.classIndex, true));
} else {
rule = rule + " " + g + " "+ currentsplit.attr_value.get(val);
//branch.add(g, currentsplit.attr_value.get(val).toString(), buildModelTree(args));
}
}
rule = rule + " " + currentsplit.classIndex;
}
split_size = splitted.size();
current_index++;
}
}
where all should I make change?
I am trying to build tree. So inoredr to get the tree structure I am trying to make my id3 code recursive.
with my current code I am only getting output as this ,But I want it as tree structure
Please suggest.

The Recursion algorithm must have following
1.Each time the function invokes itself, the Problem size has to be reduced.
(ie. If suppose first you are calling the function with array of size n, then the next time it has to be lesser than n.
Base Case - the condition for the return statement.
(For example, if the array size is 0 then return)
In your code, these two are missing.
You're keep on calling the function with the same size of array. That's the problem.
Thanks

Related

Creating triple-ended queue with efficient random access

I have been tasked to solve a question concerning the creation of a triple-ended queue with efficient random access, as outlined in this: https://open.kattis.com/problems/teque. I created a program based around using 2 very large arrays, one containing the front half of all stored integers so far and the other the back half, with both being of the same size or the front half containing at most 1 more element than the back half after every insertion operation. This should allow all insertion and retrieval operations to be of O(1) time complexity, but the code just keeps exceeding the given time limit. Can anyone tell me what is wrong with my code? Here it is:
import java.util.*;
import java.io.*;
public class Teque3 {
static int[] front = new int[1_000_000];
static int[] back = new int[1_000_000];
static int frontHead = 499_999;
static int backHead = 499_999;
static int frontSize = 0;
static int backSize = 0;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
for (int i = 0; i < n; i++) {
String[] line = br.readLine().split(" ");
if (line[0].equals("get")) {
int index = Integer.parseInt(line[1]);
if (index >= frontSize) System.out.println(back[backHead + index - frontSize]);
else System.out.println(front[frontHead + index]);
continue;
}
if (frontSize == backSize) {
if (line[0].equals("push_front")) {
frontHead--;
front[frontHead] = Integer.parseInt(line[1]);
frontSize++;
} else if (line[0].equals("push_back")) {
back[backHead + backSize] = Integer.parseInt(line[1]);
front[frontHead + frontSize] = back[backHead];
frontSize++;
backHead++;
} else if (line[0].equals("push_middle")) {
front[frontHead + frontSize] = Integer.parseInt(line[1]);
frontSize++;
}
} else {
if (line[0].equals("push_front")) {
frontHead--;
front[frontHead] = Integer.parseInt(line[1]);
backHead--;
back[backHead] = front[frontHead + frontSize];
backSize++;
} else if (line[0].equals("push_back")) {
back[backHead + backSize] = Integer.parseInt(line[1]);
backSize++;
} else if (line[0].equals("push_middle")) {
backHead--;
back[backHead] = Integer.parseInt(line[1]);
backSize++;
}
}
}
}
}
You could try to minimze IO-Operations: Collect your programm output. Instead of writing System.out.println better create a new StringBuilder to collect everything. In the end write all at once.
static StringBuilder result = new StringBuilder();
...
private static void result(int value) {
result.append(value).append("\n");
}
...
if (index >= frontSize) result(back[backHead + index - frontSize]);
else result(front[frontHead + index]);
...
System.out.println(result);
Decouple read from parse and process: Create one thread for reading the operations. But the operations in a Queue. Start another thread for the process.

How to sort a linked list with objects and private variables

I am going to be honest and up front here. This is homework, but I have become desperate and am looking for anyone to assist me. I have been working on this off and on for over a month and have gone to my instructor multiple times. Basically this program needs to create and sort a linked list that has an int, string and double in each node. It needs to be able to sort by each data type as well as print in input order but once I figure one out I can transfer it to the other data types. Please, everything needs to be "hand made", please do not use any built in commands as I need to create everything as per my instructor's demands.
I attempted to make the linked list and then sort it, but I ran into a problem so I decided to try and sort the list as I create it.
For example: Input the first node, then input the next node in front/behind the first, then put the next where it needs to go... and so forth.
Here is my code (I only focus on the strings):
String repeat = "y";
list1 fChr = null;
list1 p = fChr;
list1 copy = null;
//list1 dCopy = null;
//list1 iCopy = null;
list1 fd = fChr;//front of the double list
list1 fi = fChr;//front of the integer list
list1 fStr = fChr;//front of the string list~
list1 pStr = fStr;
boolean inserted = false;
int iii = 0;
String sss = "";
double ddd = 0.0;
while(repeat.equals("y"))//while the user agrees to adding a new node
{
if(fChr == null)// if the front is empty
{
fChr = new list1();//create a new node by calling object and sets it as the front
p = fChr;
copy = fChr;
sss = fChr.GetS();
iii = fChr.GetI();
ddd = fChr.GetD();
copy.SetS(sss);
copy.SetI(iii);
copy.SetD(ddd);
System.out.println("(1)");
}
else
{
System.out.println("(2)");
if(p!=null)
{
System.out.println("p = "+ p.GetS());
if(p.next != null)
{
System.out.println("p.next = "+ p.next.GetS());
System.out.println("p.next.next = "+ p.next.next.GetS());
}
}
p = fChr;
while(p.next != null)//finds the end of the Linked list
{
System.out.println("(3)");
p = p.next;//moves the pointer p down the list
}
list1 NextNode = new list1();//
p.next = NextNode;
sss = NextNode.GetS();
iii = NextNode.GetI();
ddd = NextNode.GetD();
copy = NextNode;
String gg = "hi";//tests to see if the setter is actually changing the value inside copy(it is not, it prints b)
copy.SetS(gg);
copy.SetI(iii);
copy.SetD(ddd);
System.out.println(copy.GetS());
System.out.println("p = "+ p.GetS());
}
pStr = fStr;
//System.out.println(copy.GetS()+"*");
inserted = false;
if(fStr == null)
{
System.out.println("(4)");
fStr = copy;//fStr = fChr;
inserted = true;
//System.out.println("p.next.next = "+ p.next.next.GetS());
}
else if(copy.GetS().compareTo(fStr.GetS()) < 0)
{
System.out.println("(5)");
//System.out.println("1)p.next.next = "+ p.next.next.GetS());
copy.next = fStr;//ERROR ON THIS LINE
System.out.println("2)p.next.next = "+ p.next.next.GetS());
System.out.println("fChr.next: "+fChr.next.GetS());
fStr = copy;
System.out.println("3)p.next.next = "+ p.next.next.GetS());
inserted = true;
System.out.println("p = "+ p.GetS());
System.out.println("p.next = "+ p.next.GetS());
System.out.println("4)p.next.next = "+ p.next.next.GetS());
}
else if(fStr.next == null && fStr != null)
{
System.out.println("(6)");
fStr.next = copy;
inserted = true;
}
else
{
System.out.println("(7)");
pStr = fStr;
System.out.println("RIP (8)");
while(pStr.next != null && inserted == false)
{
System.out.println("(9)");
System.out.println("RIP");
if(copy.GetS().compareTo(pStr.next.GetS()) < 0)//if it goes between 2 nodes
{
System.out.println("(10)");
copy.next = pStr.next;
pStr.next = copy;
inserted = true;
}
else
{
System.out.println("(11)");
pStr = pStr.next;
}
if(pStr.next == null && inserted == false)// it goes at the end(not necessary bc of the (in order) part)
{
System.out.println("(12)");
pStr.next = copy;
}
}
}
repeat = JOptionPane.showInputDialog("Would you like to add a node [y/n]");
System.out.println("End of Loop");
}
System.out.println(fStr.GetS());
PrintMenu(fChr, fi, fd, fStr);// sends the user to the menu screen
}
From all of my print statements I have (what I think) found the problem. This code runs through twice and upon hitting "y" for the third time, prints "(3)" in an infinite loop. I have found that (say the input for the strings is "c" then "b") "p" is equal to "c", p.next is equal to "b" and p.next.next is equal to "c". So, p is in an infinite loop. I have no idea why it does this, I have a theory that it could be because the front(fChr) changes and then "p" points to it and is just kinda drug along. I also just realized that me trying to set "copy" equal to "NextNode" was unsuccessful and copy just holds the value inside p.next(which is NextNode). That seems correct, but when I try to put something else in, it doesn't work. I could be testing this incorrectly and in that case the setter is correct. Setting is one of the main problems that I seem to be having. I will try to answer as many questions as I can if anyone has any.
Also here is the object in case you would like to see it. Thank you for your time, any help will be appreciated. Please if possible try to keep it relatively simple this is a high school assignment and I am so close and am stumped on how to fix what is wrong. Also, you may have noticed, but I have to use private variables. I am not asking for someone to give me a program that works, I am just asking if you know why what is going wrong is happening and if you know how to fix it. Thank you from the bottom of my heart!
import javax.swing.JOptionPane;
public class list1
{
private int i;
private String s;
private double d;
private String ss = null;
private int ii = 0;
private double dd = 0.0;
list1 next = null;
public list1()
{
String str;
s=JOptionPane.showInputDialog("Enter a String");
String temp =JOptionPane.showInputDialog("Enter an Integer");
i = Integer.parseInt(temp);
String temp2 =JOptionPane.showInputDialog("Enter a Double");
d = Double.parseDouble(temp2);
}
public double GetD()
{
return d;
}
public String GetS()
{
return s;
}
public int GetI()
{
return i;
}
public void SetS(String x)
{
ss = x;
}
public void SetI(int y)
{
ii = y;
}
public void SetD(double z)
{
dd = z;
}
}

Convert recursive function into the non-recursive function

Is it possible to convert the function go into the non-recursive function? Some hints or a start-up sketch would be very helpful
public static TSPSolution solve(CostMatrix _cm, TSPPoint start, TSPPoint[] points, long seed) {
TSPSolution sol = TSPSolution.randomSolution(start, points, seed, _cm);
double t = initialTemperature(sol, 1000);
int frozen = 0;
System.out.println("-- Simulated annealing started with initial temperature " + t + " --");
return go(_cm, sol, t, frozen);
}
private static TSPSolution go(CostMatrix _cm, TSPSolution solution, double t, int frozen) {
if (frozen >= 3) {
return solution;
}
i++;
TSPSolution bestSol = solution;
System.out.println(i + ": " + solution.fitness() + " " + solution.time() + " "
+ solution.penalty() + " " + t);
ArrayList<TSPSolution> nHood = solution.nHood();
int attempts = 0;
int accepted = 0;
while (!(attempts == 2 * nHood.size() || accepted == nHood.size()) && attempts < 500) {
TSPSolution sol = nHood.get(rand.nextInt(nHood.size()));
attempts++;
double deltaF = sol.fitness() - bestSol.fitness();
if (deltaF < 0 || Math.exp(-deltaF / t) > Math.random()) {
accepted++;
bestSol = sol;
nHood = sol.nHood();
}
}
frozen = accepted == 0 ? frozen + 1 : 0;
double newT = coolingSchedule(t);
return go(_cm, bestSol, newT, frozen);
}
This is an easy one, because it is tail-recursive: there is no code between the recursive call & what the function returns. Thus, you can wrap the body of go in a loop while (frozen<3), and return solution once the loop ends. And replace the recursive call with assignments to the parameters: solution=bestSol; t=newT;.
You need to thinkg about two things:
What changes on each step?
When does the algorithm end?
Ans the answer should be
bestSol (solution), newT (t), frozen (frozen)
When frozen >= 3 is true
So, the easiest way is just to enclose the whole function in something like
while (frozen < 3) {
...
...
...
frozen = accepted == 0 ? frozen + 1 : 0;
//double newT = coolingSchedule(t);
t = coolingSchedule(t);
solution = bestSol;
}
As a rule of thumb, the simplest way to make a recursive function iterative is to load the first element onto a Stack, and instead of calling the recursion, add the result to the Stack.
For instance:
public Item recursive(Item myItem)
{
if(myItem.GetExitCondition().IsMet()
{
return myItem;
}
... do stuff ...
return recursive(myItem);
}
Would become:
public Item iterative(Item myItem)
{
Stack<Item> workStack = new Stack<>();
while (!workStack.isEmpty())
{
Item workItem = workStack.pop()
if(myItem.GetExitCondition().IsMet()
{
return workItem;
}
... do stuff ...
workStack.put(workItem)
}
// No solution was found (!).
return myItem;
}
This code is untested and may (read: does) contain errors. It may not even compile, but should give you a general idea.

libsvm classifying - at bad stage so far

Problem: I have certain set of data to be classified - Useful(1)/Useless(0). I will provide full set of data as input for training purpose of the classifier. and test with different data set.
For this, I am trying to convert my data to LIBSVM format. before doing anything, I thought of providing numeric input of one vector and check the result.
Input:
Training: 1 1 2 (the first 1 indicates useful Class in this vector followed by numeric input)
Testing: 1 1 2(I am not sure of input data format)
Output:
(0:0.9982708183417436)(1:0.0017291816582564153)(Actual:1.0 Prediction:0.0)
I dont have class 0 in training set, but it has probEstimated for class 0.
I am not really sure of how to convert my data to numeric vector input and fetch the data from the numeric test data set to equivalent Data as supplied. ANY HELP IN THIS REGARD IS HIGHLY APPRECIATED.
Planned tasks:
1. Load all the data to Hash tables and get the keys to be saved in data sets with respective classifier - USEFUL(1).
2. Supply the data set to the svmTrain and get the model.
3. Prepare test data set(Convert each word/phrase to respective numeric value saved training set, if found. Else, assign a new value).
4. Supply the test set and model to the SVM's EVALUATE method.
5. Get the resultant vectors from the USEFUL class and re-map to the data.
Code: used from different sources.
public class Datatosvmformat {
static double[][] train = new double[1000][3];
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<String, Integer> dataSet = new HashMap<String, Integer>();
double[][] test = new double[10][3];
train[1][0] = 1;
train[1][1] = 1;
train[1][2] = 2;
svm_model model = svmTrain();
//Test Data Set
double[] test1 = new double[3];
test1[0] = 1;
test1[1] = 1;
test1[2] = 2;
evaluate(test1,model);
}
private static svm_model svmTrain() {
svm_problem prob = new svm_problem();
int dataCount = train.length;
prob.y = new double[dataCount];
prob.l = dataCount;
prob.x = new svm_node[dataCount][];
for (int i = 0; i <dataCount; i++){
double[] features = train[i];
//ystem.out.println("Features "+features[i]);
prob.x[i] = new svm_node[features.length-1];
for (int j = 1; j < features.length; j++){
svm_node node = new svm_node();
node.index = j;
node.value = features[j];
prob.x[i][j-1] = node;
}
prob.y[i] = features[0];
}
svm_parameter param = new svm_parameter();
param.probability = 1;
param.gamma = 0.5;
param.nu = 0.5;
param.C = 1;
param.svm_type = svm_parameter.C_SVC;
param.kernel_type = svm_parameter.LINEAR;
param.cache_size = 20000;
param.eps = 0.001;
svm_model model = svm.svm_train(prob, param);
return model;
}
public static double evaluate(double[] features, svm_model model)
{
svm_node[] nodes = new svm_node[features.length-1];
for (int i = 1; i < features.length; i++)
{
svm_node node = new svm_node();
node.index = i;
node.value = features[i];
nodes[i-1] = node;
}
int totalClasses = 2;
int[] labels = new int[totalClasses];
svm.svm_get_labels(model,labels);
double[] prob_estimates = new double[totalClasses];
double v = svm.svm_predict_probability(model, nodes, prob_estimates);
for (int i = 0; i < totalClasses; i++){
System.out.print("(" + labels[i] + ":" + prob_estimates[i] + ")");
}
System.out.println("(Actual:" + features[0] + " Prediction:" + v + ")");
return v;
}
}
I'm not completely sure, but the problem could be due to the fact that you need to mark positive examples with +1 and negative examples with -1.
Otherwise, the libsvm software could asssign an arbitraty class (e.g. 0) to the training vector 1 1 2, since it iterprets the first elem of the feature vector as a feature value (and not the label class).
So try to change the class label 1 in +1 for positive examples (and -1 for negative examples).
Usually, for data format for libsvm is the following:
<label> <index1>:<value1> <index2>:<value2>
where:
label is the class label (e.g. +1/-1)
indexN is the feature Id (i.e. the number that identified a certain feature)
valueN is the feature value (i.e. the value assigned to the specified feature: 0/1 for binary features or 0,1,2,... for categorical features)
An example of the data format accepted by the libsvm tool can be found at this page:
LIBSVM Data: Classification (Binary Class)
There are many datasets that you can explore in order to understand the data format accepted by the libsvm tool.

Find Range of a number from an array

I'm just rephrasing the question I asked a little while ago.
I have a sorted array {2.0,7.8,9.0,10.5,12.3}
If I given an input 9.5
What is the fastest way to find 9.0 and 10.5 to indicate that 9.5 is in between 9.0 and 10.5 (9.5 >=9.0 and <10.5) ?
Is binary search an option?But since the input need not be in the array.I'm not sure how I should do this.
Also If there is any other data structure that is suitable please comment.
A binary search would certainly be the "standard" approach - http://en.wikipedia.org/wiki/Binary_search_algorithm. Speed is O(log(N)) as opposed to linear.
In certain specialised cases you can do better than O(log(N)). But unless you are dealing with truly gigantic array sizes and satisfy these special cases then your binary search is really the fastest approach.
You could use Arrays.binarySearch to quickly locate 9.0 and 10.0, indeed.
Here's a binary search algorithm I just wrote for you that does the trick:
import java.util.Random;
public class RangeFinder {
private void find(double query, double[] data) {
if (data == null || data.length == 0) {
throw new IllegalArgumentException("No data");
}
System.out.print("query " + query + ", data " + data.length + " : ");
Result result = new Result();
int max = data.length;
int min = 0;
while (result.lo == null && result.hi == null) {
int pos = (max - min) / 2 + min;
if (pos == 0 && query < data[pos]) {
result.hi = pos;
} else if (pos == (data.length - 1) && query >= data[pos]) {
result.lo = pos;
} else if (data[pos] <= query && query < data[pos + 1]) {
result.lo = pos;
result.hi = pos + 1;
} else if (data[pos] > query) {
max = pos;
} else {
min = pos;
}
result.iterations++;
}
result.print(data);
}
private class Result {
Integer lo;
Integer hi;
int iterations;
long start = System.nanoTime();
void print(double[] data) {
System.out.println(
(lo == null ? "" : data[lo] + " <= ") +
"query" +
(hi == null ? "" : " < " + data[hi]) +
" (" + iterations + " iterations in " +
((System.nanoTime() - start) / 1000000.0) + " ms. )");
}
}
public static void main(String[] args) {
RangeFinder rangeFinder = new RangeFinder();
// test validation
try {
rangeFinder.find(12.4, new double[] {});
throw new RuntimeException("Validation failed");
} catch (IllegalArgumentException e) {
System.out.println("Validation succeeded");
}
try {
rangeFinder.find(12.4, null);
throw new RuntimeException("Validation failed");
} catch (IllegalArgumentException e) {
System.out.println("Validation succeeded");
}
// test edge cases with small data set
double[] smallDataSet = new double[] { 2.0, 7.8, 9.0, 10.5, 12.3 };
rangeFinder.find(0, smallDataSet);
rangeFinder.find(2.0, smallDataSet);
rangeFinder.find(7.9, smallDataSet);
rangeFinder.find(10.5, smallDataSet);
rangeFinder.find(12.3, smallDataSet);
rangeFinder.find(10000, smallDataSet);
// test performance with large data set
System.out.print("Preparing large data set...");
Random r = new Random();
double[] largeDataSet = new double[20000000];
largeDataSet[0] = r.nextDouble();
for (int n = 1; n < largeDataSet.length; n++) {
largeDataSet[n] = largeDataSet[n - 1] + r.nextDouble();
}
System.out.println("done");
rangeFinder.find(0, largeDataSet);
rangeFinder.find(5000000.42, largeDataSet);
rangeFinder.find(20000000, largeDataSet);
}
}
I would do it like that
double valuebefore = 0;
double valueafter = 0;
double comparevalue = 9;
foreach (var item in a)
{
valueafter = item;
if (item > comparevalue)
{
break;
}
valuebefore = item;
}
System.Console.WriteLine("Befor = {0} After = {1}", valuebefore, valueafter);
If the input numbers are in an array then binary search will be handy. Every time the search fails, indicating the number is not present in the array, the array elements at index low and high will give you the range.
The most efficient (space and time-wise) is to implement this as a modified binary search.
A simple (but less efficient) solution is to replace the array with a NavigableMap<Double, Double> and use floorKey and ceilingKey to find the bounding values. Assuming that you use a TreeMap, this has the same complexity as binary search.
For small numbers of bins a sorted linked list will be most elegant. You scan over it and when you find a number bigger you have the range.
For very large numbers it is worth putting them in a BTree or similar Tree structure in order to get O(log(N)) performance.
In Java you can use a TreeSet for this.
lowerBound = boundaries.headSet(yourNumber).last();
upperBound = boundaries.tailSet(yourNumber).first();
or similar will be O(logN) for large numbers.

Categories