{"id":18305755,"url":"https://github.com/yaricom/goneat","last_synced_at":"2025-10-05T19:14:18.465Z","repository":{"id":39650128,"uuid":"102864171","full_name":"yaricom/goNEAT","owner":"yaricom","description":"The GOLang implementation of NeuroEvolution of Augmented Topologies (NEAT) method to evolve and train Artificial Neural Networks without error back propagation","archived":false,"fork":false,"pushed_at":"2024-12-24T12:14:45.000Z","size":3712,"stargazers_count":78,"open_issues_count":10,"forks_count":18,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-09-05T15:19:37.790Z","etag":null,"topics":["artificial-neural-networks","augmenting-topologies","neat","neural-network","neuroevolution","reinforcement-learning","reinforcement-learning-algorithms","unsupervised-learning","unsupervised-machine-learning"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yaricom.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"patreon":"io42","custom":["https://www.buymeacoffee.com/io42"]}},"created_at":"2017-09-08T13:26:28.000Z","updated_at":"2025-08-14T11:15:26.000Z","dependencies_parsed_at":"2023-12-26T06:36:30.964Z","dependency_job_id":"dd62be38-1167-47f0-a5df-5f582186453b","html_url":"https://github.com/yaricom/goNEAT","commit_stats":{"total_commits":769,"total_committers":2,"mean_commits":384.5,"dds":"0.0039011703511053764","last_synced_commit":"e79a27c98c4bf096553f70e3eb8c27ef9ac770f2"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/yaricom/goNEAT","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yaricom%2FgoNEAT","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yaricom%2FgoNEAT/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yaricom%2FgoNEAT/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yaricom%2FgoNEAT/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yaricom","download_url":"https://codeload.github.com/yaricom/goNEAT/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yaricom%2FgoNEAT/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278504819,"owners_count":25998014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["artificial-neural-networks","augmenting-topologies","neat","neural-network","neuroevolution","reinforcement-learning","reinforcement-learning-algorithms","unsupervised-learning","unsupervised-machine-learning"],"created_at":"2024-11-05T15:35:35.537Z","updated_at":"2025-10-05T19:14:18.420Z","avatar_url":"https://github.com/yaricom.png","language":"Go","funding_links":["https://patreon.com/io42","https://www.buymeacoffee.com/io42","https://img.buymeacoffee.com/button-api/?text=Buy"],"categories":[],"sub_categories":[],"readme":"# goNEAT 🇺🇦 [![Made in Ukraine](https://img.shields.io/badge/made_in-ukraine-ffd700.svg?labelColor=0057b7)](https://u24.gov.ua)\n[![banner](contents/book_title.png)][6]\n\n[NeuroEvolution — evolving Artificial Neural Networks topology from the scratch](https://becominghuman.ai/neuroevolution-evolving-artificial-neural-networks-topology-from-the-scratch-d1ebc5540d84)\n\n[![version](https://img.shields.io/github/v/tag/yaricom/goNEAT.svg?sort=semver)](https://github.com/yaricom/goNEAT/releases/latest)\n[![GoDoc](https://godoc.org/github.com/yaricom/goNEAT/neat?status.svg)](https://godoc.org/github.com/yaricom/goNEAT/neat)\n[![Go version](https://img.shields.io/badge/go-1.18-blue.svg)](https://github.com/moovweb/gvm)\n[![license](https://img.shields.io/github/license/yaricom/goNEAT.svg)](https://github.com/yaricom/goNEAT/blob/master/LICENSE)\n[![yaricom/goNEAT](https://tokei.rs/b1/github/yaricom/goNEAT?category=lines)](https://github.com/yaricom/goNEAT)\n[![DOI](https://zenodo.org/badge/102864171.svg)](https://zenodo.org/badge/latestdoi/102864171)\n\n| Branch | Tests                                                                                      | Coverage                                                                                                                             | Linting                                                                    | Code Security                                                                    |\n|--------|--------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------|----------------------------------------------------------------------------|\n| master | [![CI](https://github.com/yaricom/goNEAT/actions/workflows/ci.yml/badge.svg)](https://github.com/yaricom/goNEAT/actions/workflows/ci.yml) | [![codecov](https://codecov.io/gh/yaricom/goNEAT/branch/master/graph/badge.svg?token=as31613DnV)](https://codecov.io/gh/yaricom/goNEAT) | [![Lint](https://github.com/yaricom/goNEAT/actions/workflows/lint.yml/badge.svg)](https://github.com/yaricom/goNEAT/actions/workflows/lint.yml) | [![CodeQL](https://github.com/yaricom/goNEAT/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/yaricom/goNEAT/actions/workflows/codeql-analysis.yml) |\n\n## Overview\nThis repository provides implementation of [NeuroEvolution of Augmenting Topologies (NEAT)][1] method written in Go language.\n\nThe NeuroEvolution (NE) is an artificial evolution of Neural Networks (NN) using genetic algorithms to find optimal NN \nparameters and network topology. NeuroEvolution of NN may assume a search for optimal weights of connections between NN \nnodes and search for the optimal topology of the resulting network graph. The NEAT method implemented in this work \nsearches for optimal connection weights and the network graph topology for a given task (number of NN nodes per layer \nand their interconnections).\n\n## Minimum requirements\n| Requirement | Notes            |\n|-------------|------------------|\n| Go version  | Go1.18 or higher |\n\n## Releases\n\nPlease do not depend on master as your production branch. Use [releases](https://github.com/yaricom/goNEAT/releases) instead.\n\n## Quick Start\n\nYou can evaluate the NEAT algorithm performance by running the following command:\n\n```bash\ncd $GOPATH/src/github.com/yaricom/goNEAT\ngo run executor.go -out ./out/xor -context ./data/xor.neat -genome ./data/xorstartgenes -experiment XOR\n```\n\nOr\n\n```bash\nmake run-xor\n````\n\nThe command above will run the [XOR problem solver experiment](https://github.com/yaricom/goNEAT/wiki/XOR-Experiment#the-xor-experiment-with-connected-inputs-in-the-start-genome)\nand save the collected data samples. You can use saved experimental data for analysis using standard plotting\nlibraries as in the figure below.\n\n![The XOR results plot](contents/xor_results_plot.png)\n\nThe figure was created using Matplotlib. You can find more details in the [Jupyter notebook](contents/notebooks/experiments_results.ipynb).\n\n## Documentation\n\nYou can find the algorithm performance evaluation and related documentation in the project's [wiki](https://github.com/yaricom/goNEAT/wiki)\n\nThe goNEAT library saves results of the experiments using [Numpy NPZ](https://numpy.org/doc/stable/reference/generated/numpy.savez.html)\nformat, which allows analysis of collected experimental\ndata samples using a variety of readily available Python libraries.\n\nFor your reference, we included [Jupyter notebook](contents/notebooks/experiments_results.ipynb) with an \nexample of the collected experimental data analysis, which can be used as a starter kit to analyze data \nsamples acquired from your experiments.\n\n### Installation\n\nMake sure you have at least GO 1.15.x installed onto your system and execute the following command:\n```bash\n\ngo get github.com/yaricom/goNEAT\n```\n\nFor new projects, consider using the v2 of the library with the following import:\n\n```go\nimport \"github.com/yaricom/goNEAT/v3\"\n```\n\n## Essential Packages\n\n### [`genetics`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/genetics \"API documentation\") package\n\nThe `genetics` package provides the genetic part of the NEAT algorithm describing all the machinery related to\ngenome mutations, mating, and speciation of the population of organisms.\n\nIt contains implementation of all important types related to the NEAT algorithm:\n* [`Gene`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/genetics#Gene) type in this system specifies a \"Connection Gene.\"\n* [`MIMOControlGene`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/genetics#MIMOControlGene) type is the Multiple-Input Multiple-Output (MIMO) control Gene which allows creation of modular genomes  \n* [`Genome`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/genetics#Genome) type is the primary source of genotype information used to create a phenotype.\n* [`Organism`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/genetics#Organism) type is Genotypes (Genomes) and Phenotypes (Networks) combined with fitness information, i.e. the genotype and phenotype together.\n* [`Population`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/genetics#Population) type is a group of Organisms including their Species\n* [`Species`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/genetics#Species) type  is a group of similar Organisms. Reproduction takes place mostly within a single species, so that compatible organisms can mate.\n\nAdditionally, it contains variety of utility functions to serialise/deserialize specified above types using two\nsupported data formats:\n* plain text\n* YAML\n\nThe current implementation supports sequential and parallel execution of evolution epoch which controlled by\n[related parameter](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat#EpochExecutorType) in the NEAT context options.\n\n### [`math`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/math \"API documentation\") package\n\nPackage `math` defines standard mathematical primitives used by the NEAT algorithm as well as utility functions\n\n### [`network`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/network \"API documentation\") package\n\nPackage `network` provides data structures and utilities to describe Artificial Neural Network and network solvers.\n\nThe most important types are:\n* [`NNode`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/network#NNode) type defines the node of the network and is a part of organism's genotype as well as phenotype\n* [`Link`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/network#Link) type is a connection from one node to another with an associated weight.\n* [`Network`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/network#Network) type is a collection of all nodes within an organism's phenotype, which effectively defines Neural Network topology.\n* [`Solver`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/network#Solver) type defines network solver interface, which allows propagation of the activation waves through the underlying network graph.\n\nThe current implementation supports two types of network solvers: \n* [`FastModularNetworkSolver`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/network#FastModularNetworkSolver) is the network solver implementation to be used for large neural networks simulation.\n* Standard Network Solver implemented by the `Network` type\n\nThe topology of the Neural Network represented by the `Network` fully supports the directed graph presentation as defined\nby [Gonum graph](https://pkg.go.dev/gonum.org/v1/gonum/graph) package. This feature can be used for analysis of the network\ntopology as well as encoding the graph in variety of popular graph presentation formats.\n\n### [`experiment`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/experiment \"API documentation\") package\n\nPackage `experiment` defines standard evolutionary epochs evaluators and experimental data samples collectors. It provides\nstandardised approach to define experiments using the NEAT algorithm implementation.\n\nThe most important type here is:\n* [`GenerationEvaluator`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/experiment#GenerationEvaluator) is the interface to be implemented by custom experiments\n\nYou can find examples of `GenerationEvaluator` implementations at [examples](https://github.com/yaricom/goNEAT/tree/master/examples):\n* [`pole`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/examples/pole) - single-, double-pole balancing experiments\n* [`xor`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/examples/xor) - XOR solver experiment\n\nThe following code snippet demonstrates how to run experiments using different implementations of the `GenerationEvaluator` \nand the [`experiment.Execute`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/experiment#Execute):\n\n```go\n// create experiment\nexpt := experiment.Experiment{\n    Id:       0,\n    Trials:   make(experiment.Trials, neatOptions.NumRuns),\n    RandSeed: seed,\n}\nvar generationEvaluator experiment.GenerationEvaluator\nswitch *experimentName {\ncase \"XOR\":\n    exp.MaxFitnessScore = 16.0 // as given by fitness function definition\n    generationEvaluator = xor.NewXORGenerationEvaluator(outDir)\ncase \"cart_pole\":\n    exp.MaxFitnessScore = 1.0 // as given by fitness function definition\n    generationEvaluator = pole.NewCartPoleGenerationEvaluator(outDir, true, 1500000)\ncase \"cart_pole_parallel\":\n    exp.MaxFitnessScore = 1.0 // as given by fitness function definition\n    generationEvaluator = pole.NewCartPoleParallelGenerationEvaluator(outDir, true, 1500000)\ncase \"cart_2pole_markov\":\n    exp.MaxFitnessScore = 1.0 // as given by fitness function definition\n    generationEvaluator = pole2.NewCartDoublePoleGenerationEvaluator(outDir, true, pole2.ContinuousAction)\ncase \"cart_2pole_non-markov\":\n    generationEvaluator = pole2.NewCartDoublePoleGenerationEvaluator(outDir, false, pole2.ContinuousAction)\ncase \"cart_2pole_markov_parallel\":\n    exp.MaxFitnessScore = 1.0 // as given by fitness function definition\n    generationEvaluator = pole2.NewCartDoublePoleParallelGenerationEvaluator(outDir, true, pole2.ContinuousAction)\ndefault:\n    log.Fatalf(\"Unsupported experiment: %s\", *experimentName)\n}\n\n// prepare to execute\nerrChan := make(chan error)\nctx, cancel := context.WithCancel(context.Background())\n\n// run experiment in the separate GO routine\ngo func() {\n    if err = expt.Execute(neat.NewContext(ctx, neatOptions), startGenome, generationEvaluator, nil); err != nil {\n        errChan \u003c- err\n    } else {\n        errChan \u003c- nil\n    }\n}()\n```\n\nFor more details, take a look at the experiment [executor](https://github.com/yaricom/goNEAT/blob/master/executor.go) \nimplementation provided with the goNEAT library.\n\n### [`neat`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat \"API documentation\") package\n\nPackage `neat` is an entry point to the NEAT algorithm. It defines the NEAT execution context and configuration\noptions.\n\nYou can find all available configuration options in the [`Options`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat#Options).\n\nThe configuration options can be saved either using plain text or the YAML format. We recommend using the YAML format \nfor new projects because it allows for a more flexible setup and detailed documentation of the configuration \nparameters.\n\nTake a look at the [example configuration file](data/xor_test.neat.yml) to get a better understanding.\n\nThe NEAT context options can be read as follows:\n\n```go\n// Loading YAML options\noptFile, err := os.Open(\"./data/xor_test.neat.yml\")\nif err != nil {\n\treturn err\n}\noptions, err := neat.LoadYAMLOptions(optFile)\n```\n\nOr with plain-text format:\n\n```go\n// Loading plain-text options\noptFile, err := os.Open(\"./data/xor_test.neat\")\nif err != nil {\n\treturn err\n}\noptions, err := neat.LoadNeatOptions(optFile)\n```\n\n## Phenotype Network Graph Visualization\n\nThe [`formats`](https://pkg.go.dev/github.com/yaricom/goNEAT/v3/neat/network/formats \"formats\") package provides support for various network graph serialization formats which can be used to visualize the graph with help of well-known tools. Currently, we have support for DOT and CytoscapeJS data formats.\n\n### The CytoscapeJS JSON format\n\nAnother important data format supported by the library is the `CytoscapeJS JSON`. The `Network` graph serialized into this format can be easily rendered using either [Cytoscape App](https://cytoscape.org) or the corresponding [CytoscapeJS](https://js.cytoscape.org) JavaScript library.\n\nThe following code snippet demonstrates how this can be done:\n```go\nimport (\n\"github.com/yaricom/goNEAT/v3/neat/network\"\n\"github.com/yaricom/goNEAT/v3/neat/network/formats\"\n\"bytes\"\n\"fmt\"\n)\n\nallNodes := []*network.NNode{\n\tnetwork.NewNNode(1, network.InputNeuron), \n\tnetwork.NewNNode(2, network.InputNeuron), \n\tnetwork.NewNNode(3, network.BiasNeuron), \n\tnetwork.NewNNode(4, network.HiddenNeuron), \n\tnetwork.NewNNode(5, network.HiddenNeuron), \n\tnetwork.NewNNode(6, network.HiddenNeuron), \n\tnetwork.NewNNode(7, network.OutputNeuron), \n\tnetwork.NewNNode(8, network.OutputNeuron),\n}\n\n// HIDDEN 4\nallNodes[3].connectFrom(allNodes[0], 15.0)\nallNodes[3].connectFrom(allNodes[1], 10.0)\n// HIDDEN 5\nallNodes[4].connectFrom(allNodes[1], 5.0)\nallNodes[4].connectFrom(allNodes[2], 1.0)\n// HIDDEN 6\nallNodes[5].connectFrom(allNodes[4], 17.0)\n// OUTPUT 7\nallNodes[6].connectFrom(allNodes[3], 7.0)\nallNodes[6].connectFrom(allNodes[5], 4.5)\n// OUTPUT 8\nallNodes[7].connectFrom(allNodes[5], 13.0)\n\nnet := network.NewNetwork(allNodes[0:3], allNodes[6:8], allNodes, 0)\n\nb := bytes.NewBufferString(\"\")\nerr := formats.WriteCytoscapeJSON(b, net)\nfmt.Println(b)\n```\nThe produced output looks like the following:\n```json\n{\n  \"elements\": {\n    \"nodes\": [\n      {\n        \"data\": {\n          \"activation_function\": \"SigmoidSteepenedActivation\",\n          \"activation_value\": 0,\n          \"background-color\": \"#339FDC\",\n          \"border-color\": \"#CCCCCC\",\n          \"control_node\": false,\n          \"id\": \"1\",\n          \"in_connections_count\": 0,\n          \"neuron_type\": \"INPT\",\n          \"node_type\": \"SENSOR\",\n          \"out_connections_count\": 1,\n          \"parent\": \"\",\n          \"shape\": \"diamond\"\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"activation_function\": \"SigmoidSteepenedActivation\",\n          \"activation_value\": 0,\n          \"background-color\": \"#339FDC\",\n          \"border-color\": \"#CCCCCC\",\n          \"control_node\": false,\n          \"id\": \"2\",\n          \"in_connections_count\": 0,\n          \"neuron_type\": \"INPT\",\n          \"node_type\": \"SENSOR\",\n          \"out_connections_count\": 2,\n          \"parent\": \"\",\n          \"shape\": \"diamond\"\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"activation_function\": \"SigmoidSteepenedActivation\",\n          \"activation_value\": 0,\n          \"background-color\": \"#FFCC33\",\n          \"border-color\": \"#CCCCCC\",\n          \"control_node\": false,\n          \"id\": \"3\",\n          \"in_connections_count\": 0,\n          \"neuron_type\": \"BIAS\",\n          \"node_type\": \"SENSOR\",\n          \"out_connections_count\": 1,\n          \"parent\": \"\",\n          \"shape\": \"pentagon\"\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"activation_function\": \"SigmoidSteepenedActivation\",\n          \"activation_value\": 0,\n          \"background-color\": \"#009999\",\n          \"border-color\": \"#CCCCCC\",\n          \"control_node\": false,\n          \"id\": \"4\",\n          \"in_connections_count\": 2,\n          \"neuron_type\": \"HIDN\",\n          \"node_type\": \"NEURON\",\n          \"out_connections_count\": 1,\n          \"parent\": \"\",\n          \"shape\": \"hexagon\"\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"activation_function\": \"SigmoidSteepenedActivation\",\n          \"activation_value\": 0,\n          \"background-color\": \"#009999\",\n          \"border-color\": \"#CCCCCC\",\n          \"control_node\": false,\n          \"id\": \"5\",\n          \"in_connections_count\": 2,\n          \"neuron_type\": \"HIDN\",\n          \"node_type\": \"NEURON\",\n          \"out_connections_count\": 1,\n          \"parent\": \"\",\n          \"shape\": \"hexagon\"\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"activation_function\": \"SigmoidSteepenedActivation\",\n          \"activation_value\": 0,\n          \"background-color\": \"#009999\",\n          \"border-color\": \"#CCCCCC\",\n          \"control_node\": false,\n          \"id\": \"6\",\n          \"in_connections_count\": 1,\n          \"neuron_type\": \"HIDN\",\n          \"node_type\": \"NEURON\",\n          \"out_connections_count\": 2,\n          \"parent\": \"\",\n          \"shape\": \"hexagon\"\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"activation_function\": \"SigmoidSteepenedActivation\",\n          \"activation_value\": 0,\n          \"background-color\": \"#E7298A\",\n          \"border-color\": \"#CCCCCC\",\n          \"control_node\": false,\n          \"id\": \"7\",\n          \"in_connections_count\": 2,\n          \"neuron_type\": \"OUTP\",\n          \"node_type\": \"NEURON\",\n          \"out_connections_count\": 0,\n          \"parent\": \"\",\n          \"shape\": \"round-rectangle\"\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"activation_function\": \"SigmoidSteepenedActivation\",\n          \"activation_value\": 0,\n          \"background-color\": \"#E7298A\",\n          \"border-color\": \"#CCCCCC\",\n          \"control_node\": false,\n          \"id\": \"8\",\n          \"in_connections_count\": 1,\n          \"neuron_type\": \"OUTP\",\n          \"node_type\": \"NEURON\",\n          \"out_connections_count\": 0,\n          \"parent\": \"\",\n          \"shape\": \"round-rectangle\"\n        },\n        \"selectable\": true\n      }\n    ],\n    \"edges\": [\n      {\n        \"data\": {\n          \"id\": \"1-4\",\n          \"recurrent\": false,\n          \"source\": \"1\",\n          \"target\": \"4\",\n          \"time_delayed\": false,\n          \"weight\": 15\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"id\": \"2-4\",\n          \"recurrent\": false,\n          \"source\": \"2\",\n          \"target\": \"4\",\n          \"time_delayed\": false,\n          \"weight\": 10\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"id\": \"2-5\",\n          \"recurrent\": false,\n          \"source\": \"2\",\n          \"target\": \"5\",\n          \"time_delayed\": false,\n          \"weight\": 5\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"id\": \"3-5\",\n          \"recurrent\": false,\n          \"source\": \"3\",\n          \"target\": \"5\",\n          \"time_delayed\": false,\n          \"weight\": 1\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"id\": \"5-6\",\n          \"recurrent\": false,\n          \"source\": \"5\",\n          \"target\": \"6\",\n          \"time_delayed\": false,\n          \"weight\": 17\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"id\": \"4-7\",\n          \"recurrent\": false,\n          \"source\": \"4\",\n          \"target\": \"7\",\n          \"time_delayed\": false,\n          \"weight\": 7\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"id\": \"6-7\",\n          \"recurrent\": false,\n          \"source\": \"6\",\n          \"target\": \"7\",\n          \"time_delayed\": false,\n          \"weight\": 4.5\n        },\n        \"selectable\": true\n      },\n      {\n        \"data\": {\n          \"id\": \"6-8\",\n          \"recurrent\": false,\n          \"source\": \"6\",\n          \"target\": \"8\",\n          \"time_delayed\": false,\n          \"weight\": 13\n        },\n        \"selectable\": true\n      }\n    ]\n  },\n  \"layout\": {\n    \"name\": \"circle\"\n  },\n  \"style\": [\n    {\n      \"selector\": \"node\",\n      \"style\": {\n        \"background-color\": \"data(background-color)\",\n        \"border-color\": \"data(border-color)\",\n        \"border-width\": 3,\n        \"label\": \"data(id)\",\n        \"shape\": \"data(shape)\"\n      }\n    },\n    {\n      \"selector\": \"edge\",\n      \"style\": {\n        \"curve-style\": \"bezier\",\n        \"line-color\": \"#CCCCCC\",\n        \"target-arrow-color\": \"#CCCCCC\",\n        \"target-arrow-shape\": \"triangle-backcurve\",\n        \"width\": 5\n      }\n    }\n  ]\n}\n```\n\nThe above CYJS can be visualized as following with [Cytoscape App](https://cytoscape.org).\n\n![Example Network](contents/example/example.svg)\n\nYou can find more **interesting visualizations** at project's [Wiki](https://github.com/yaricom/goNEAT/wiki/Network-Graph-Visualization).\n\n### The DOT format\nThe `Network` can be serialized into popular [GraphViz DOT](http://www.graphviz.org/doc/info/lang.html)\nformat. The following code snippet demonstrates how this can be done:\n\n```go\nimport (\n\"github.com/yaricom/goNEAT/v3/neat/network\"\n\"github.com/yaricom/goNEAT/v3/neat/network/formats\"\n\"bytes\"\n\"fmt\"\n)\n\nallNodes := []*network.NNode{\n\tnetwork.NewNNode(1, network.InputNeuron), \n\tnetwork.NewNNode(2, network.InputNeuron), \n\tnetwork.NewNNode(3, network.BiasNeuron), \n\tnetwork.NewNNode(4, network.HiddenNeuron), \n\tnetwork.NewNNode(5, network.HiddenNeuron), \n\tnetwork.NewNNode(6, network.HiddenNeuron), \n\tnetwork.NewNNode(7, network.OutputNeuron), \n\tnetwork.NewNNode(8, network.OutputNeuron),\n}\n\n// HIDDEN 4\nallNodes[3].connectFrom(allNodes[0], 15.0)\nallNodes[3].connectFrom(allNodes[1], 10.0)\n// HIDDEN 5\nallNodes[4].connectFrom(allNodes[1], 5.0)\nallNodes[4].connectFrom(allNodes[2], 1.0)\n// HIDDEN 6\nallNodes[5].connectFrom(allNodes[4], 17.0)\n// OUTPUT 7\nallNodes[6].connectFrom(allNodes[3], 7.0)\nallNodes[6].connectFrom(allNodes[5], 4.5)\n// OUTPUT 8\nallNodes[7].connectFrom(allNodes[5], 13.0)\n\nnet := network.NewNetwork(allNodes[0:3], allNodes[6:8], allNodes, 0)\nnet.Name = \"TestNN\"\n\nb := bytes.NewBufferString(\"\")\nerr := formats.WriteDOT(b, net)\nfmt.Println(b)\n```\n\nThe DOT output can be saved into the file for subsequent visualization by variety of tools listed at [GraphViz Downloads](http://www.graphviz.org/download/).\n\n## Conclusion\n\nThe experiments described in this work confirm that introduced NEAT algorithm implementation can evolve new structures in \nthe _Artificial Neural Networks_ ([XOR experiments](https://github.com/yaricom/goNEAT/wiki/XOR-Experiment)) and can solve reinforcement learning \ntasks under conditions of incomplete knowledge ([single-pole balancing](https://github.com/yaricom/goNEAT/wiki/The-single-pole-balancing-experiment) and\n[double-pole balancing](https://github.com/yaricom/goNEAT/wiki/Double-Pole-Balancing-Experiments)).\n\nWe hope that you will find great applications in your research and work projects for the provided NEAT algorithm's \nimplementation as well as utilities to run experiments while collecting relevant data samples.\n\n## Projects Using goNEAT library\n* [Learning to play Asteroids in Golang with NEAT](https://maori.geek.nz/learning-to-play-asteroids-in-golang-with-neat-f44c3472938f) - interesting article about implementation of the intelligent agent to play classic Asteroid game using the NEAT algorithm.\n* [NEAT with Novelty Search](https://github.com/yaricom/goNEAT_NS) - implementation of the Novelty Search optimization algorithm for solution search in the deceptive environments.\n* [Evolvable-Substrate HyperNEAT](https://github.com/yaricom/goESHyperNEAT) - is hypercube-based extension of the NEAT allowing to encode ANNs in the substrate with specific geometric topology and with significant number of neural units.\n\n## References\n\n* The original C++ NEAT implementation created by Kenneth Stanley, see: [NEAT][1]\n* Other NEAT implementations may be found at [NEAT Software Catalog][2]\n* Iaroslav Omelianenko, [NeuroEvolution — evolving Artificial Neural Networks topology from the scratch][4], Medium, 2018\n* Kenneth O. Stanley, [Ph.D. Dissertation: Efficient Evolution of Neural Networks through Complexification][5], Department of Computer Sciences, The University of Texas at Austin, Technical Report~AI-TR-04–39, August 2004\n* [Hands-On NeuroEvolution with Python, Build high-performing artificial neural network architectures using neuroevolution-based algorithms][6], Iaroslav Omelianenko, Birmingham: Packt Publishing, 2019\n\n## Citing\n\nIf you find our work useful, please consider citing:\n\n```text\n@software{omelianenko_iaroslav_zenodo_8178788,\n  author       = {Omelianenko, Iaroslav},\n  title        = {The GoLang implementation of NeuroEvolution of \n                   Augmented Topologies (NEAT) algorithm},\n  month        = {9},\n  year         = {2024},\n  note         = {If you use this software, please cite it as below.},\n  publisher    = {Zenodo},\n  version      = {v4.2.0},\n  doi          = {10.5281/zenodo.8178788},\n  url          = {https://doi.org/10.5281/zenodo.8178788}\n}\n```\n\nThis source code maintained and managed by [Iaroslav Omelianenko][3]\n\n\u003ca href=\"https://www.buymeacoffee.com/io42\"\u003e\u003cimg src=\"https://img.buymeacoffee.com/button-api/?text=Buy me a coffee\u0026emoji=\u0026slug=io42\u0026button_colour=be38f3\u0026font_colour=ffffff\u0026font_family=Comic\u0026outline_colour=ffffff\u0026coffee_colour=FFDD00\"\u003e\u003c/a\u003e\n\n[1]:http://www.cs.ucf.edu/~kstanley/neat.html\n[2]:http://eplex.cs.ucf.edu/neat_software/\n[3]:https://io42.space\n[4]:https://becominghuman.ai/neuroevolution-evolving-artificial-neural-networks-topology-from-the-scratch-d1ebc5540d84\n[5]:https://nn.cs.utexas.edu/downloads/papers/stanley.phd04.pdf\n[6]:https://www.packtpub.com/product/hands-on-neuroevolution-with-python/9781838824914\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyaricom%2Fgoneat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyaricom%2Fgoneat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyaricom%2Fgoneat/lists"}