eaopt icon indicating copy to clipboard operation
eaopt copied to clipboard

CrossCX and CrossERX relies on hashable types

Open JensRantil opened this issue 5 years ago • 1 comments

I have a genome which isn't hashable. When I run my application, it panics:

panic: runtime error: hash of unhashable type scheduler.ScheduleRequest

goroutine 20 [running]:
github.com/JensRantil/eaopt.getNeighbours(0x118e300, 0xc0000990a0, 0xc000099140)
	/Users/jrantil/go/pkg/mod/github.com/!jens!rantil/[email protected]/slice.go:70 +0xfd
github.com/JensRantil/eaopt.CrossERX(0x118e300, 0xc0000990a0, 0x118e300, 0xc0000990c0)
	/Users/jrantil/go/pkg/mod/github.com/!jens!rantil/[email protected]/crossover.go:262 +0x156
github.com/JensRantil/meeting-scheduler.(*solution).Crossover(0xc000099040, 0x118d280, 0xc000099080, 0xc000076360)
	/Users/jrantil/src/meeting-scheduler/lib.go:163 +0xa3
github.com/JensRantil/eaopt.(*Individual).Crossover(...)
	/Users/jrantil/go/pkg/mod/github.com/!jens!rantil/[email protected]/individual.go:82
github.com/JensRantil/eaopt.generateOffsprings(0x1e, 0xc0000bc000, 0x1e, 0x1e, 0x118c400, 0xc00008a070, 0x3fe6666666666666, 0xc000076360, 0x110b8b9, 0x116362b, ...)
	/Users/jrantil/go/pkg/mod/github.com/!jens!rantil/[email protected]/models.go:32 +0x362
github.com/JensRantil/eaopt.ModGenerational.Apply(0x118c400, 0xc00008a070, 0x3fe0000000000000, 0x3fe6666666666666, 0xc000088640, 0xf, 0x0)
	/Users/jrantil/go/pkg/mod/github.com/!jens!rantil/[email protected]/models.go:64 +0x8c
github.com/JensRantil/eaopt.(*GA).evolve.func1(0xc000088640, 0xc00003ef60, 0x10759e6)
	/Users/jrantil/go/pkg/mod/github.com/!jens!rantil/[email protected]/ga.go:102 +0x240
github.com/JensRantil/eaopt.Populations.Apply.func1(0xc00003ef68, 0xc00003efc0)
	/Users/jrantil/go/pkg/mod/github.com/!jens!rantil/[email protected]/population.go:56 +0x45
golang.org/x/sync/errgroup.(*Group).Go.func1(0xc000076f90, 0xc000076fc0)
	/Users/jrantil/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:57 +0x64
created by golang.org/x/sync/errgroup.(*Group).Go
	/Users/jrantil/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:54 +0x66
FAIL	github.com/JensRantil/meeting-scheduler	0.227s

and

panic: runtime error: hash of unhashable type scheduler.ScheduleRequest

goroutine 20 [running]:
github.com/MaxHalford/eaopt.newIndexLookup(0x118c560, 0xc00009b120, 0x20)
	/Users/jrantil/go/pkg/mod/github.com/!max!halford/eaopt@v0.0.0-20191122194827-37dd3a71cb482d1990b40d439adbd976f27fc095/slice.go:33 +0x84
github.com/MaxHalford/eaopt.getCycles(0x118c560, 0xc00009b120, 0x118c560, 0xc00009b140, 0x5a0, 0x114c940, 0x1267960)
	/Users/jrantil/go/pkg/mod/github.com/!max!halford/eaopt@v0.0.0-20191122194827-37dd3a71cb482d1990b40d439adbd976f27fc095/slice.go:42 +0x50
github.com/MaxHalford/eaopt.CrossCX(0x118c560, 0xc00009b120, 0x118c560, 0xc00009b140)
	/Users/jrantil/go/pkg/mod/github.com/!max!halford/eaopt@v0.0.0-20191122194827-37dd3a71cb482d1990b40d439adbd976f27fc095/crossover.go:220 +0xc6
