{ "info": { "author": "Max Strange", "author_email": "maxfieldstrange@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development :: Libraries", "Topic :: Utilities" ], "description": "\n# primordial-ooze\n\nDirt simple genetic algorithm library for Python\n\nDocs are below.\n\n## Simulation\n\nA GA simulation. The general workflow for this is:\n\n```python\nimport primordialooze as po\nimport pandas\nimport matplotlib.pyplot\n\nsim = po.Simulation(nagents, shape, fitnessfunction)\nbestagent, fitness = sim.run()\nprint(\"The agent {} has the best fitness, which is: {}\".format(bestagent, fitness))\n\n# Dump and plot\nfname = \"stats.csv\"\nsim.dump_history_csv(fname)\n\ndf = pandas.read_csv(fname)\ndf = df.drop(['GenerationIndex'], axis=1)\ndf.plot()\nplt.show()\n```\n\n## Statistics\n\nThe Simulation class stores a list `statistics`, which contains instances of the class `Statistics`.\nThe `Statistics` class contains the following properties:\n\n- `generationidx`, which is the zero-based index indicating which generation this `Statistics` instance is for.\n- `maxval`, which is the maximum fitness score for this generation.\n- `minval`, which is the minimum fitness score for this generation.\n- `avgval`, which is the average fitness score for this generation.\n\nThe Simulation class also stores a list `best_agents`, which contains the best agent at each generation.\n\n\n### __init__\n\n```python\ndef __init__(self, population, shape, fitnessfunc, *, seedfunc=None, selectionfunc=None,\n crossoverfunc=None, mutationfunc=None, elitismfunc=None, nworkers=0,\n max_agents_per_generation=None, min_agents_per_generation=None)\n```\n\n#### Args\n\nThe following list contains the arguments that are needed. These do not have default values\nsince the values for these will change dramatically depending on the problem.\n\n- **population**: The number of agents in the first generation. We will generate this many agents\n in the initial generation, each of which is a Numpy Array of shape=`shape`.\n They will be mutated according to `mutationfunc`, and evaluated each generation\n by `fitnessfunc`.\n- **shape**: The shape of each agent in the population. Must be a list-like. The shape of the agents\n must be a 1D array of whatever length like `(7,)`.\n- **fitnessfunc**: The function to use to evaluate the fitness of each agent in the generation.\n Must have signature: `fitnessfunc(agent) -> scalar float`. This function\n will be evaluated on every single agent in the gene pool at each generation.\n If this function is slow, it probably makes sense to use multiprocessing, unless the\n gene pool is quite small. See `nworkers`.\n\n#### Keyword Args\n\nThese arguments contain (mostly) sensible defaults, but you should definitely make sure these\ndefaults work for you. You will almost certainly want to change some of these to fit your problem.\n\n- **seedfunc**: The function to use to create the first generation of agents. The function must have\n the signature `seedfunc() -> agent of shape 'shape'`. We call this function\n `population` times. When `None`, defaults to uniform random\n over the range [-1.0, 1.0) in each dimension.\n- **selectionfunc**: The function to use to select the agents that are allowed to breed to create the\n next generation. Signature must be `selectionfunc(population, evaluations) -> selected_agents`,\n where `population` is an n-dimensional array of shape (nagents, agent_length),\n `evaluations` is an array of shape (nagents,); `evaluations[i]` contains\n the fitness value for `population[i, :]`; `selected_agents` is an n-dimensional array\n of shape (nagents_selected, agent_length), which must contain the selected agents.\n `population` and `evaluations` are pre-sorted so that `population[0, :]`, corresponds\n to `evalutaion[0]` and has the highest evaluation value. Agents which are not selected\n are simply discarded, i.e., they will not appear in the next generation (unless randomly\n created again as part of crossover/mutation).\n If `None`, defaults to selecting the top ten percent.\n- **crossoverfunc**: Crossover function to use. Must have signature `crossoverfunc(agents) -> new_agents`,\n where `agents` is an n-dimensional array of shape (nselected_agents, agent_length),\n and where `new_agents` must be an n-dimensional array of shape (nagents, agent_length).\n This function is applied after the selection function is used to determine which\n agents will enter the new generation and this function is used exclusively on those\n selected agents. Typically, `new_agents` will constitute the entirety of the new generation,\n with one exception being if elitism is used (see below) and another exception being\n if the mutation function adds new individuals to the gene pool, rather than just mutating\n existing ones.\n If `None`, defaults to 2-point crossover used on randomly selected pairs from the\n breeding agents until `population` agents (or, if `elitismfunc` is None, `0.9 * population`).\n- **mutationfunc**: The function to use to apply mutations to the gene pool. The signature must be\n `mutationfunc(agents) -> new_agents`, where `agents` is the value returned from\n `crossoverfunc` and `new_agents` must be an n-dimensional array of shape (nagents, agent_length).\n This function is applied to the result of `crossoverfunc`.\n When `None`, defaults to setting each value in 0.05 of the agents to a random value,\n where the random value is drawn from a Gaussian distribution of mean = the value being replaced\n and stdev = 0.25.\n- **elitismfunc**: A function of signature `elitismfunc(generation_index) -> float in range [0.0, 1.0]`.\n This function takes the index of the generation (0 for the first generation, 1 for the second, etc.)\n and returns the fraction of top-performers to hold over as-is to the next generation.\n The elites are duplicated and then, after the new\n generation is created via the selectionfunc -> crossoverfunc -> mutationfunc pipeline, they are\n reintroduced into the gene pool. This means that if the above pipeline generates 100 agents\n and the elitism is set to take 10, the new generation will be composed of 110 agents. If this\n is confusing, see `max_agents_per_generation` and `min_agents_per_generation`.\n When `None`, defaults to a function that simply returns 0.1 (or 10%) of the gene pool regardless of the\n generation.\n- **nworkers**: The number of processes to use to parallelize the fitness function. This will default to 0, which will\n mean no parallelism at all. `None` will use the number of cores. Otherwise, should be a positive integer.\n- **max_agents_per_generation**: The maximum agents to allow into a generation. If the selection, crossover, mutation,\n and elitism functions are not handled properly, it is possible for the number of\n agents to change per generation. While this may be desired in some circumstances, it\n is often not. If this value is negative, we will allow the generations to grow to arbitrary\n size. If it is nonzero, after selection, crossover, mutation, and elitism, we will\n take all of the candidates as long as they do not number more than this value. If they do,\n we take this many at random.\n This value defaults to `None`, which means we use `population` as the max.\n- **min_agents_per_generation**: The minimum agents to allow making a new generation. If the selection, crossover, mutation,\n and elitism functions are not handled properly, it is possible for the number of\n agents to change per generation. While this may be desired in some circumstances, it\n is often not. If this value is negative or zero, we will allow the generations\n to shrink to zero, after which the simulation will stop. If it is nonzero, after selection,\n crossover, mutation, and elitism, we will cycle through the candidate agents in random\n order, duplicating them until this value is met. Note that we attempt to spread out the\n duplication evenly amongst all candidates.\n This value defaults to `None`, which means we use `population` as the min.\n\n\n### run\n\n```python\n def run(self, niterations=100, fitness=None)\n```\n\nRuns the constructed simulation.\n\nEither runs until `niterations` have passed, or runs until the best fitness is `fitness` or greater.\nReturns the best agent along with its fitness.\n\n#### Keyword Args\n\n- **niterations**: The number of iterations to run the simulation to. Defaults to 100. If `None`,\n `fitness` will be used (and must not be None). If both this and `fitness` is\n specified, we will stop as soon as one or the other condition is met.\n- **fitness**: The fitness level to converge on. As soon as one or more agents have this fitness level\n or higher, the simulation will stop. Defaults to `None`. If `None` (the default),\n `niterations` will be used (and must not be None). If this and `niterations` is\n specified, we will stop as soon as one or the other condition is met.\n- **printprogress**: If `True` (the default), we will print a progress indication after each generation.\n\n#### Returns\n\n- The agent with the highest fitness score after the simulation ends.\n- The fitness of this agent.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/MaxStrange/primordial-ooze", "keywords": "machine learning genetic algorithm", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "primordialooze", "package_url": "https://pypi.org/project/primordialooze/", "platform": "", "project_url": "https://pypi.org/project/primordialooze/", "project_urls": { "Homepage": "https://github.com/MaxStrange/primordial-ooze" }, "release_url": "https://pypi.org/project/primordialooze/0.4.0/", "requires_dist": [ "numpy" ], "requires_python": "~=3.5", "summary": "Super simple genetic algorithm library for Python.", "version": "0.4.0" }, "last_serial": 4919492, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "9a821f8e335e360b3d60aabb418fb52f", "sha256": "c7175a6c9e7458db370de5b5a3875a69c82933eeb30844bef926878a0fa1cb2e" }, "downloads": -1, "filename": "primordialooze-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "9a821f8e335e360b3d60aabb418fb52f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 11629, "upload_time": "2019-02-24T04:30:35", "url": "https://files.pythonhosted.org/packages/10/a1/0be4085aed27af7215710e067a14a0da07313303e135bd3403fee5ad18ed/primordialooze-0.1.0-py3-none-any.whl" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "d8a79229ac1afbe89a32de2cad8526b1", "sha256": "906c8d6e7b1d7ecb7980fbd52f144bae7e1e87cd6aa4bf2691b1f23aaf3beb5b" }, "downloads": -1, "filename": "primordialooze-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "d8a79229ac1afbe89a32de2cad8526b1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 11656, "upload_time": "2019-02-24T04:37:23", "url": "https://files.pythonhosted.org/packages/95/68/59c962ffb3dd0344f373eb92baf70b9dc1a6e1ffe2dea145af3b043bdd5b/primordialooze-0.1.1-py3-none-any.whl" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "61f5a5da2b30b3ca17e0b26de958a5ce", "sha256": "7a75d59270d2b68cef79404fef9e86389588a17fe04684307a4bedb73c99db12" }, "downloads": -1, "filename": "primordialooze-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "61f5a5da2b30b3ca17e0b26de958a5ce", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 11980, "upload_time": "2019-02-25T05:01:02", "url": "https://files.pythonhosted.org/packages/55/e3/bec89be2acba9d5662aecd2bd963b11e8365025fad6ca382706bb164226e/primordialooze-0.2.0-py3-none-any.whl" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "0d03a665495e57e2c674316b5a8dfbe5", "sha256": "e97b9d800f527e2c74b5e7eb83cca151638490ed5ca8b39ef10a0797655b0b97" }, "downloads": -1, "filename": "primordialooze-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "0d03a665495e57e2c674316b5a8dfbe5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 12583, "upload_time": "2019-02-25T06:08:02", "url": "https://files.pythonhosted.org/packages/34/99/34a424f1d72a8de7b830c3cd60b94c5e2cad230fabb3bfa88c4bd81c549b/primordialooze-0.3.0-py3-none-any.whl" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "28170490fccdb1613a7ef661703e3904", "sha256": "d5305d7b98595a067f0928905ef27fb10c5b3c7058b857a79189b75536588f79" }, "downloads": -1, "filename": "primordialooze-0.4.0-py3-none-any.whl", "has_sig": false, "md5_digest": "28170490fccdb1613a7ef661703e3904", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 12784, "upload_time": "2019-03-09T20:08:22", "url": "https://files.pythonhosted.org/packages/b4/30/82fe7e60f888ad26cf7178e58706b35e11b4bf62889bf1fd5352728af6d3/primordialooze-0.4.0-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "28170490fccdb1613a7ef661703e3904", "sha256": "d5305d7b98595a067f0928905ef27fb10c5b3c7058b857a79189b75536588f79" }, "downloads": -1, "filename": "primordialooze-0.4.0-py3-none-any.whl", "has_sig": false, "md5_digest": "28170490fccdb1613a7ef661703e3904", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 12784, "upload_time": "2019-03-09T20:08:22", "url": "https://files.pythonhosted.org/packages/b4/30/82fe7e60f888ad26cf7178e58706b35e11b4bf62889bf1fd5352728af6d3/primordialooze-0.4.0-py3-none-any.whl" } ] }