-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
improvements, password test and wip salesman
- Loading branch information
Tom Hohler
committed
Apr 16, 2018
1 parent
c4bb1d8
commit 56b45be
Showing
6 changed files
with
179 additions
and
117 deletions.
There are no files selected for viewing
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,54 @@ | ||
import { Selection } from "../genetic/methods"; | ||
import { Candidate, Population } from "../genetic/model"; | ||
|
||
export function findPassword(password: string) { | ||
|
||
const fitness = (pass: string) => (genes: string[]) => { | ||
const passwordArray = pass.split(""); | ||
if (genes.length !== pass.length) { | ||
throw Error("passwords length not matching"); | ||
} | ||
let score = 0; | ||
for (let i = 0; i < genes.length; i++) { | ||
if (genes[i] === passwordArray[i]) { | ||
score += 1; | ||
} | ||
} | ||
return score * 100 / pass.length; | ||
}; | ||
|
||
const mutate = (pass: string) => (genes: string[]) => { | ||
const genesCopy = genes.slice(); | ||
const mutatedIndex = Math.floor(Math.random() * pass.length); | ||
genesCopy[mutatedIndex] = getRandomLetter(); | ||
return genesCopy; | ||
}; | ||
|
||
const generateRandomGenes = (pass: string) => () => { | ||
const genes = []; | ||
for (let i = 0; i < pass.length; i++) { | ||
genes.push(getRandomLetter()); | ||
} | ||
return genes; | ||
}; | ||
|
||
let pop = Population.generatePopulation( | ||
100, | ||
generateRandomGenes(password), | ||
{ | ||
fitness: fitness(password), | ||
mutate: mutate(password), | ||
mutationProbability: 0.4 | ||
} | ||
); | ||
|
||
for (let i = 0; i < 100; i++) { | ||
document.getElementById("main")!.innerHTML | ||
+= ("<br/><br />" + pop.candidates[0].genes + ", fitness: " + pop.candidates[0].fitness(pop.candidates[0].genes)); | ||
pop = pop.createNextGeneration(); | ||
} | ||
|
||
function getRandomLetter() { | ||
return String.fromCharCode(97 + Math.floor(Math.random() * 26)); | ||
} | ||
} |
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,70 @@ | ||
import { Selection } from "../genetic/methods"; | ||
import { Candidate, Population } from "../genetic/model"; | ||
|
||
export interface Position { | ||
x: number; | ||
y: number; | ||
} | ||
|
||
export function salesman(towns: Position[]) { | ||
|
||
const fitness = (genes: number[]) => { | ||
const totalDistance = genes.reduce((acc, gene, index) => { | ||
if (index === 0) { | ||
return 0; | ||
} | ||
return acc + distance(towns[gene], towns[genes[index - 1]]); | ||
}); | ||
return 1 / totalDistance; | ||
}; | ||
|
||
const mutate = (genes: number[]) => { | ||
const genesCopy = genes.slice(); | ||
const mutatedIndex1 = Math.floor(Math.random() * genes.length); | ||
const mutatedIndex2 = Math.floor(Math.random() * genes.length); | ||
[genesCopy[mutatedIndex1], genesCopy[mutatedIndex2]] = [genesCopy[mutatedIndex2], genesCopy[mutatedIndex1]]; | ||
return genesCopy; | ||
}; | ||
|
||
const cross = (motherGenes: number[], fatherGenes: number[]) => { | ||
const startPos = 0; | ||
} | ||
|
||
let pop = Population.generatePopulation( | ||
20, | ||
createRandomGenotype, | ||
{ | ||
fitness, | ||
mutate, | ||
cross, | ||
mutationProbability: 0.4 | ||
} | ||
); | ||
|
||
for (let i = 0; i < 40; i++) { | ||
document.getElementById("main")!.innerHTML | ||
+= ("<br/><br />" + pop.candidates[0].genes + ", fitness: " + pop.candidates[0].fitness(pop.candidates[0].genes)); | ||
pop = pop.createNextGeneration(); | ||
} | ||
|
||
function createRandomGenotype() { | ||
const genotype = Array.from({length: towns.length}, (v, k) => k); | ||
shuffleArray(genotype); | ||
return genotype; | ||
} | ||
} | ||
|
||
function distance(pos1: Position, pos2: Position) { | ||
return Math.sqrt(Math.pow(pos2.x - pos1.x, 2) + Math.pow(pos2.y - pos1.y, 2)); | ||
} | ||
|
||
/** | ||
* Randomize array element order in-place. | ||
* Using Durstenfeld shuffle algorithm. | ||
*/ | ||
function shuffleArray(array: any[]) { | ||
for (let i = array.length - 1; i > 0; i--) { | ||
const j = Math.floor(Math.random() * (i + 1)); | ||
[array[i], array[j]] = [array[j], array[i]]; | ||
} | ||
} |
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,19 @@ | ||
export class Crossover { | ||
static SINGLE_POINT = (crossProbability: number = 0.8) => <T>(motherGenes: T[], fatherGenes: T[]) => { | ||
const firstChildGenes: T[] = []; | ||
const secondChildGenes: T[] = []; | ||
/** | ||
* Cross the two parents genes according to the cross probability | ||
*/ | ||
for (let i = 0; i < motherGenes.length ; i++) { | ||
firstChildGenes.push(Math.random() < crossProbability ? motherGenes[i] : fatherGenes[i]); | ||
secondChildGenes.push(Math.random() < crossProbability ? fatherGenes[i] : motherGenes[i]); | ||
} | ||
|
||
return [ | ||
firstChildGenes, | ||
secondChildGenes | ||
]; | ||
|
||
} | ||
} |
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
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
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 |
---|---|---|
@@ -1,62 +1,13 @@ | ||
import { Selection } from "./genetic/methods"; | ||
import { Candidate, Population } from "./genetic/model"; | ||
|
||
const PASSWORD = "hardcorepasswordmasterrace"; | ||
const fitness = (password: string) => (genes: string[]) => { | ||
const passwordArray = password.split(""); | ||
if (genes.length !== password.length) { | ||
throw Error("passwords length not matching"); | ||
} | ||
let score = 0; | ||
for (let i = 0; i < genes.length; i++) { | ||
if (genes[i] === passwordArray[i]) { | ||
score += 1; | ||
} | ||
} | ||
return score * 100 / password.length; | ||
}; | ||
|
||
const mutate = (password: string) => (genes: string[]) => { | ||
const genesCopy = genes.slice(); | ||
const mutatedIndex = Math.floor(Math.random() * PASSWORD.length); | ||
genesCopy[mutatedIndex] = getRandomLetter(); | ||
return genesCopy; | ||
}; | ||
|
||
// Create the networks | ||
const candidates = []; | ||
|
||
for (let i = 0; i < 100; i ++) { | ||
const genes = generateRandomGenes(); | ||
const candidate = new Candidate<string>( | ||
generateRandomGenes(), | ||
{ | ||
fitness: fitness(PASSWORD), | ||
mutate: mutate(PASSWORD), | ||
mutationProbability: 0.4 | ||
} | ||
); | ||
candidates.push(candidate); | ||
} | ||
|
||
const initialPop = new Population(candidates); | ||
|
||
let pop = initialPop; | ||
|
||
for (let i = 0; i < 100; i ++) { | ||
document.getElementById("main")!.innerHTML | ||
+= ("<br/><br />" + pop.candidates[0].genes + ", fitness: " + pop.candidates[0].fitness(pop.candidates[0].genes)); | ||
pop = pop.createNextGeneration(); | ||
} | ||
|
||
function generateRandomGenes() { | ||
const genes = []; | ||
for (let i = 0; i < PASSWORD.length; i++) { | ||
genes.push(getRandomLetter()); | ||
} | ||
return genes; | ||
} | ||
|
||
function getRandomLetter() { | ||
return String.fromCharCode(97 + Math.floor(Math.random() * 26)); | ||
} | ||
import { findPassword } from "./demos/findPassword"; | ||
import { salesman } from "./demos/salesman"; | ||
|
||
// findPassword("passwordhardcoretropduratrouver"); | ||
salesman([ | ||
{x: 0, y: 0}, | ||
{x: 1, y: 1}, | ||
{x: 2, y: 2}, | ||
{x: 3, y: 3}, | ||
{x: 4, y: 4}, | ||
{x: 4, y: 0}, | ||
{x: 0, y: 4} | ||
]); |