I have two individuals I need to perform crossover on that are of different lengths.
The individuals may be like this, but could be much longer:
0 1 2 2 1 2 0 [0] 1 2 1 2 0 1 2 [0] 1 2 1 2 0 2 1 [1]
1 2 1 1 0 2 0 [0] 1 2 1 2 0 0 1 [1]
However, I need to keep their original length after crossover. I also need to ensure that every 8th bit (in square brackets) cannot be a 2. The length of each individual will always be multiples of 8.
How can I perform crossover on these individuals without changing the length and structure of either individual?
I haven't been able to find a solution to this so any help would be greatly appreciated.
I assume you're talking about a single-point crossover. You could do something like this:
Select a random number between 1 and the length of the shorter individual. This will be your crossover point.
Cut both individuals at this point.
Swap them, as per regular crossover.
Example:
0 1 2 2 1 2 0 [0] 1 2 1 2 0 1 2 [0] 1 2 1 2 0 2 1 [1]
1 2 1 1 0 2 0 [0] 1 2 1 2 0 0 1 [1]
The shorter individual has length 16, so we generate a random number between 1 and 16 --> e.g., 9
Crossover point:
|
0 1 2 2 1 2 0 [0] 1|2 1 2 0 1 2 [0] 1 2 1 2 0 2 1 [1]
1 2 1 1 0 2 0 [0] 1|2 1 2 0 0 1 [1]
|
Swap sub-sections after the point:
|
0 1 2 2 1 2 0 [0] 1|2 1 2 0 0 1 [1]
1 2 1 1 0 2 0 [0] 1|2 1 2 0 1 2 [0] 1 2 1 2 0 2 1 [1]
|
This preserves the length of both individuals, and preserves the no-2s-in-brackets rule.
I've tried this type of solution:
it works (but different cross-over location:
the code is in python
from random import choices, randint, randrange, random
a = [1,2,4,5,8,11,3,4,7,2,4,6]
b = [3,4,5,6,9,1,3,6,7]
length_a =len(a)
length_b = len(b)
crossover_prob = 0.8
p = randint(1, length_a - 1)
q = randint(1, length_b -1)
while p < crossover_prob:
c = a[0:p] + b[q:]
while q < crossover_prob:
d = b[0:q] + a[p:]
print (c)
print (d)
result:
[1, 3, 4, 5, 6, 9, 1, 3, 6, 7]
[2, 4, 5, 8, 11, 3, 4, 7, 2, 4, 6]
Related
How to list combinations in java with methods that stack upon each other.
To print the combinations, you need to print when amount == 0.
To do that, you need to accumulate what has been done to get to that value, i.e. which coins has been applied to the amount value.
One way would be to build a string, appending a space and the coin value as part of the recursive call. The resultant string will start with a space, so it has to be skipped when printing.
public static int combo(int amount, int currentCoin, String combo) {
// Added: ^^^^^^^^^^^^^^
if (amount == 0) {
System.out.println(combo.substring(1)); // <<<<< Added
return 1;
}
if (amount < 0) {
return 0;
}
int nCombos = 0;
for (int coin = currentCoin; coin < coins.length; coin++) {
nCombos += combo(amount - coins[coin], coin, combo + " " + coins[coin]);
// Added: ^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
return nCombos;
}
Test
System.out.println("combo = " + combo(20, 0, ""));
// Added: ^^^^
Output
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 2 5
1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1 2 2 5
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1 5 5
1 1 1 1 1 1 1 1 1 2 2 2 5
1 1 1 1 1 1 1 1 2 2 2 2 2 2
1 1 1 1 1 1 1 1 2 5 5
1 1 1 1 1 1 1 2 2 2 2 5
1 1 1 1 1 1 2 2 2 2 2 2 2
1 1 1 1 1 1 2 2 5 5
1 1 1 1 1 2 2 2 2 2 5
1 1 1 1 1 5 5 5
1 1 1 1 2 2 2 2 2 2 2 2
1 1 1 1 2 2 2 5 5
1 1 1 2 2 2 2 2 2 5
1 1 1 2 5 5 5
1 1 2 2 2 2 2 2 2 2 2
1 1 2 2 2 2 5 5
1 2 2 2 2 2 2 2 5
1 2 2 5 5 5
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 5 5
5 5 5 5
combo = 29
I need help with my code which that my input ratings isĀ
-1 2 3 5 -1 5 3 3 1 4 2 2 5 -1 1 3 3 5 4 3
-1 1 1 4 1 3 3 1 2 3 4 -1 4 1 2 4 5 4 2 3
3 -1 2 3 -1 2 5 -1 3 3 5 2 2 1 2 3 5 3 4 2
-1 1 -1 4 1 3 5 2 1 5 3 -1 5 2 1 3 4 5 3 2
-1 -1 3 2 -1 5 5 2 2 4 4 2 3 2 -1 3 4 4 3 1
2 1 1 5 2 2 4 2 3 4 3 -1 5 2 2 5 3 5 2 1
3 -1 3 4 -1 2 5 -1 -1 4 3 -1 3 -1 2 5 5 5 4 2
4 -1 4 2 3 -1 1 3 4 -1 1 4 4 4 -1 2 -1 1 4 4
4 3 3 3 -1 2 2 4 3 -1 2 4 3 4 2 -1 -1 2 2 3
3 -1 3 -1 3 4 -1 5 5 -1 -1 -1 1 -1 -1 1 1 2 -1 5
3 -1 3 4 3 4 -1 5 5 2 3 3 4 1 1 -1 -1 -1 -1 4
4 -1 4 4 1 3 -1 5 4 -1 1 3 4 1 -1 1 -1 1 -1 5
5 -1 3 1 4 3 -1 5 4 1 3 2 1 -1 4 2 1 -1 2 4
3 -1 5 1 4 4 2 5 5 1 2 3 1 1 -1 1 -1 1 -1 5
4 1 5 4 3 -1 1 3 4 -1 -1 3 3 -1 1 1 2 -1 3 5
-1 1 1 3 -1 3 1 3 -1 -1 3 -1 5 2 2 1 4 -1 5 -1
3 -1 2 3 1 5 4 3 3 -1 5 -1 5 2 -1 4 4 3 3 3
1 1 1 3 2 4 1 -1 -1 -1 5 -1 3 -1 -1 1 -1 2 5 2
-1 2 3 5 -1 4 3 1 1 3 3 -1 4 -1 -1 4 3 2 5 1
-1 1 3 3 -1 3 3 1 -1 -1 3 -1 5 -1 -1 3 1 2 4 -1
3 -1 2 4 1 4 3 -1 2 3 4 1 3 -1 2 -1 4 3 5 -1
-1 1 3 5 -1 4 2 1 -1 3 3 2 3 2 -1 3 1 -1 3 -1
3 2 2 3 -1 5 -1 -1 2 3 4 -1 4 1 -1 -1 -1 -1 4 2
-1 3 -1 -1 4 -1 2 -1 2 2 2 5 -1 3 4 -1 -1 2 -1 2
1 4 3 -1 3 2 1 -1 -1 -1 1 3 1 3 3 1 -1 -1 -1 3
4 3 3 -1 4 2 -1 4 -1 -1 2 4 -1 3 4 2 -1 -1 -1 4
-1 5 1 -1 4 1 -1 3 2 2 -1 4 1 3 3 1 -1 -1 -1 3
-1 4 2 1 5 -1 -1 2 1 1 -1 5 -1 5 4 1 2 2 -1 1
2 5 2 -1 3 -1 -1 1 -1 2 -1 4 2 4 3 -1 2 1 -1 -1
2 5 1 1 4 -1 2 1 -1 -1 2 4 -1 3 4 2 -1 -1 -1 4
which I am taking the first role of the rate by vertically which my average[] has 20 values.
I am confused about where is wrong with my code such that if number = -1, then it set to 0 and then doesn't count.
This is a code to count the average rating of a book, my average[] value comes out different then my calculation on a calculator.
public static double [] recommandratings(double[][]ratings) {
double [] average = new double[20];
int [] count = new int[20];
double[] sum = new double[30];
Arrays.fill(count,0);
Arrays.fill(sum, 0);
for(int i= 0;i<20;i++) {
for(int j=0; j<30; j++) {
if(ratings[j][i] == -1) {
ratings[j][i] = 0;
sum[i] += ratings[j][i];
count[i]--;
} else {
sum[i] += ratings[j][i];
count[i]++;
}
}
}
for(int a =0; a<20;a++) {
average[a] = sum[a]/count[a];
}
return average;
}
I think the way of iteration of the 2D array is wrong in your case. I made the following changes to make it simple and dynamic. I hope the following code will give you desired result.
public static double [] recommandratings (double[][]ratings) {
int rowSize = ratings.length;
int colSize = ratings[0].length;
double [] average = new double[colSize];
int[] count = new int[colSize];
for (int row= 0;row < rowSize;row++) {
for (int col=0; col < colSize; col++) {
if (ratings[row][col] != -1) {
average[col] += ratings[row][col];
count[col]++;
}
}
}
for (int a =0; a < colSize;a++) {
int sum = (int) average[a];
average[a] = average[a] / count[a];
System.out.println("count[" + a + "]=" + count[a] + "; sum[" + a + "]=" + sum + "; average[" + a + "]=" + average[a]);
}
return average;
}
P.S. I removed the sum[] and reused the average[] to optimize memory.
Update
This update is based on the comments where you state that the count[a] is always returning 30, where it should be less than 30. I performed a test with both your exact dataset and a smaller dataset. I found my solution is returning less than 30 which is expected. Therefore, I think you made some mistake in integrating my solution. So, I have made a gist with complete source code and input/output as well which will help you integrate it correctly.
Since you don't want to count number with value -1, there is no use of count[i]-- because you are increasing count only when there is a number not equal to -1.
public class UnaryOperator {
public static void main(String[] args) {
byte a= -5;
System.out.println(~a); // prints 4
}
}
When I do it manually, I get the answer as 6.
Here is how I did it:
128 64 32 16 8 4 2 1
0 0 0 0 0 1 0 1
As it is a negation I inverted it to the following:
128 64 32 16 8 4 2 1
0 0 0 0 0 1 0 1
sign -1 1 1 1 1 0 1 0
-----------------------------
0 0 0 0 1 0 1
add one--> 0 0 0 0 0 1 1
------------------------------
0 0 0 0 1 1 0 = 6
------------------------------
I know there's something wrong with what I am doing but I am not able to figure it out.
5 is 00000101
-5 is 11111010+00000001 = 11111011
~(-5) is 00000100
so you get 4.
You're starting out with -5, which is in two's complement. Thus:
-128 64 32 16 8 4 2 1
1 1 1 1 1 0 1 1 (= -5)
flip: 0 0 0 0 0 1 0 0 (= +4)
I haven't done much bitwise stuff, but after reading wikipedia for a few seconds it seems like NOT -5 = 4, on wikipedia they used NOT x = -x - 1. So the program is correct.
Edit: For unsigned integers, you use NOT x = y - x were y is the maximum number that integer can hold.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I would like to built a combination table for example 4 number of 5 samples(0 -4), but not in the right order. The table should start with the combinations of 0 and 1; than 0,1 2; than 0,1,2,3; than 0,1,2,3,4. Of course the table should not have repetition. I need an algorithm to do it but I can not find any until now. After that I have to write a java code. At the end the table should look like this:
0 0 0 1
0 0 1 0
0 1 0 0
1 0 0 0
0 0 1 1
0 1 0 1
0 1 1 0
1 0 1 0
1 1 0 0
0 1 1 1
.... ... ... ...
1 1 1 1
0 0 0 2
.... ... ... ...
2 0 0 0
... ... ... ...
0 0 1 2
.... ... ... ...
2 2 2 2
0 0 0 3
.... ... ... ...
3 0 0 0
0 0 1 3
.... ... ... ...
3 2 2 2
... ... ... ...
3 3 3 3
.... .... ...... ...
4 4 4 4
You could start with 0000 and increment by 1 (in base 2,3,4,5) until you overflow. E.g.
Base 2:
0000 + 1 => 0001
0001 + 1 => 0010
0010 + 1 => 0011
...
1110 + 1 => 1111
Base 3:
0000 + 1 => 0001
0001 + 1 => 0002
0002 + 1 => 0010
...
2221 + 1 => 2222
And similar for bases 4 and 5.
If you care about repeats (e.g. 0001 is repeated in base 2 and 3) then you can just increment until: for base 2 you have at least a single 1, for base 3 you have at least a single 2, etc...
Java Example:
public static void main(String... args){
int n = 4;
// for base 1, 2, 3, 4, 5 (base 1 gives 0000)
for(int base = 1; base < n + 2; base++)
// for every combination: base^n
for(int j = 0; j < Math.pow(base, n); j++)
// if num contains a (base-1) digit, it's not a dup
if(Integer.toString(j, base).contains(Integer.toString(base-1)))
System.out.println(String.format("%04d",
Integer.parseInt(Integer.toString(j, base))));
}
I have a small program to do in Java. I have a 2D array filled with 0 and 1, and I must find the largest rhombus (as in square rotated by 45 degrees) and their numbers.
Example:
0 1 0 0 0 1
1 0 1 1 1 0
1 0 1 1 1 1
0 1 1 1 1 1
0 0 1 1 1 1
1 1 1 1 1 1
Result:
1
1 1 1
1 1 1 1 1
1 1 1
1
The problem is similar to this SO question.
If you have any idea, post it here.
This too long for a comment. I'll post my solution later on if you can't solve it but here's how I've done it (in less than 15 lines of code): I first created a second array (a little big bigger [n+2][n+2]) and did n/2 pass:
0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0
0 1 0 1 1 1 0 0
0 1 0 1 2 2 1 0
0 0 1 2 2 2 1 0
0 0 0 1 2 2 1 0
0 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0
0 1 0 1 1 1 0 0
0 1 0 1 2 2 1 0
0 0 1 2 3 2 1 0
0 0 0 1 2 2 1 0
0 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0
Where a non-zero number x means "I'm the center of a rhombus of size x" (I'm expressing the size in relation with the length of the diagonals [which are both equal in your case] of the rhombus). You can find if you have the center of a rhombus of size (k+1) by checking if {top,right,down,left} are all the centers of rhombus of size k.
The advantage of first creating a bigger array is that it really simplifies your logic but I could do it in place, with a more convoluted logic, by modifying the original array or by using a second array of the same size as the input (once again, it's way easier to simply put a safe "fence" of all-zeroes around your input).
If you don't "surround" your array with a fence, you have a lot of additional if/else checks: this would be prone to errors, lead to bigger code and lead to uglier code.
Short tutorial:
How would you solve the problem if it was a 1x1-field?
How could you formulate the problem recursively?
How could you remember intermediate results and use them?
Do it.
void rhombus()
{
maxr=0;
for (int i=n-1;i>=0;i--)
{
for (int j=n-1;j>=0;j--)
{
if (b[i][j]>0)
{
if ((i==n-1) || (j==n-1) || (i==0) || (j==0)) b[i][j]=1;
else {
b[i][j]=min4(b[i][j+1],b[i][j-1],b[i+1][j],b[i-1][j])+1;
if (b[i][j]==maxr) nrr++;
else if (b[i][j]>maxr) {
nrr=1;
maxr=b[i][j];
}
}
}
}
}
}
Did it,it works,this is my function,where maxr is the max size of the rhombus,and nrr is the number of max sized rhombus.Not sure how it works on huge arrays.(i loop this function n/2 times)