Skip to content

Commit

Permalink
WIP Add Option Importance solver util
Browse files Browse the repository at this point in the history
  • Loading branch information
Glavin001 committed Aug 21, 2018
1 parent 65f8879 commit 8bc684e
Show file tree
Hide file tree
Showing 21 changed files with 578 additions and 325 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"unibeautify": "ts-node src/UnibeautifySolver.ts",
"test2": "ts-node src/PhraseSolver.ts",
"test": "npm run build && npm run jest",
"start": "ts-node scripts/run.ts",
"start:run": "ts-node scripts/run.ts",
"start:importance": "ts-node scripts/importance.ts",
"start": "npm run start:run",
"calcSpace": "ts-node scripts/calcSpace.ts"
},
"repository": {
Expand Down
23 changes: 23 additions & 0 deletions scripts/importance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Beautifier } from "unibeautify";
import prettier from "@unibeautify/beautifier-prettier";
import jsBeautify from "@unibeautify/beautifier-js-beautify";
import fileBeautifier from "@unibeautify/beautifier-file";

import {
ImportantOptionsRegistryBuilder,
} from "../src/OptionImportance";

const beautifiers: Beautifier[] = [prettier, jsBeautify, fileBeautifier];

const desiredText = `/** @format */\r\n\r\nif (true) {\r\n console.log('hello world');\r\n helloWorld();\r\n}\r\n`;

const userData: UserData = {
beautifiers,
language: "JavaScript",
desiredText,
};

const builder = new ImportantOptionsRegistryBuilder(userData);
builder.buildImportantOptionsRegistry().then(registry => {
console.log(JSON.stringify(registry, null, 2));
});
195 changes: 119 additions & 76 deletions scripts/run.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
import * as Genetic from "@glavin001/genetic-js";
import { Beautifier } from "unibeautify";
import { Beautifier, OptionValues } from "unibeautify";
import prettier from "@unibeautify/beautifier-prettier";
import jsBeautify from "@unibeautify/beautifier-js-beautify";
import fileBeautifier from "@unibeautify/beautifier-file";
// import * as fs from "fs";
// import * as path from "path";
import * as fs from "fs";
import * as path from "path";
// import * as _ from "lodash";
// import * as stringify from "json-stable-stringify";
import * as asciichart from "asciichart";

import { UserData, Entity } from "../src/index";
import { UserData, Entity, UnibeautifyGenetic } from "../src/index";
import { ConfigSolver } from "../src/ConfigSolver";

// const fixtureText = fs
// .readFileSync(path.resolve(__dirname, "../test/fixtures/ReactElement.js"))
// .toString();
const fixtureText = fs
.readFileSync(path.resolve(__dirname, "../test/fixtures/ReactElement.js"))
.toString();

const beautifiers: Beautifier[] = [prettier, jsBeautify, fileBeautifier];
const configuration: Partial<Genetic.Configuration> = {
iterations: 30,
// size: 50,
// iterations: 1000,
// size: 100,
size: 200,
// iterations: 300,
// size: 50,
size: 10,
crossover: 0.8,
mutation: 0.5,
// mutation: 0.75,
// mutation: 0.5,
mutation: 0.75,
// skip: 5,
// iterations: 20,
// size: 5,
// crossover: 0.8,
// mutation: 0.5,
skip: 1,
};

const desiredText = `/** @format */\r\n\r\nif (true) {\r\n console.log('hello world');\r\n helloWorld();\r\n}\r\n`;

