Array Shuffle (With same Start and end Value) - java

I'm currently working on a Travelling salesman problem and i'm having trouble generating random paths with the same start and end value
This is my current path(path of cities visited)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 38 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 14 39 40 41 42 43 44 45 46 47 48 49 50 51 0
See how the last node arrives back at 0(TSP logic)
Now i'm trying to shuffle this array randomly because random start points generate better results then others However I know how to shuffle the array using Collections but that would shuffle every value randomly
Basically i'm trying to create a method to shuffle an array randomly WITH THE EXCEPTION THE START and END VALUES must be the same and every number must be distinct 0-51
This is my current code, it basically shuffles the array and sets the last index to the first index
static void shuffleArray(int[] ar)
{
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
ar[ar.length-1]=ar[0];
}
however this is giving me duplicate values for some reason

Could you not remove the start and end position, shuffle the array, and then add the start and end position again?

Related

How to split multiple tab delimited lines in Java if they all have a different number of columns?

I have a text file which is tab delimited, but there are a different number of columns on each line. Here is an example:
1 : 2 16 17 24 31 34 40 41 45 47 48
2 : 1 3 4 5 6 7 8 13 18 20 22 28 33 35 37 38 42 44 46 49
3 : 2 10 12 16 17 19 24 25 29 31 34 40 41 45
I want to use the split function, like I did here for a different assignment:
String[] words = line.split("\t");
col1 = Integer.parseInt(words[0]);
col2 = Integer.parseInt(words[1]);
col3 = Integer.parseInt(words[2]);
col4 = Integer.parseInt(words[3]);
This puts each column from a line into a different variable. I want to do the same but I'm not sure how to do this with a varying number of columns.
As said in the comments, you're quite good with what you've done. If you really want to have your Integer values stored somehow, you could simply use an Integer array, and fill it with a loop like this:
String[] words = line.split("\t");
int[] numbers = new int[words.length];
for (int i = 0; i < words.length; i++)
{
numbers[i] = Integer.parseInt(words[i]);
}
That whole thing being inside the loop you use to iterate your lines.
I don't think you need anything more complex than an array.

Memory error in java

