{"id":34090175,"url":"https://github.com/tmetsch/graph_stitcher","last_synced_at":"2026-04-08T15:31:02.366Z","repository":{"id":57435881,"uuid":"48659707","full_name":"tmetsch/graph_stitcher","owner":"tmetsch","description":"Graph algorithms to merge two graphs based on stitching.","archived":false,"fork":false,"pushed_at":"2019-10-18T10:29:38.000Z","size":465,"stargazers_count":12,"open_issues_count":0,"forks_count":3,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-16T17:18:45.735Z","etag":null,"topics":["bidding","combinatorial-optimization","evolutionary-algorithm","graph","graph-embedding","iterative-repair","particle-swarm-optimization","self-optimization"],"latest_commit_sha":null,"homepage":"http://tmetsch.github.io/graph_stitcher/","language":"Python","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/tmetsch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-27T20:39:52.000Z","updated_at":"2022-10-18T19:50:20.000Z","dependencies_parsed_at":"2022-09-01T18:42:31.317Z","dependency_job_id":null,"html_url":"https://github.com/tmetsch/graph_stitcher","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tmetsch/graph_stitcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmetsch%2Fgraph_stitcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmetsch%2Fgraph_stitcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmetsch%2Fgraph_stitcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmetsch%2Fgraph_stitcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tmetsch","download_url":"https://codeload.github.com/tmetsch/graph_stitcher/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmetsch%2Fgraph_stitcher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31562684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["bidding","combinatorial-optimization","evolutionary-algorithm","graph","graph-embedding","iterative-repair","particle-swarm-optimization","self-optimization"],"created_at":"2025-12-14T14:12:52.865Z","updated_at":"2026-04-08T15:31:02.358Z","avatar_url":"https://github.com/tmetsch.png","language":"Python","readme":"# Graph stitching\n\nThis tool is a little framework to determine possible merges between two graphs\nbased on a set of required additional relationships (aka stitches / edges).\nBased on a set of possible resulting candidate graphs we validate which of the\ncandidates graphs is the \"best\".\n\nAn example use case is a packaging problem: e.g. set of entities need to be\nplaced in an container which already contains a set of different entities.\n\nLet's assume the entities to be placed can be described using a *request* graph\n(as in entities having a relationship) and the existing *container* can be\ndescribed as a graph as well (entities having relationships and are already\nranked). Nodes \u0026 edges in the existing container should be ranked to indicate\nhow loaded/busy they are.\n\nAdding a new set of entities (e.g. a lamp described by the lamp bulb \u0026 fitting)\nto the existing container (e.g. a house) automatically requires certain\nrelationships to be added (e.g. the power cable which is plugged into the\nsocket). But not all possible relationship setups might be good as e.g. adding\nanother consumer (the lamp) to a certain power socket might impact other\nconsumers (the microwave) of the same socket as the fuse might give up. How\nloaded the power socket is can be expressed through the previously mentioned\nrank.\n\nHence **stitching** two graphs together is done by adding relationships (edges)\nbetween certain types of nodes from the *container* and the *request*. As\nmultiple stitches are possible we need to know determine and validate (adhering\nconditions like compositions and attribute requirements) the possible\ncandidates and determine the best. Defining the best one can be done using a\nvery simple principle. A good stitch is defined by:\n\n* all new relationships are satisfied\n* the resulting graph is stable and none of the existing nodes (entities) are\nimpacted by the requested once.\n\nThrough the pluggable architecture of this tool we can now implement\ndifferent algorithms on how to determine if a resulting graph is good\n\u0026 stable:\n\n* through a simple rule saying for a node of type A, the maximum number of\n  incoming dependencies is Y\n* through a simple rule saying for a node of type B, that it cannot take more\n  incoming relationships when it's rank is over an threshold K.\n* (many more .e.g implement your own)\n\nThis tool obviously can also be used to enhance the placement of workload after\na temporal scheduling decision has been made (based on round-robin, preemptive,\npriority, fair share, fifo, ... algorithms) within clusters.\n\n## graph stitcher's internals\n\nAs mentioned above graph stitcher is pluggable, to test different algorithms of\n**graph stitching** \u0026 validation of the same. Hence it has a pluggable\ninterface for the *stitch()* and *validate()* routine (see *BaseStitcher*\nclass).\n\nTo stitch two graphs the tool needs to know which relationships are needed:\n\n    Type of source node | Type of target node\n    -----------------------------------------\n    type_a              | type_x\n    ...                 | ...\n\nThese are stored in the file (stitch.json). Sample graphs \u0026 tests can be found\nin the **tests** directory as well.\n\nThere is a *conditional_filter()* function implemented which can do some basic\nfiltering. Implementing your own is possible by passing conditions and the\n*conditional_filter()* routine you want to use as parameters to the *stich()*\ncall.\n\nThe basic filter support the following operations:\n\n  * based on required (exception: not equal operation) target attributes -\n    example below: node a requires it's stitched target to have an attribute\n    'foo' with value 'y'\n    * this can also be done with: not equal, larger than, less than or by a\n      regular expression.\n  * the notion that two nodes require the same or different target - example\n    below: node 1 \u0026 2 need to have the same stitched target node and node 3 \u0026 4\n    need to have different stitched target nodes.\n  * the notion that stitched target nodes (not) share a common attribute - \n    example below: node x \u0026 y need to be stitched to target nodes which share \n    the same attribute value for the attribute with the name 'group'.\n\nThe following dictionary can be passed in as a composition condition:\n\n    {\n     'attributes': [('eq', ('a', ('foo', 'y'))),\n                    ('neq', ('a', ('foo', 5))),\n                    ('lt', ('a', ('foo', 4))),\n                    ('lg', ('a', ('foo', 7))),\n                    ('regex', ('a', ('foo', '^a')))],\n     'compositions': [('same', ('1', '2')),\n                      ('diff', ('3', '4')),\n                      ('share', ('group', ['x', 'y'])),\n                      ('nshare', ('group', ['a', 'b']))]\n    }\n\nThis graph stitcher is mostly developed to test \u0026 play around. Also to check if\n[evolutionary algorithms](https://en.wikipedia.org/wiki/Evolutionary_algorithm)\ncan be developed to determine the best resulting graph. More details on the \nalgorithms in place can be found in the [/docs](/docs/algorithms.md) directory.\n\n## Running it\n\nJust do a:\n\n    $ ./run_me.py\n\nYou will hopefully see something similar to the following diagram. The *k*,\n*l*, *m* nodes form the request. All other nodes represent the container (node\ncolors indicate the rank, node forms the different types). The stitches are\ndotted lines. Each graph is a candidate solution, the results of the\nvalidation are shown as titles of the graphs.\n\n![output](./figure_1.png?raw=true \"Output\")\n\nTo test the evolutionary algorithm run:\n\n    $ ./run_me.py -a evolutionary\n\nPlease note that it might not always find a set of good solutions, as the \ncontainer and the request are pretty small. Also note that currently the \nfitness function expresses a fitness for the given conditions; and does not \ninclude a fitness value for the validation phase.\n\nTo test the bidding algorithm in which the container nodes try to find the \noptimal solution run:\n\n    $ ./run_me.py -a bidding\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftmetsch%2Fgraph_stitcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftmetsch%2Fgraph_stitcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftmetsch%2Fgraph_stitcher/lists"}