如何用两个整数数组做一个 "cross-over"
How to do a "cross-over" with two integer arrays
我正在尝试学习遗传算法,目前正在研究 "crossing over" 两个 "genes"。
基因是一个整数数组,由 1 和 0 组成。为了举例说明我的问题,假设我们有两个基因。
int[] geneA = {1,0,0,0,0};
int[] geneB = {0,1,1,1,0};
交叉的预期结果,例如位置 3 将是:
geneA = [1,0,0,1,0]
geneB = [0,1,1,0,0]
意味着索引为 3 或以上的每个元素都将与另一个基因的等效元素交换。为此,我编写了以下方法:
private void crossOver(int[] geneA, int[] geneB, int pos) {
int copyA[];
int copyB[];
copyA = geneA;
copyB = geneB;
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA);
System.out.println(Arrays.toString(geneB);
}
但是,似乎 geneB 的元素只是在索引为 3 或更高的位置复制到 geneA 中。
控制台输出如下:
[1, 0, 0, 1, 0]
[0, 1, 1, 1, 0]
非常感谢任何解释或帮助。提前致谢!
我认为你在创建数组副本时出错了......目前你没有制作副本,但 copyA 和 copyB 只是指向 geneA 和 geneB 的引用 resp
像这样使用Arrays.copy,
copyA = Arrays.copyOf(geneA, geneA.length);
copyB = Arrays.copyOf(geneB, geneB.length);
此代码有效:
void crossOver(int[] geneA, int[] geneB, int pos) {
int copyA[];
int copyB[];
copyA = Arrays.copyOf(geneA,geneA.length);
copyB = Arrays.copyOf(geneB,geneB.length);
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
您的代码存在问题,因为您正在通过以下方式复制数组:
copyA = geneA;
copyB = geneB;
它只是指向同一个引用。因此,在其余代码中,您处理的是同一个数组,而不是副本。
复制数组的正确方法是:
copyA = Arrays.copyOf(geneA,geneA.length);
copyB = Arrays.copyOf(geneB,geneB.length);
有问题。您可以很容易地将两个数组复制到 copyA
和 copyB
,这不会生成新副本。它只是复制数组的引用并且两个数组都引用相同的内存。所以其中一个的任何变化也会改变另一个。为此,您可以改用 Arrays.copyof()
。
我想这就是你想要的:
private void crossOver(int[] geneA, int[] geneB, int pos) {
int[] copyA = Arrays.copyOf(geneA, geneA.length);
int[] copyB = Arrays.copyOf(geneB, geneB.length);
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
而不是那样,正如我所见,您在进行复制和交换后更改 geneA
和 geneB
,所以我认为这段代码会用更少的代码做同样的事情,但我不知道是不是你想要的:
private void crossOver(int[] geneA, int[] geneB, int pos) {
for(int i = pos; i < geneA.length; i++) {
int temp = geneA[i];
geneA[i] = geneB[i];
geneB[i] = temp;
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
希望对你有所帮助。
copyA = geneA
不创建副本。两个变量现在都引用 same 数组。
没有必要浪费时间和space复制整个数组。
交换值时,只需将其中一个值存储在临时变量中即可。
private static void crossOver(int[] geneA, int[] geneB, int pos) {
for (int i = pos; i < geneA.length; i++) {
int temp = geneA[i];
geneA[i] = geneB[i];
geneB[i] = temp;
}
}
这将就地更新数组,因此调用者将看到更改。
int[] geneA = {1,0,0,0,0};
int[] geneB = {0,1,1,1,0};
crossOver(geneA, geneB, 3);
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
输出
[1, 0, 0, 1, 0]
[0, 1, 1, 0, 0]
我正在尝试学习遗传算法,目前正在研究 "crossing over" 两个 "genes"。 基因是一个整数数组,由 1 和 0 组成。为了举例说明我的问题,假设我们有两个基因。
int[] geneA = {1,0,0,0,0};
int[] geneB = {0,1,1,1,0};
交叉的预期结果,例如位置 3 将是:
geneA = [1,0,0,1,0]
geneB = [0,1,1,0,0]
意味着索引为 3 或以上的每个元素都将与另一个基因的等效元素交换。为此,我编写了以下方法:
private void crossOver(int[] geneA, int[] geneB, int pos) {
int copyA[];
int copyB[];
copyA = geneA;
copyB = geneB;
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA);
System.out.println(Arrays.toString(geneB);
}
但是,似乎 geneB 的元素只是在索引为 3 或更高的位置复制到 geneA 中。 控制台输出如下:
[1, 0, 0, 1, 0]
[0, 1, 1, 1, 0]
非常感谢任何解释或帮助。提前致谢!
我认为你在创建数组副本时出错了......目前你没有制作副本,但 copyA 和 copyB 只是指向 geneA 和 geneB 的引用 resp
像这样使用Arrays.copy,
copyA = Arrays.copyOf(geneA, geneA.length);
copyB = Arrays.copyOf(geneB, geneB.length);
此代码有效:
void crossOver(int[] geneA, int[] geneB, int pos) {
int copyA[];
int copyB[];
copyA = Arrays.copyOf(geneA,geneA.length);
copyB = Arrays.copyOf(geneB,geneB.length);
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
您的代码存在问题,因为您正在通过以下方式复制数组:
copyA = geneA;
copyB = geneB;
它只是指向同一个引用。因此,在其余代码中,您处理的是同一个数组,而不是副本。
复制数组的正确方法是:
copyA = Arrays.copyOf(geneA,geneA.length);
copyB = Arrays.copyOf(geneB,geneB.length);
有问题。您可以很容易地将两个数组复制到 copyA
和 copyB
,这不会生成新副本。它只是复制数组的引用并且两个数组都引用相同的内存。所以其中一个的任何变化也会改变另一个。为此,您可以改用 Arrays.copyof()
。
我想这就是你想要的:
private void crossOver(int[] geneA, int[] geneB, int pos) {
int[] copyA = Arrays.copyOf(geneA, geneA.length);
int[] copyB = Arrays.copyOf(geneB, geneB.length);
for(int i = pos; i < geneA.length; i++) {
geneA[i] = copyB[i];
geneB[i] = copyA[i];
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
而不是那样,正如我所见,您在进行复制和交换后更改 geneA
和 geneB
,所以我认为这段代码会用更少的代码做同样的事情,但我不知道是不是你想要的:
private void crossOver(int[] geneA, int[] geneB, int pos) {
for(int i = pos; i < geneA.length; i++) {
int temp = geneA[i];
geneA[i] = geneB[i];
geneB[i] = temp;
}
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
}
希望对你有所帮助。
copyA = geneA
不创建副本。两个变量现在都引用 same 数组。
没有必要浪费时间和space复制整个数组。
交换值时,只需将其中一个值存储在临时变量中即可。
private static void crossOver(int[] geneA, int[] geneB, int pos) {
for (int i = pos; i < geneA.length; i++) {
int temp = geneA[i];
geneA[i] = geneB[i];
geneB[i] = temp;
}
}
这将就地更新数组,因此调用者将看到更改。
int[] geneA = {1,0,0,0,0};
int[] geneB = {0,1,1,1,0};
crossOver(geneA, geneB, 3);
System.out.println(Arrays.toString(geneA));
System.out.println(Arrays.toString(geneB));
输出
[1, 0, 0, 1, 0]
[0, 1, 1, 0, 0]