-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7ed2827
commit 4f124bc
Showing
3 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
73 changes: 73 additions & 0 deletions
73
src/lib/crossover/numeric/floating/BaseFloatingCrossover.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* @license | ||
* Copyright (c) 2019 Cristian Abrante. All rights reserved. | ||
* Licensed under the MIT License. See LICENSE in the project root for license information. | ||
*/ | ||
|
||
import { Generator } from '../../../generator/utils'; | ||
import { NumericRange } from '../../../individual/numeric/base'; | ||
import { FloatingIndividual } from '../../../individual/numeric/floating'; | ||
import BaseCrossover from '../../base/BaseCrossover'; | ||
import { CrossoverParams, IndividualConstructor } from '../../base/Crossover'; | ||
|
||
export interface BaseFloatingCrossoverParams extends CrossoverParams<FloatingIndividual, number> { | ||
alpha: number; | ||
} | ||
|
||
abstract class BaseFloatingCrossover extends BaseCrossover<FloatingIndividual, number, BaseFloatingCrossoverParams> { | ||
private recombinationPoint: number = 0; | ||
public cross( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
alpha = 0.5, | ||
engine = Generator.DEFAULT_ENGINE, | ||
): FloatingIndividual[] { | ||
return this.crossWith(firstParent, secondParent, { engine, alpha, individualConstructor: FloatingIndividual }); | ||
} | ||
|
||
public crossWith( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
params: BaseFloatingCrossoverParams, | ||
): FloatingIndividual[] { | ||
this.generateRecombinationPoint(firstParent.length(), params); | ||
this.checkParams(params); | ||
return super.crossWith(firstParent, secondParent, params); | ||
} | ||
|
||
protected getGenotypeValues( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
params: BaseFloatingCrossoverParams, | ||
index: number, | ||
): { first: number; second: number } { | ||
const recombinationCondition = this.getRecombinationCondition(index); | ||
const firstValue = firstParent.get(index); | ||
const secondValue = secondParent.get(index); | ||
return { | ||
first: recombinationCondition ? firstValue : this.getRecombinationValue(firstValue, secondValue, params), | ||
second: recombinationCondition ? secondValue : this.getRecombinationValue(secondValue, firstValue, params), | ||
}; | ||
} | ||
|
||
protected abstract getRecombinationCondition(index: number): boolean; | ||
|
||
protected getRecombinationValue( | ||
firstParentValue: number, | ||
secondParentValue: number, | ||
params: BaseFloatingCrossoverParams, | ||
): number { | ||
const { alpha } = params; | ||
return alpha * firstParentValue + (1.0 - alpha) * secondParentValue; | ||
} | ||
|
||
private checkParams(params: BaseFloatingCrossoverParams) { | ||
if (!Generator.probabilityIsValid(params.alpha)) { | ||
throw new Error(`BaseFloatingCrossover: alpha of ${params.alpha} is not in range [0.0, 1.0]`); | ||
} | ||
} | ||
|
||
private generateRecombinationPoint(parentsLength: number, params: BaseFloatingCrossoverParams) { | ||
this.recombinationPoint = Generator.generateInteger(new NumericRange(0, parentsLength - 1), params.engine); | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
src/lib/crossover/numeric/floating/SimpleArithmeticRecombination.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* @license | ||
* Copyright (c) 2019 Cristian Abrante. All rights reserved. | ||
* Licensed under the MIT License. See LICENSE in the project root for license information. | ||
*/ | ||
|
||
import { Generator } from '../../../generator/utils'; | ||
import { NumericRange } from '../../../individual/numeric/base'; | ||
import { FloatingIndividual } from '../../../individual/numeric/floating'; | ||
import BaseCrossover from '../../base/BaseCrossover'; | ||
import { CrossoverParams, IndividualConstructor } from '../../base/Crossover'; | ||
|
||
export interface SimpleArithmeticRecombinationParams extends CrossoverParams<FloatingIndividual, number> { | ||
alpha: number; | ||
} | ||
|
||
class SimpleArithmeticRecombination extends BaseCrossover< | ||
FloatingIndividual, | ||
number, | ||
SimpleArithmeticRecombinationParams | ||
> { | ||
private recombinationPoint: number = 0; | ||
|
||
public cross( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
individualConstructor: IndividualConstructor<FloatingIndividual, number>, | ||
alpha = 0.5, | ||
engine = Generator.DEFAULT_ENGINE, | ||
): FloatingIndividual[] { | ||
return this.crossWith(firstParent, secondParent, { | ||
alpha, | ||
engine, | ||
individualConstructor, | ||
}); | ||
} | ||
|
||
public crossWith( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
params: SimpleArithmeticRecombinationParams, | ||
): FloatingIndividual[] { | ||
this.generateRecombinationPoint(firstParent.length(), params); | ||
return super.crossWith(firstParent, secondParent, params); | ||
} | ||
|
||
protected getGenotypeValues( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
params: SimpleArithmeticRecombinationParams, | ||
index: number, | ||
): { first: number; second: number } { | ||
const parentSelectionCondition = index < this.recombinationPoint; | ||
const firstValue = firstParent.get(index); | ||
const secondValue = secondParent.get(index); | ||
return { | ||
first: parentSelectionCondition ? firstValue : this.getRecombinedValues(secondValue, firstValue, params), | ||
second: parentSelectionCondition ? secondValue : this.getRecombinedValues(firstValue, secondValue, params), | ||
}; | ||
} | ||
|
||
private getRecombinedValues(firstValue: number, secondValue: number, params: SimpleArithmeticRecombinationParams) { | ||
return params.alpha * firstValue + (1.0 - params.alpha) * secondValue; | ||
} | ||
|
||
private generateRecombinationPoint(parentsLength: number, params: SimpleArithmeticRecombinationParams) { | ||
this.recombinationPoint = Generator.generateInteger(new NumericRange(1, parentsLength - 1), params.engine); | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
src/lib/crossover/numeric/floating/SingleArithmeticRecombination.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* @license | ||
* Copyright (c) 2019 Cristian Abrante. All rights reserved. | ||
* Licensed under the MIT License. See LICENSE in the project root for license information. | ||
*/ | ||
|
||
import { Generator } from '../../../generator/utils'; | ||
import { NumericRange } from '../../../individual/numeric/base'; | ||
import { FloatingIndividual } from '../../../individual/numeric/floating'; | ||
import BaseCrossover from '../../base/BaseCrossover'; | ||
import { CrossoverParams } from '../../base/Crossover'; | ||
import { SimpleArithmeticRecombinationParams } from './SimpleArithmeticRecombination'; | ||
|
||
export interface SingleArithmeticRecombinationParams extends CrossoverParams<FloatingIndividual, number> { | ||
alpha: number; | ||
} | ||
|
||
class SingleArithmeticRecombination extends BaseCrossover< | ||
FloatingIndividual, | ||
number, | ||
SingleArithmeticRecombinationParams | ||
> { | ||
private recombinationPoint: number = 0; | ||
|
||
public cross( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
...args: any[] | ||
): FloatingIndividual[] { | ||
return []; | ||
} | ||
|
||
public crossWith( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
params: SingleArithmeticRecombinationParams, | ||
): FloatingIndividual[] { | ||
this.generateRecombinationPoint(firstParent.length(), params); | ||
return super.crossWith(firstParent, secondParent, params); | ||
} | ||
|
||
protected getGenotypeValues( | ||
firstParent: FloatingIndividual, | ||
secondParent: FloatingIndividual, | ||
params: SingleArithmeticRecombinationParams, | ||
index: number, | ||
): { first: number; second: number } { | ||
const parentSelectionCondition = index === this.recombinationPoint; | ||
const firstValue = firstParent.get(index); | ||
const secondValue = secondParent.get(index); | ||
return { | ||
first: parentSelectionCondition ? firstValue : this.getRecombinedValues(secondValue, firstValue, params), | ||
second: parentSelectionCondition ? secondValue : this.getRecombinedValues(firstValue, secondValue, params), | ||
}; | ||
} | ||
|
||
private getRecombinedValues(firstValue: number, secondValue: number, params: SimpleArithmeticRecombinationParams) { | ||
return params.alpha * firstValue + (1.0 - params.alpha) * secondValue; | ||
} | ||
|
||
private generateRecombinationPoint(parentsLength: number, params: SimpleArithmeticRecombinationParams) { | ||
this.recombinationPoint = Generator.generateInteger(new NumericRange(1, parentsLength - 1), params.engine); | ||
} | ||
} |