const userData: UserData = {
beautifiers,
language: "JavaScript",

originalText: desiredText,
desiredText,
// originalText: desiredText,
// desiredText,

// originalText: `console.log("hello world");`,
// desiredText: `/** @format */\n\nconsole.log('hello world')\n`,
Expand All @@ -67,8 +68,8 @@ const userData: UserData = {
// originalText: `console.log('hello world')\n`,
// desiredText: `console.log('hello world')\n`,

// originalText: fixtureText,
// desiredText: fixtureText,
originalText: fixtureText,
desiredText: fixtureText,
};
const desiredEntity: Entity = {
options: {
Expand Down Expand Up @@ -97,13 +98,29 @@ const genetic = new ConfigSolver({
userData,
});

/*
genetic.optionsImportance
.buildImportantOptionsRegistry()
.then(optionsRegistry => {
console.log(JSON.stringify(optionsRegistry, null, 2));
const importantOptionKeys = Object.keys(optionsRegistry);
const allOptionKeys = Object.keys(genetic.optionsRegistry);
console.log(
`${importantOptionKeys.length} of ${
allOptionKeys.length
} keys are important`
);
// (genetic as any).optionsRegistry = optionsRegistry;
// genetic.evolve().catch(console.error);
});
*/

const history: number[] = [];
genetic.notification = function({
population,
isFinished,
generation,
stats,
}: Genetic.Notification<Entity>) {
genetic.notification = function(
this: typeof genetic,
{ population, isFinished, generation, stats }: Genetic.Notification<Entity>
) {
const bestFromPop = population[0];
console.log(generation, bestFromPop.fitness, isFinished, stats);
console.log(`[ ${population.map(entity => entity.fitness).join(", ")} ]`);
Expand All @@ -112,64 +129,90 @@ genetic.notification = function({
// console.log(history);
console.log(asciichart.plot(history, { height: 20 }));
}
// if (isFinished) {
Promise.all([
this.beautify(this.originalText, bestFromPop.entity),
this.beautify(this.originalText, desiredEntity),
]).then(([beautifiedText, desiredText]: [string, string]) => {
console.log(`Solution after ${generation} generations:`);
console.log(JSON.stringify(bestFromPop, null, 2));
console.log(JSON.stringify(stats, null, 2));
console.log(
JSON.stringify(
{
fitness: bestFromPop.fitness,
diff: this.diffCount(beautifiedText, desiredText),
optionsUsed: this.optionsUsed(bestFromPop.entity),
allOptions: this.optionsCount,
},
null,
2
)
if (isFinished) {
Promise.all([
this.beautify(this.originalText, bestFromPop.entity),
this.beautify(this.originalText, desiredEntity),
this.trimOptions(bestFromPop.entity.options),
]).then(
([beautifiedText, desiredText, trimmedOptions]: [
string,
string,
OptionValues
]) => {
console.log(`Solution after ${generation} generations:`);
console.log(JSON.stringify(bestFromPop, null, 2));
console.log(JSON.stringify(trimmedOptions, null, 2));
console.log(JSON.stringify(stats, null, 2));
console.log(
JSON.stringify(
{
fitness: bestFromPop.fitness,
diff: this.diffCount(beautifiedText, desiredText),
optionsUsed: this.optionsUsed(bestFromPop.entity),
allOptions: this.optionsCount,
},
null,
2
)
);

// console.log("-".repeat(20));
// console.log(`${"-".repeat(10)} Alternative Entities ${"-".repeat(10)}`);
// const diffCount = Math.floor(bestFromPop.fitness / 10000);
// _.uniqBy(
// population.filter(({ fitness }) => {
// return Math.floor(fitness / 10000) === diffCount;
// }),
// stringify
// ).forEach((entity, index) => {
// console.log(`${"-".repeat(10)} Config ${index + 1} ${"-".repeat(10)}`);
// console.log(JSON.stringify(entity, null, 2));
// });

console.log(`${"-".repeat(10)} Desired Text ${"-".repeat(10)}`);
console.log(this.desiredText);
console.log(
`${"-".repeat(10)} Text from Desired Options ${"-".repeat(10)}`
);
console.log(desiredText);
console.log(`${"-".repeat(10)} Beautified Text ${"-".repeat(10)}`);
console.log(beautifiedText);
console.log("-".repeat(20));
// console.log(history);
console.log(asciichart.plot(history, { height: 40 }));
console.log("-".repeat(20));

const { configuration } = this as any;
const progress: string = (
generation /
configuration.iterations *
100
).toFixed(2);
console.log(
`${progress}% progress... (${generation} of ${
configuration.iterations
})`
);
}
);
} else {
population.slice(0, 1).forEach((entity, index) => {
console.log(`${"-".repeat(10)} Config ${index + 1} ${"-".repeat(10)}`);
console.log(JSON.stringify(entity, null, 2));
});

// console.log("-".repeat(20));
// console.log(`${"-".repeat(10)} Alternative Entities ${"-".repeat(10)}`);
// const diffCount = Math.floor(bestFromPop.fitness / 10000);
// _.uniqBy(
// population.filter(({ fitness }) => {
// return Math.floor(fitness / 10000) === diffCount;
// }),
// stringify
// ).forEach((entity, index) => {
// console.log(`${"-".repeat(10)} Config ${index + 1} ${"-".repeat(10)}`);
// console.log(JSON.stringify(entity, null, 2));
// });

console.log(`${"-".repeat(10)} Desired Text ${"-".repeat(10)}`);
console.log(this.desiredText);
console.log(
`${"-".repeat(10)} Text from Desired Options ${"-".repeat(10)}`
);
console.log(desiredText);
console.log(`${"-".repeat(10)} Beautified Text ${"-".repeat(10)}`);
console.log(beautifiedText);
console.log("-".repeat(20));
// console.log(history);
console.log(asciichart.plot(history, { height: 40 }));
console.log("-".repeat(20));

const { configuration } = this as any;
const progress: string = (
generation /
configuration.iterations *
100
).toFixed(2);
console.log(
`${(generation / this.configuration.iterations * 100).toFixed(
2
)}% progress... (${generation} of ${this.configuration.iterations})`
`${progress}% progress... (${generation} of ${configuration.iterations})`
);
});
// } else {
// population.slice(0, 1).forEach((entity, index) => {
// console.log(`${"-".repeat(10)} Config ${index + 1} ${"-".repeat(10)}`);
// console.log(JSON.stringify(entity, null, 2));
// });
// }
console.log(`Last generation with same fitness: ${this.lastGenWithSameFitness(bestFromPop.fitness)}`);
}
};
genetic.evolve().catch(console.error);
14 changes: 9 additions & 5 deletions src/ConfigSolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as _ from "lodash";
import { UnibeautifyGenetic, Options, Entity } from "./UnibeautifySolver";

export class ConfigSolver extends UnibeautifyGenetic {
private readonly optionsCount: number;
// private readonly optionsCount: number;
private readonly originalTextVariations: Promise<string>[];

constructor(options: Options) {
Expand All @@ -17,9 +17,9 @@ export class ConfigSolver extends UnibeautifyGenetic {
);
}
super(options);
this.optionsCount = this.optionKeys.length;
// this.optionsCount = this.optionKeys.length;
console.log(JSON.stringify(this.optionKeys, null, 2));
const variationsCount = 30;
const variationsCount = 10;
this.originalTextVariations = [];
for (let currSeed = 0; currSeed < variationsCount; ++currSeed) {
this.originalTextVariations.push(
Expand All @@ -28,6 +28,10 @@ export class ConfigSolver extends UnibeautifyGenetic {
}
}

public get optionsCount(): number {
return this.optionKeys.length;
}

protected internalFitness(entity: Entity): Promise<number> {
return Promise.all(this.originalTextVariations)
.then(originalTextVariations => {
Expand Down Expand Up @@ -98,11 +102,11 @@ export class ConfigSolver extends UnibeautifyGenetic {
);
}

protected diffCount(src: string, dest: string): number {
public diffCount(src: string, dest: string): number {
return fastLevenshtein.get(src, dest);
}

protected optionsUsed(entity: Entity): number {
public optionsUsed(entity: Entity): number {
const ignoreOptionKeys = [
"beautifiers",
// "indent_size",
Expand Down
Loading

0 comments on commit 8bc684e

Please sign in to comment.