diff --git a/content/algorithms/graph-coloring/greedy_colouring.md b/content/algorithms/graph-coloring/greedy_colouring.md new file mode 100644 index 00000000..1890ab3f --- /dev/null +++ b/content/algorithms/graph-coloring/greedy_colouring.md @@ -0,0 +1,862 @@ +--- +jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.11.2 +kernelspec: + display_name: Python 3 + language: python + name: python3 +language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.8.5 +--- + +In this tutorial, we are going to talk about the graph coloring methods implemented in networkx. In the graph coloring problems, we assign minimum possible labels/colors that are subjected to certain conditions. + + +In networkx, there are two types of graph coloring methods (both are vertex coloring methods): + +1. Greedy Coloring: + + + - Constraints/Conditions: + 1. directly connected nodes should not have the same color + +2. Equitable Coloring: + + + - Constraints/Conditions: + 1. directly connected node should not be same color + 2. The number of nodes for each color should differ at max by 1/2 + + + +```python +### Importing the libraries +import networkx as nx +import matplotlib.pyplot as plt +import geopandas as gpd +import networkx as nx +import matplotlib.animation as animation +import numpy as np +import folium +import json +import requests +%matplotlib inline +``` + +### Greedy Colouring: + +The priority of colours/labels assigned is given by the strategies. Below is the list of strategies in networkx. +You can also add your custom strategy. + + +```python +strategies = nx.coloring.greedy_coloring.STRATEGIES +``` + + +```python +print('\n'.join( strategies.keys())) +``` + + largest_first + random_sequential + smallest_last + independent_set + connected_sequential_bfs + connected_sequential_dfs + connected_sequential + saturation_largest_first + DSATUR + custom_strategy_implementation + + + +```python +def custom_strategy_implementation(G, colors): + ''' + In this strategy we are returning the priority according to + betweeness centrality of each node. + ''' + centrality = nx.betweenness_centrality(G) + centrality = sorted(centrality, key=centrality.get) + yield from centrality +``` + + +```python +strategies['custom_strategy_implementation'] = custom_strategy_implementation +``` + + +```python +random_graph = nx.erdos_renyi_graph(9, 0.5, seed=4) +nx.draw(random_graph, with_labels=True) +``` + + + +![png](greedy_colouring_files/greedy_colouring_7_0.png) + + + + +```python +### Getting greedy Colouring for all the strategies: +colors = {current_strategy: nx.greedy_color(random_graph, strategy=current_strategy) for current_strategy in strategies} + +``` + + +```python +selected_strategy = 'DSATUR' + +pos = nx.spring_layout(random_graph, seed=32) +node_order = list(colors[selected_strategy].keys()) +node_colors = list(colors[selected_strategy].values()) + +fig,ax = plt.subplots(figsize=(10,10)) + +create_legend = plt.cm.RdYlGn +legend = create_legend(np.arange(create_legend.N)) +ax.imshow([legend], extent=[0.6, 1, 0.85, 0.9],) +nx.draw_networkx_nodes( + node_order, pos=pos, + node_color=node_colors, + node_size=500, + alpha=0.7, + cmap=plt.cm.RdYlGn, + label='Node', + ax=ax + + ) +nx.draw_networkx_labels(random_graph, pos=pos, font_size=10, font_family='sans-serif') +nx.draw_networkx_edges(random_graph, pos=pos) +#plt.axis('off') +``` + + + + + + + + + + +![png](greedy_colouring_files/greedy_colouring_9_1.png) + + + +#### Creating animation of the strategies as more nodes are added + + +```python +subgraphs = [nx.subgraph(random_graph, list(range(i))) for i in range(1, len(random_graph.nodes))] + +``` + + +```python +def update(i): + j = 0 + create_legend = plt.cm.RdYlGn + legend = create_legend(np.arange(create_legend.N)) + + for current_strategy in strategies: + ax[j].clear() + # if j == 2: + # ax[j].imshow([legend], extent=[0.6, 1, 0.85, 0.9],) + + node_colors = [colors[current_strategy].get(node) for node in subgraphs[i].nodes] + + nx.draw(subgraphs[i], pos=pos, ax=ax[j], with_labels=True, + node_color=node_colors, node_size=500, cmap=plt.cm.RdYlGn, + font_size=10, font_family='sans-serif', + alpha=0.7) + + ax[j].set_title(current_strategy) + + j += 1 + + +``` + + +```python +%matplotlib agg + + + +fig, all_axes = plt.subplots(5, 2, figsize=(20, 20)) +ax = all_axes.flat + + +ani = animation.FuncAnimation( + fig, + func = update, + frames=len(subgraphs), + ) + + +``` + + +```python +gif_file_path = r"greedy_colouring.gif" +writergif = animation.PillowWriter(fps=1) +ani.save(gif_file_path, writer=writergif) +``` + + +```python +def display_animation(gif_file_path): + from IPython.display import Image + display(Image(data=open(gif_file_path,'rb').read(), format='png')) + + +``` + + +```python +display_animation(gif_file_path) +``` + + + +![png](greedy_colouring_files/greedy_colouring_16_0.png) + + + +#### Four Color Theorom: + - Example of the use of greedy coloring + - The four color theorom states that any maps with neighbours requires only 4 or less colors + - The below uses indian map and shows the example of the four color theorom + + +```python +%matplotlib inline + + +intial_location = (21.1458, 79.0882) + +m = folium.Map(location=intial_location, zoom_start=4) + +``` + + +```python +indian_map_url = 'https://raw.githubusercontent.com/Subhash9325/GeoJson-Data-of-Indian-States/master/Indian_States' +indian_map_data = json.loads(requests.get(indian_map_url).text) +``` + + +```python +state_data = gpd.read_file(indian_map_url) +``` + + +```python +state_data.explore(m=m) +``` + + + + +
Make this Notebook Trusted to load map: File -> Trust Notebook
+ + + + +```python +def get_neighbor_links(row): + neighbors = state_data[state_data.geometry.touches(row['geometry'])].ID_1.tolist() + return neighbors + + +``` + + +```python +state_data['neighbors'] = state_data.apply(get_neighbor_links, axis=1) +``` + + +```python +#state_data['neighbors'] = state_data.apply(lambda x: get_neighbor_links(x), axis=1) +``` + + +```python +indian_states = nx.from_pandas_edgelist(state_data.explode(column='neighbors'), 'ID_1', 'neighbors') +indian_states.remove_node(np.nan) +``` + + +```python +pos = nx.spring_layout(indian_states, seed=32) +nx.draw(indian_states, with_labels=True) +``` + + + +![png](greedy_colouring_files/greedy_colouring_26_0.png) + + + + +```python +india_state_colors = {current_strategy: nx.greedy_color(indian_states, + strategy=strategies[current_strategy]) + for current_strategy in strategies} + +# +``` + + +```python +selected_strategy = 'custom_strategy_implementation' +``` + + +```python +pos = nx.spring_layout(indian_states, seed=20) + +nx.draw_networkx_nodes(list(india_state_colors[selected_strategy].keys()), pos=pos, + node_color=list(india_state_colors[selected_strategy].values()), + node_size=500, + alpha=0.7, + cmap=plt.cm.RdYlGn, + label='Node') +nx.draw_networkx_labels(indian_states, pos=pos, font_size=10, font_family='sans-serif') +patch = nx.draw_networkx_edges(indian_states, pos=pos) + +``` + + + +![png](greedy_colouring_files/greedy_colouring_29_0.png) + + + + +```python +state_data['color'] = state_data['ID_1'].map(india_state_colors[selected_strategy]) +state_data['color'].fillna(0, inplace=True) # assigning default colour to states without any neighbours +``` + + +```python +state_data.explore(m=m, + column='color', + cmap='RdYlGn', + ) +folium.LayerControl().add_to(m) # use folium to add layer control + +``` + + + + + + + + + +```python +m +``` + + + + +
Make this Notebook Trusted to load map: File -> Trust Notebook
+ + diff --git a/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_16_0.png b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_16_0.png new file mode 100644 index 00000000..51072044 Binary files /dev/null and b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_16_0.png differ diff --git a/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_26_0.png b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_26_0.png new file mode 100644 index 00000000..61e78ea2 Binary files /dev/null and b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_26_0.png differ diff --git a/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_29_0.png b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_29_0.png new file mode 100644 index 00000000..1453b521 Binary files /dev/null and b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_29_0.png differ diff --git a/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_7_0.png b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_7_0.png new file mode 100644 index 00000000..fc66f1a2 Binary files /dev/null and b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_7_0.png differ diff --git a/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_9_1.png b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_9_1.png new file mode 100644 index 00000000..d2388371 Binary files /dev/null and b/content/algorithms/graph-coloring/greedy_colouring_files/greedy_colouring_9_1.png differ diff --git a/content/algorithms/index.md b/content/algorithms/index.md index 4c990ef4..4dd7d9e3 100644 --- a/content/algorithms/index.md +++ b/content/algorithms/index.md @@ -10,4 +10,5 @@ maxdepth: 1 assortativity/correlation dag/index flow/dinitz_alg +graph-coloring/greedy_colouring ```