I am trying to code in java prime number algorithm. I am trying to face the problems with the integer and long size. My simply code is the following which works until a limit for n:
public static long f(int n) {
if (n == 1 || n == 2)
return 1;
else {
long value = f(n-2) + f(n-1);
return value;
}
}
If in my main I ll give 50 for example my code will be crushed, I am guessing due to the size of the outcome. I ve got also another approach which I am struggle to understand it, which is the following:
private static long[] cache = new long[60];
public static long f(int n) {
if (n == 1 || n == 2)
return 1;
else if (cache[n] > 0)
return cache[n];
else {
long value = f(n-2) + f(n-1);
cache[n] = value;
return value;
}
}
With this approach everything works fine whatever is the n, my issue is that I cannot get the difference.
By "crushed" you mean that the computation runs very long. The reason is that the same call is made many times. If you add this to your method:
static long count;
public static long f(int n) {
count++;
...
you'll see how many times the method is executed. For f(50), it is actually calling the method 25,172,538,049 times, which runs in 41 seconds in my machine.
When you cache the result of previous invocations, called memoization, you eliminate all the redundant calls, e.g. f(40) = f(39) + f(38), but f(39) = f(38) + f(37), so f(38) is called twice. Remembering the result of f(38) means that subsequent invocation has the answer immediately, without having to redo the recursion.
Without memoization, I get this:
n f(n) count time(ns)
== ============== =============== ==============
1 1 1 6,273
2 1 1 571
3 2 3 855
4 3 5 1,141
5 5 9 1,425
6 8 15 1,140
7 13 25 1,996
8 21 41 2,851
9 34 67 7,413
10 55 109 16,536
11 89 177 8,839
12 144 287 19,103
13 233 465 21,098
14 377 753 11,405
15 610 1,219 5,703
16 987 1,973 9,979
17 1,597 3,193 21,099
18 2,584 5,167 32,788
19 4,181 8,361 35,639
20 6,765 13,529 57,307
21 10,946 21,891 91,521
22 17,711 35,421 147,687
23 28,657 57,313 237,496
24 46,368 92,735 283,970
25 75,025 150,049 331,583
26 121,393 242,785 401,720
27 196,418 392,835 650,052
28 317,811 635,621 1,053,483
29 514,229 1,028,457 1,702,679
30 832,040 1,664,079 2,750,745
31 1,346,269 2,692,537 4,455,137
32 2,178,309 4,356,617 12,706,520
33 3,524,578 7,049,155 11,714,051
34 5,702,887 11,405,773 19,571,980
35 9,227,465 18,454,929 30,605,757
36 14,930,352 29,860,703 51,298,507
37 24,157,817 48,315,633 84,473,965
38 39,088,169 78,176,337 127,818,746
39 63,245,986 126,491,971 208,727,118
40 102,334,155 204,668,309 336,785,071
41 165,580,141 331,160,281 543,006,638
42 267,914,296 535,828,591 875,782,771
43 433,494,437 866,988,873 1,429,555,753
44 701,408,733 1,402,817,465 2,301,577,345
45 1,134,903,170 2,269,806,339 3,724,691,882
46 1,836,311,903 3,672,623,805 6,010,675,962
47 2,971,215,073 5,942,430,145 9,706,561,705
48 4,807,526,976 9,615,053,951 15,715,064,841
49 7,778,742,049 15,557,484,097 25,427,015,418
50 12,586,269,025 25,172,538,049 41,126,559,697
If you get a StackOverflowError, it is due to the recursive nature of your algorithm. The second algorithm stores known results into an array to prevent functions piling up when it asks for an already computed result.
One of the problem can be the big number result, which is more than integer limit:
fibonacci for 50 =
12,586,269,025
2,147,483,647 - int max
and the other can be due to the recursion stackoverflow like #Xalamadrax pointed.

Deletion algorithm for array

Deletion(int array[ ], int delete, int position)
So I have this method, see above, the first parameter is the name of the array, the second is the value I want deleted, and the third is the index of which it can be found. For example:
Deletion(list,50,4);
In this case, the array I chose is called list, the value I want deleted is 50, and the index of which the value is located is 4.
If we were to use Deletion(list,50,4), this method is supposed to replace the 50 at the index of 4 with the element at the index of 5 and the element at index of 5 is replaced with the element at index of 6 and so on.
If this is the array list: 90 76 55 48 50 69 66 52 87 56 89 91 86 73 50 68 52 75 54 45
The output should be: 90 76 55 48 69 66 52 87 56 89 91 86 73 50 68 52 75 54 45 45
However,I can only get it to replace the 50 but not any of the other numbers.
This is the output I get: 90 76 55 48 69 69 66 52 87 56 89 91 86 73 50 68 52 75 54 45
The 50 is replaced with the 69 but everything else stays the same, I need the other elements to "shift" to the left.
Here is my code so far for the Deletion method:
for (int i=array.length-1; i<position; i ++)
array[i] = array[ i+1];
array[position] = array[position+1]
The length of the list is 20, subtract 1, so i = 19. I know 19 is not less than 4 so it skips the for loop, but if I made it i > position, I get this error:
java.lang.ArrayIndexOutOfBoundsException: 20
So this is where I'm stuck. Please help!
You need to redefine the value of i so that it is initialized as the the int value of position (so that your deletion/replacement process can start there).
for (int i = position; i < array.length - 2; i++)
{
array[i] = array[i+1];
}
Your i.max_value should be array.length-2 so that i will incrementally increase until the end of the array. It shouldn't be -1 since you are essentially deleting the last index of your array (as the value has nothing)
You'd better be using System.arraycopy instead on implementing your own algorithm for moving array elements. Like this:
System.arraycopy(array, position+1, array, position, array.length-position);
Also see this question: Delete item from array and shrink array

Got wrong output in my task, cant solve it

Hello i got one task to do. output should be like this:
{
0
0 1
0 2 4
0 3 6 9
0 4 8 12 16
0 5 10 15 20 25
0 6 12 18 24 30 36
0 7 14 21 28 35 42 49
0 8 16 24 32 40 48 56 64
0 9 18 27 36 45 54 63 72 81
}
I tried to do it: here is my code:
public class ContnueUzOznakoMojNacin
{
public static void main(String args[])
{
int k=0, v=0;
int j;
for(int i=0;i<10;i++)
{
for(j=10-i;j<10;j++)
{
System.out.print(v+" ");
v+=k;
}
System.out.println();
v=0;
k++;
}
}
}
And the output i get is wrong and i dont get it why.
here it is:
{
0
0 2
0 3 6
0 4 8 12
0 5 10 15 20
0 6 12 18 24 30
0 7 14 21 28 35 42
0 8 16 24 32 40 48 56
0 9 18 27 36 45 54 63 72
}
When i follow these loops and increments from my program i cant find mistake.
first line is ok output should be 0;
but second line, output should be 0 1; not 0 2 ?
I dont need you to give me code for this task i need you to help me to do it, to tell me where i made mistake so i do it on my own. Thanks :)
Change this line:
for(j=10-i;j<10;j++)
to this:
for(j=9-i;j<10;j++)
And here's an explanation:
So i starts at 0, right? What will be i's maximum? 9, because in for(int i=0;i<10;i++), i cannot get to 10.
Let's look at how that affects for(j=10-i;j<10;j++). If i is 9 (the last row), then the j loop will only run 9 times. j will equal 1,2,3,4,5,6,7,8,9. That's only 9 loops. If you look at the bottom of the upper triangle, you can see that 0 9 18 27 36 45 54 63 72 has only 9 numbers.
We want j to run 10 times, as you can see by the base of the correct triangle: 0 9 18 27 36 45 54 63 72 81. How do we do this? We make j run one more time on every i loop, by decreasing the starting number (10-i) by one (which equals 9-i). That is how you arrive at
for(j=9-i;j<10;j++)

java random generator without repeat

Im trying to generate a 2d array using a random generator. basically, each column should contain a random value between 1-50 that is not repeated but the problem is, I can't get a repeat value on the same row, or any other row or column in the program. In other words, each I integer should only display once. My objects were created via linked list and I will probably integrate the algorthim in there once I figure it out but for now, heres what I did.
int[] array = new int[50];
for(int i=1;i<=9;i++)
{
int[] grades = new int[5];
for(int j=0;j<=4;j++)
{
int unique = gen.nextInt(50)+1;
grades[j] = unique;
}
list.add(new Student(i, grades));
}
System.out.println(list);
My output:
Student1: 20 49 45 16 13
Student2: 28 10 11 30 6
Student3: 13 25 37 31 49
Student4: 8 23 8 12 32
Student5: 22 18 35 2 7
Student6: 35 8 16 23 36
Student7: 35 3 15 42 2
Student8: 43 12 44 2 35
Student9: 12 21 36 23 12
So my issue is this. How can I implement the random gen without repeating values. Normally I would try a collection list by now, but I'm trying to do this using java.util.Random Personally, I would do this a different way but I'm instructed. Thank you
Here's what I would do:
Take an ArrayList of numbers 1-50, then use Collections.shuffle on the list.
You could check if the number is unique before accepting it. For example you could try something like the following:
int count=0;
List<Integer> list=new ArrayList<Integer>();
while(count<50){
int num=random.nextInt(50);
if(!list.contains(num)){
list.add(num);
++count;
}
}

Categories