github.com/JensRantil/meeting-scheduler.(*solution).Crossover(0xc00009b0c0, 0x118b540, 0xc00009b100, 0xc000078360)
	/Users/jrantil/src/meeting-scheduler/lib.go:163 +0xa3
github.com/MaxHalford/eaopt.(*Individual).Crossover(...)
	/Users/jrantil/go/pkg/mod/github.com/!max!halford/eaopt@v0.0.0-20191122194827-37dd3a71cb482d1990b40d439adbd976f27fc095/individual.go:82
github.com/MaxHalford/eaopt.generateOffsprings(0x1e, 0xc0000be000, 0x1e, 0x1e, 0x118a6c0, 0xc00008c070, 0x3fe6666666666666, 0xc000078360, 0x110a809, 0x1161cab, ...)
	/Users/jrantil/go/pkg/mod/github.com/!max!halford/eaopt@v0.0.0-20191122194827-37dd3a71cb482d1990b40d439adbd976f27fc095/models.go:32 +0x362
github.com/MaxHalford/eaopt.ModGenerational.Apply(0x118a6c0, 0xc00008c070, 0x3fe0000000000000, 0x3fe6666666666666, 0xc00008a640, 0xf, 0x0)
	/Users/jrantil/go/pkg/mod/github.com/!max!halford/eaopt@v0.0.0-20191122194827-37dd3a71cb482d1990b40d439adbd976f27fc095/models.go:64 +0x8c
github.com/MaxHalford/eaopt.(*GA).evolve.func1(0xc00008a640, 0xc00003ef60, 0x10755b6)
	/Users/jrantil/go/pkg/mod/github.com/!max!halford/eaopt@v0.0.0-20191122194827-37dd3a71cb482d1990b40d439adbd976f27fc095/ga.go:102 +0x240
github.com/MaxHalford/eaopt.Populations.Apply.func1(0xc00003ef68, 0xc00003efc0)
	/Users/jrantil/go/pkg/mod/github.com/!max!halford/eaopt@v0.0.0-20191122194827-37dd3a71cb482d1990b40d439adbd976f27fc095/population.go:56 +0x45
golang.org/x/sync/errgroup.(*Group).Go.func1(0xc000078f90, 0xc000078fc0)
	/Users/jrantil/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:57 +0x64
created by golang.org/x/sync/errgroup.(*Group).Go
	/Users/jrantil/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:54 +0x66
FAIL	github.com/JensRantil/meeting-scheduler	0.229s

Assuming that interface{} is hashable is probably a bad idea.

JensRantil avatar Dec 06 '19 13:12 JensRantil

Workaround: This is what my genome looked like:

type ScheduleRequestSlice []ScheduleRequest

...

type solution struct {
       scheduler *Scheduler
       order      ScheduleRequestSlice
}

func (s *solution) Crossover(genome eaopt.Genome, rng *rand.Rand) {
    // https://www.hindawi.com/journals/cin/2017/7430125/
    eaopt.CrossCX(s.order, genome.(*solution).order)
}

Instead, what I did, was to introduce a list of ints, [0, 1, 2, 3, 4...] which maps to the items in solution.reqs:

type solution struct {
       scheduler *Scheduler
       reqs      []ScheduleRequest

       // This is the order we are optimizing for. We could in theory really
       // reorder reqs, but since eaopt requires that slices's interface{} content
       // is hashable we reorder ints which really are the indexes of reqs.
       order []int
}

func (s *solution) Crossover(genome eaopt.Genome, rng *rand.Rand) {
    // https://www.hindawi.com/journals/cin/2017/7430125/
    eaopt.CrossCXInt(s.order, genome.(*solution).order)
}

JensRantil avatar Dec 06 '19 14:12 JensRantil