Giter Site home page Giter Site logo

graphwavefunctioncollapse's Introduction

GraphWaveFunctionCollapse (GWFC)

A python 3.x package to color a graph based on patterns extracted from an colored example graph, it's based on WaveFunctionCollapse. I wrote a thesis on the algorithm (in German).

Below are some examples:

  • On the left side the example input can be seen which was converted into the input graph GI.
  • In the middle we see the graph GL which describes the structur of the patterns to be extracted.
  • On the right side is the ouput. It was generated from the ouput graph GO which was colored by GWFC using the patterns extracted from GI.

overview.png

In the /examples directoy all graphs (GI,GL and GO) can be found as GraphML files. You may also want to look at the example in the Usage section.
To display GraphML files you might want to check out Gephi, Tulip and/or Cytoscape.
The second example from the top (starcave) uses graphs to simulate WFC with N=3.

Algorithm

The general idea is similar to WFC:

  1. We extract patterns from the colored example input GI. We describe the structur of the patterns by providing the 'local similarity graph' GL; All patterns are subgraphs of GI isomorph to GL.
  2. Initially every node in GO is colored in all colors.
  3. We remove all the nodes from GO that are not in an subgraph isomorphism (with GL). We won't color them (see the top-left and the bottom-rigth hexagon of the first example from the top).
  4. Patterns can be applied to all subgraphs of GO isomorph to GL:
    1. We select an isomorphism in GO that has a low Shannon entropy bigger than 0;
      • We can select from all patterns that are applicable regarding the current coloring of the nodes.
      • The probability of an applicable pattern is the relative amount of occurrences of that pattern in GI.
      • If all nodes are colored in exactly one color we stop and output the colored GO.
    2. We apply a pattern to the selected isomorphism by having the respective nodes colored in only the respective color given by the pattern.
    3. We use constraint propagation to remove colors from nodes in GO that are not possible anymore given the current coloring. If we removed all colors from a node, it's a contradiction and we stop without output.

Usage

Install with pip install graphwfc or after downloading this repo python setup.py install.

After installing you can try out the examples by going into the respective directory (e.g. /examples/beach) and running python -m graphwfc -v value. This will generate an out.graphml file. All examples use the node attribute 'value' as color which is given by -v value. With -e edge_attr it will check for equality of the edge attribute 'edge_attr' while searching for subgraph isomorphisms. The default is 'type'.

While this package was meant to be used standalone with python -m graphwfc an API is available which can be found in the autogenerated documenation.

Remarks:

  • Instead of GL we use GLs, we allow to use more than one graph to extract and apply patterns.
  • We use GraphML files for the graphs.
  • The API accepts networkx (Di)Graphs. Don't mix Graphs and DiGraphs.
  • Since this package uses the networkx implemetation of VF2 to find subgraph isomorphisms, only those of node induced subgraphs are used.
  • Undirected Graphs are nearly untested. Since edges are only used to get subgraph isomorphisms this should be fine.

Example code

import networkx as nx
import graphwfc
GI = nx.Graph([(1,2),(2,3),(3,4)])
GI.add_nodes_from([(1,{'c':'b'}),(2,{'c':'b'}),(3,{'c':'r'}),(4,{'c':'y'})])
GL = nx.Graph([(1,2)])
GO = nx.random_tree(40)
S = graphwfc.GraphWFCState(GO=GO,GLs=[GL],GI=GI,node_attr='c')
while not S.run():
    S.reset()

GI is the graph blue -- blue -- red -- yellow ('b' -- 'b' -- 'r' -- 'y'). GL is 1 -- 2 where 1 and 2 have no color. We extract the patterns blue -- blue, blue -- red and red -- yellow.

GO will only contain the extracted patterns. As such the GO will be a tree with 40 nodes colored in a way such that no red node has a red neighbour and no yellow node has a neighbour with that is yellow or blue. The color will be stored in the node attribute 'c'.

api_basic_out.png

You can either save the output with

nx.write_graphml(S.GO, "out.graphml")

Or you can visualize it with matplotlib (pip install matplotlib)

import matplotlib.pyplot as plt
colors = list(nx.get_node_attributes(S.GO,'c').values())
nx.draw(S.GO, node_color=colors, node_size=100)
plt.show()

Fun Fact: This example is an arc consistency problem. In this case GraphWaveFunctionCollapse's constraint propagation will behave somewhat similar to the AC-3 algorithm.

graphwavefunctioncollapse's People

Contributors

lamelizard avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

graphwavefunctioncollapse's Issues

Some sort of examples would be great

Hi! Would it be possible to get some kind of guide (in English) for how to actually work with the code?

While one has to appreciate the fact it is uploaded, it is fairly impossible to figure out how to use it properly. For example, how does one make "spherical planet" sort of graph?

Thanks!

GLs example

As PR #3 stated (#3's note was about GIs), we do not have an example for GLs yet,
is there a good simple example?

We could do the "Eight queens puzzle" with rocks and kings
-> allow GWFC to insert some rocks and kings and no piece may be able to hit another piece
-> requires 3 GLs (2 for rocks, 1 for kings)
but this is boring (but music or art is probably too much code as a simple example?)

networkx 2.5 breaks

I tried to run the code in the readme:

import networkx as nx
import graphwfc
GI = nx.Graph([(1,2),(2,3),(3,4)])
GI.add_nodes_from([(1,{'c':1}),(2,{'c':1}),(3,{'c':2}),(4,{'c':3})])
GL = nx.DiGraph([(1,2)])
GO = nx.random_tree(1000)

But it raises the following networkx error: AttributeError: 'Graph' object has no attribute 'pred'

I'm using networkx==2.5

Originally posted by @asher-pembroke in #1 (comment)

Partial coloring of the GO graph

Is there a way to initialize a few nodes of the output graph? I'm trying to propagate known colors for some of the nodes, but my output graph appears to ignore them. If need be I'll post some example code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.