') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - NesCafe62/GeneticAlgorithm: С# Genetic algorithm library · GitHub
Skip to content

Latest commit

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GeneticAlgorithm

Lightweight genetic algorithm library wtitten in С# with ability to customize operators and define own

Usage

Define gene, chromosome and fitness function

Fitness function higher values treated as better. Calculate fintess can return any values even negative. Except if you use RouletteWheelSelection, in that case values need to be more than zero.

classMyGene:IGene{publicintValue;publicMyGene(intvalue){Value=value;}}classMyChromosome:IChromosome{publicdouble?Fitness{get;set;}publicintLength{get;}publicint[]Values;publicMyChromosome(int[]values){Values=values;Length=Values.Length;}publicIChromosomeClone(){varchromosome=newMyChromosome(Values);chromosome.Fitness=Fitness;returnchromosome;}publicvoidSetGene(intindex,IGenegene){Values[index]=((MyGene)gene).Value;}publicIGeneGetGene(intindex){returnnewMyGene(Values[index]);}}classMyFitness:IFitness{publicdoubleCalculateFitness(IChromosomechromosome){varmyChromosome=(MyChromosome)chromosome;intcounter=0;// for example count how many neighbout numbers differ by only 1for(inti=0;i<myChromosome.Length-1;i++){if(Math.Abs(myChromosome.Values[i]-myChromosome.Values[i+1])==1){counter++;}}returncounter;}}

Define chromosome validator (optional)

classMyChromosomeValidator:IChromosomeValidator{publicboolValidate(IChromosomechromosome){varmyChromosome=(MyChromosome)chromosome;// some validation logic herereturntrue;}}

Define chromosome and gene factory

It can be two separate classes or just one single class

classMyChromosomeFactory:IChromosomeFactory,IGeneFactory{privateintcount;privateintmaxValue;privateintminValue;privateRandomrandom;publicMyChromosomeFactory(intcount,intminValue,intmaxValue,Randomrandom){this.count=count;this.minValue=minValue;this.maxValue=maxValue;this.random=random;}privateintGenerateGene(intindex){returnrandom.Next(minValue,maxValue);}publicIGeneCreateGene(intindex){returnnewMyGene(GenerateGene(index));}publicIChromosomeCreateChromosome(){varvalues=newint[count];for(inti=0;i<count;i++){values[i]=GenerateGene(i);}returnnewMyChromosome(values);}}

Creating chromosome and gene factories

varchromosomeFactory=newMyChromosomeFactory(10,-5,5,newRandom());vargeneFactory=chromosomeFactory;

Creating algorithm options

varoptions=newGeneticAlgorithmOptions{// factory that will be used for creating new chromosomesChromosomeFactory=chromosomeFactory,// number of chromosomes in generationGenerationSize=20,// chance that selected parent will be crossed to create new chromosomesCrossoverProbability=0.8,// chance that chromosomes created by crossover will be mutatedMutationProbability=0.1,// how long continue to run algorithm if best chromosome fitness is not changing// [optional]// default value: 50TerminateUnchangedGenetarionsCount=50,// fitness functionFitness=newMyFitness(),// selection operatorSelection=newEliteSelection(),// Selection = new RouletteWheelSelection(new Random()),// Selection = new TournamentSelection(new Random(), roundSize: 3),// parent selection operatorParentSelection=newRandomParentSelection(newRandom()),// ParentSelection = new InbreedingParentSelection(new Random()),// crossover operatorCrossover=newSinglePointCrossover(chromosomeFactory,newRandom()),// Crossover = new MultiPointCrossover(chromosomeFactory, new Random(), pointsCount: 3),// mutation operatorMutation=newRandomMutation<MyGene>(geneFactory,newRandom()),// Mutation = new SwapMutation<MyGene>(new Random()),// Mutation = new ReverseMutation<MyGene>(new Random()),// [optional]// default value: EmptyValidatorValidator=newMyChromosomeValidator(),// delegate function (event) that will be executed after each algorithm iteration// [optional]OnAfterIteration=(generation)=>{// output generation chromosomes for example}};

Creating and running genetic algorithm

// creting genetic algorithmga=newGeneticAlgorithm(options);// alowed to set after iteration delegate from here alsoga.OnAfterIteration+=(generation)=>{// ...};// running algorithmga.Run();// getting resultintgenerationsCount=ga.GenerationsCount;varbestChromosome=(MyChromosome)ga.BestChromosome;

Islands genetic algorithm

...

Selection operators

EliteSelection()

Takes best chromosomes of generation determined by fintess function

RouletteWheelSelection(Random random)

Picks chromosomes from a wheel, where probability is proportional to fintess function, until number of chromosomes in new generation match required generation size

TournamentSelection(Random random, int roundSize)

roundSize: Number of chromosomes participating in each tournament round

Takes winner chromosome (by fitness function) to new generation from each tournament round until new generation match required generation size. Participants are picked randomly (so same chromosome can be taken multiple times, though Clone method will guarantee unique chromosome instances in new generation)

Parent selection operators

RandomParentSelection(Random random)

...

InbreedingParentSelection(Random random)

...

Crossover operators

SinglePointCrossover(IChromosomeFactory factory, Random random)

factory: chromosome factory

...

MultiPointCrossover(IChromosomeFactory factory, Random random, int pointsCount)

factory: chromosome factory

pointsCount: number of chromosome split points

...

Mutation operators

RandomMutation(IGeneFactory factory, Random random)

factory: gene factory

...

SwapMutation(Random random)

...

ReverseMutation(Random random)

...

Defining custom operators

...

About

С# Genetic algorithm library

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages