patterngoMinor
Solving the travelling salesman problem using a genetic algorithm
Viewed 0 times
problemsolvingthesalesmantravellinggeneticalgorithmusing
Problem
I've got a simple program written in Golang that takes a map as input and tries to solve the travelling salesman problem by using a genetic algorithm. My Crossover method is a real performance killer due to intense use of
What I'd like to do - and yet failed to do is outsource the creation of
I am also interested in any suggestions for improvements of my coding style in Golang and other performance improvements I can take a look at.
My source is at Github.
Here is an excerpt of the function I am trying to improve:
```
func (ts *TravellingSalesman) Crossover() {
// Crossover
var nCrossover = int(ts.pCrossover * float64(ts.nGenes))
var newGenes = make([]ga.Gene, nCrossover)
for i:=0; i take m
if existN && !existM {
newGenes[i].Data[k] = nextM
currentCity = nextM
} else if !existN && existM {
newGenes[i].Data[k] = nextN
currentCity = nextN
} else if existN && existM {
nextRandom := findNextRandomCity(newGenes[i].Data[0:k], &(ts.genes[n].Data))
newGenes[i].Data[k] = nextRandom
currentCity = nextRandom
} else {
// If both didn't exist, take the shorter one
distN := ts.distMatrix.GetDistance(currentCity-1, nextN-1)
distM := ts.distMatrix.GetDistance(currentCity-1, nextM-1)
// Take the shorter route
if distN < distM {
newGenes[i].Data[k] = nextN
currentCity = nextN
} else {
newGenes[i].Data[k] = nextM
currentCity = nextM
}
}
}
}
copy(ts.ge
make() (allocate memory / will provoke the GC).What I'd like to do - and yet failed to do is outsource the creation of
newGenes. pCrossover and therefore the size of newGenes will be the same over all calls of the function, so I'd like to avoid creating that slice again and again.I am also interested in any suggestions for improvements of my coding style in Golang and other performance improvements I can take a look at.
My source is at Github.
Here is an excerpt of the function I am trying to improve:
```
func (ts *TravellingSalesman) Crossover() {
// Crossover
var nCrossover = int(ts.pCrossover * float64(ts.nGenes))
var newGenes = make([]ga.Gene, nCrossover)
for i:=0; i take m
if existN && !existM {
newGenes[i].Data[k] = nextM
currentCity = nextM
} else if !existN && existM {
newGenes[i].Data[k] = nextN
currentCity = nextN
} else if existN && existM {
nextRandom := findNextRandomCity(newGenes[i].Data[0:k], &(ts.genes[n].Data))
newGenes[i].Data[k] = nextRandom
currentCity = nextRandom
} else {
// If both didn't exist, take the shorter one
distN := ts.distMatrix.GetDistance(currentCity-1, nextN-1)
distM := ts.distMatrix.GetDistance(currentCity-1, nextM-1)
// Take the shorter route
if distN < distM {
newGenes[i].Data[k] = nextN
currentCity = nextN
} else {
newGenes[i].Data[k] = nextM
currentCity = nextM
}
}
}
}
copy(ts.ge
Solution
How about using a slice for
You just allocate
before entering the for loop and assign
You'd cut down on the amount of allocations (and system calls) without changing much else (except
And you'd follow the advice given by the languages creators in Effective Go.
Gene.Data?You just allocate
var allData := make([]int, nCrossover * ts.geneLength)before entering the for loop and assign
newGenes[i].Data = allData[i * ts.geneLength: (i + 1) * ts.geneLength]You'd cut down on the amount of allocations (and system calls) without changing much else (except
findNextCity and isInArray - but they should be written to accept slices instead of array pointers anyway).And you'd follow the advice given by the languages creators in Effective Go.
Code Snippets
var allData := make([]int, nCrossover * ts.geneLength)newGenes[i].Data = allData[i * ts.geneLength: (i + 1) * ts.geneLength]Context
StackExchange Code Review Q#6464, answer score: 2
Revisions (0)
No revisions yet.