Skip to content

Commit

Permalink
Rules - Associate Functions with GA class, and create Setter function…
Browse files Browse the repository at this point in the history
…s and Test
  • Loading branch information
Dylan Clarke authored and Dylan Clarke committed Oct 30, 2017
1 parent 4089ee7 commit 1c20e7f
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 39 deletions.
17 changes: 17 additions & 0 deletions GeneticAlgorithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ type GeneticAlgorithm struct {
Selection SelectFunction
Output func(a ...interface{})

RulesMatch RulesMatchFunc
EncodeRules EncodeRulesFunc
DecodeRules DecodeRulesFunc

RandomEngine *rand.Rand
}

Expand All @@ -40,6 +44,10 @@ func NewGeneticAlgorithm() GeneticAlgorithm {
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(time.Now().Unix())

geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
return geneticAlgorithm
}

Expand Down Expand Up @@ -107,6 +115,15 @@ func (genA *GeneticAlgorithm) Run(populationSize, bitstringLength, generations i
if genA.RandomEngine == nil {
return errors.New("random generator is not initialised")
}
if genA.RulesMatch == nil {
return errors.New("rulesMatch func is nil")
}
if genA.EncodeRules == nil {
return errors.New("encodeRules func is nil")
}
if genA.DecodeRules == nil {
return errors.New("decodeRules func is nil")
}

// Init
genA.Candidates = make(Population, 0)
Expand Down
88 changes: 74 additions & 14 deletions GeneticAlgorithm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ func testCustomFunctions(geneticAlgorithm *GeneticAlgorithm, t *testing.T) {

func TestGACustomFunctions(t *testing.T) {
t.Parallel()
success := true
success = success && t.Run("NilGenerateCandidate", func(t *testing.T) {
t.Run("NilGenerateCandidate", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetCrossoverFunc(DefaultCrossoverFunc)
Expand All @@ -90,9 +89,12 @@ func TestGACustomFunctions(t *testing.T) {
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(time.Now().Unix())
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})
success = success && t.Run("NilCrossover", func(t *testing.T) {
t.Run("NilCrossover", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
Expand All @@ -101,9 +103,12 @@ func TestGACustomFunctions(t *testing.T) {
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(time.Now().Unix())
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})
success = success && t.Run("NilMutate", func(t *testing.T) {
t.Run("NilMutate", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
Expand All @@ -112,9 +117,12 @@ func TestGACustomFunctions(t *testing.T) {
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(time.Now().Unix())
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})
success = success && t.Run("NilFitness", func(t *testing.T) {
t.Run("NilFitness", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
Expand All @@ -123,9 +131,12 @@ func TestGACustomFunctions(t *testing.T) {
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(time.Now().Unix())
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})
success = success && t.Run("NilSelection", func(t *testing.T) {
t.Run("NilSelection", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
Expand All @@ -134,9 +145,12 @@ func TestGACustomFunctions(t *testing.T) {
geneticAlgorithm.SetFitnessFunc(DefaultFitnessFunc)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(time.Now().Unix())
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})
success = success && t.Run("NilOutput", func(t *testing.T) {
t.Run("NilOutput", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
Expand All @@ -145,9 +159,12 @@ func TestGACustomFunctions(t *testing.T) {
geneticAlgorithm.SetFitnessFunc(DefaultFitnessFunc)
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetSeed(time.Now().Unix())
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})
success = success && t.Run("NilRandom", func(t *testing.T) {
t.Run("NilRandom", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
Expand All @@ -156,9 +173,57 @@ func TestGACustomFunctions(t *testing.T) {
geneticAlgorithm.SetFitnessFunc(DefaultFitnessFunc)
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})
success = success && t.Run("AllFuncs", func(t *testing.T) {

t.Run("NilRulesMatch", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
geneticAlgorithm.SetCrossoverFunc(DefaultCrossoverFunc)
geneticAlgorithm.SetMutateFunc(DefaultMutateFunc)
geneticAlgorithm.SetFitnessFunc(DefaultFitnessFunc)
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(3)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})

t.Run("NilEncodeRules", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
geneticAlgorithm.SetCrossoverFunc(DefaultCrossoverFunc)
geneticAlgorithm.SetMutateFunc(DefaultMutateFunc)
geneticAlgorithm.SetFitnessFunc(DefaultFitnessFunc)
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(3)
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetDecodeRulesFunc(DefaultDecodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})

t.Run("NilDecodeRules", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm GeneticAlgorithm
geneticAlgorithm.SetGenerateCandidate(DefaultGenerateCandidate)
geneticAlgorithm.SetCrossoverFunc(DefaultCrossoverFunc)
geneticAlgorithm.SetMutateFunc(DefaultMutateFunc)
geneticAlgorithm.SetFitnessFunc(DefaultFitnessFunc)
geneticAlgorithm.SetSelectionFunc(TournamentSelection)
geneticAlgorithm.SetOutputFunc(PrintToConsole)
geneticAlgorithm.SetSeed(3)
geneticAlgorithm.SetRulesMatchFunc(DefaultRulesMatchFunc)
geneticAlgorithm.SetEncodeRulesFunc(DefaultEncodeRulesFunc)
testCustomFunctions(&geneticAlgorithm, t)
})
t.Run("AllFuncs", func(t *testing.T) {
t.Parallel()
var geneticAlgorithm = NewGeneticAlgorithm()
geneticAlgorithm.SetOutputFunc(func(a ...interface{}) { t.Log(a) })
Expand All @@ -169,11 +234,6 @@ func TestGACustomFunctions(t *testing.T) {
t.Log("GA returned nil error as expected. Got:", err)
}
})
if success {
t.Log("Test GA Custom Functions Succeeded")
} else {
t.Error("Test GA Custom Functions Failed")
}
}

func testGA(length, generations, expectedFitness, selectionMethod int, terminateEarly bool, t *testing.T) {
Expand Down
34 changes: 22 additions & 12 deletions rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ type Rule struct {

type RuleBase []Rule
type RulesMatchFunc func(Rule, Rule) (bool, error)
type EncodeRulesFunc func(RuleBase) (Bitstring, error)
type DecodeRulesFunc func(Bitstring, int, int) (RuleBase, error)

func (r Rule) String() string {
return fmt.Sprintf("%v %v", r.Condition, r.Output)
}

// SetMutateFunc changes the mutate function to the function specified
func (genA *GeneticAlgorithm) SetRulesMatchFunc(f RulesMatchFunc) {
genA.RulesMatch = f
}

var DefaultRulesMatchFunc RulesMatchFunc = func(rule1, rule2 Rule) (bool, error) {
if len(rule1.Condition) != len(rule2.Condition) {
Expand All @@ -30,29 +41,28 @@ var DefaultRulesMatchFunc RulesMatchFunc = func(rule1, rule2 Rule) (bool, error)
return outputMatches && conditionMatches, nil
}

var RulesMatch = DefaultRulesMatchFunc

// SetMutateFunc changes the mutate function to the function specified
func SetRulesMatchFunc(f RulesMatchFunc) {
RulesMatch = f
func (genA *GeneticAlgorithm) SetDecodeRulesFunc(f DecodeRulesFunc) {
genA.DecodeRules = f
}

func (r Rule) String() string {
return fmt.Sprintf("%v %v", r.Condition, r.Output)
}

func DecodeRuleBase(sequence Bitstring, conditionLength, ruleLength int) RuleBase {
var DefaultDecodeRulesFunc DecodeRulesFunc = func(sequence Bitstring, conditionLength, ruleLength int) (RuleBase, error) {
NewRuleBase := make([]Rule, 0)
for i := 0; i < len(sequence); i += ruleLength {
condition := make(Bitstring, len(sequence[i:i+conditionLength]))
copy(condition, sequence[i:i+conditionLength])
rule := Rule{condition, sequence[i+conditionLength]}
NewRuleBase = append(NewRuleBase, rule)
}
return NewRuleBase
return NewRuleBase, nil
}

// SetMutateFunc changes the mutate function to the function specified
func (genA *GeneticAlgorithm) SetEncodeRulesFunc(f EncodeRulesFunc) {
genA.EncodeRules = f
}

func EncodeRuleBase(paramRuleBase RuleBase) Bitstring {
var DefaultEncodeRulesFunc = func(paramRuleBase RuleBase) (Bitstring, error) {
var sequence Bitstring
for _, rule := range paramRuleBase {
for _, condition := range rule.Condition {
Expand All @@ -62,5 +72,5 @@ func EncodeRuleBase(paramRuleBase RuleBase) Bitstring {
sequence = append(sequence, string(output))
}
}
return sequence
return sequence, nil
}
Loading

0 comments on commit 1c20e7f

Please sign in to comment.