[已解决]Golang中切片赋值问题如何解决

[已解决]Golang中切片赋值问题如何解决 请查看 https://play.golang.org/p/ViIwhNoGuSW

如果运行该脚本,您可以看到,例如在结果的最后一行: crosspoint: 3 par1: 4 [0 0 1 1 1 1 0 1 0 0] ... 这是不正确的。

之前,

parent1 := make([]int, 0)
parent2 := make([]int, 0)

是在 for 循环之外的。将它们放在循环内部是为了避免切片问题,但仍然无法正确运行。

我遗漏了什么?


更多关于[已解决]Golang中切片赋值问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

lib:

不正确。

怎样才是正确的?这个程序应该做什么?

更多关于[已解决]Golang中切片赋值问题如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我已经理解了这一点。 child 正在某处重写 pop

如果你遇到了Go语言的问题,请具体说明这个问题。但如果是遗传算法的错误,我怀疑我们可能无法提供帮助。

crossover 函数应该为每对 parents 生成一个 childpopulation 包含当前世代的所有 individualspool 包含将用于生成 children 的每个父代的索引。 因此,pool 的前两个值 [4, 4] 将在 crosspoint = 3 处进行交叉。将使用左侧 4 的索引 [0,3] 和右侧 4 的索引 [3, 10]。在这种情况下,由于左右父代相同,结果将是一个相似的 individual

正如你在结果的第一行(以 crosspoint: 开头)中看到的,par1 是 4,它确实对应于 pop(或 population)的索引 4。 同样在第一行中,同样引用索引 4 的 par2 也是正确的。 在第五行中,par2 (4) 也是正确的。

但在最后一行中,par1 (4) [0 0 1 1 1 1 0 1 0 0] 与它应该是的 [0 0 1 1 0 1 1 1 1 1] 不同。

为什么会这样?

问题在于切片在Go中是引用类型,当您将切片赋值给另一个变量时,它们实际上共享相同的底层数组。在您的代码中,当您执行类似 parent1 = individual1.Genome 这样的赋值时,parent1individual1.Genome 指向同一个底层数组,后续对 parent1 的修改会影响 individual1.Genome

解决方案是使用 copy 函数或通过切片表达式创建新切片来复制数据,而不是直接赋值。以下是修复后的代码示例:

package main

import "fmt"

func main() {
    // 模拟原始数据
    individual1 := struct {
        Genome []int
    }{
        Genome: []int{0, 1, 0, 1, 1, 0, 0, 1, 0, 1},
    }
    
    individual2 := struct {
        Genome []int
    }{
        Genome: []int{1, 0, 1, 0, 0, 1, 1, 0, 1, 0},
    }

    crosspoint := 3
    
    // 创建新切片并复制数据
    parent1 := make([]int, len(individual1.Genome))
    copy(parent1, individual1.Genome)
    
    parent2 := make([]int, len(individual2.Genome))
    copy(parent2, individual2.Genome)
    
    // 执行交叉操作
    for i := crosspoint; i < len(parent1); i++ {
        parent1[i], parent2[i] = parent2[i], parent1[i]
    }
    
    fmt.Printf("crosspoint: %d parent1: %v parent2: %v\n", 
        crosspoint, parent1, parent2)
    // 输出: crosspoint: 3 parent1: [0 1 0 0 0 1 1 0 1 0] parent2: [1 0 1 1 1 0 0 1 0 1]
}

或者使用切片表达式创建新切片:

// 方法2:使用切片表达式
parent1 := append([]int{}, individual1.Genome...)
parent2 := append([]int{}, individual2.Genome...)

关键点是避免直接赋值切片,而是创建新的切片并复制原始数据。这样对 parent1parent2 的修改就不会影响原始的 individual1.Genomeindividual2.Genome

回到顶部