Skip to content

CrossCX and CrossERX relies on hashable types #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
JensRantil opened this issue Dec 6, 2019 · 1 comment
Open

CrossCX and CrossERX relies on hashable types #44

JensRantil opened this issue Dec 6, 2019 · 1 comment

Comments

@JensRantil
Copy link
Collaborator

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
Copy link
Collaborator Author

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)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant