diff options
author | jarrodmillman <jarrod.millman@gmail.com> | 2022-12-14 17:21:13 +0000 |
---|---|---|
committer | jarrodmillman <jarrod.millman@gmail.com> | 2022-12-14 17:21:13 +0000 |
commit | 832c558e3507e5cb667a622b5372f91384ab026f (patch) | |
tree | 74481f14ab9cfb5c6984ab59b378cdc857a8180d /_downloads/d4ff05da55438abd8747b5d94df09ea1/plot_beam_search.ipynb | |
parent | 71985f91c82bf85657dce6a74669e93ec8d29e11 (diff) | |
download | networkx-832c558e3507e5cb667a622b5372f91384ab026f.tar.gz |
Deploying to gh-pages from @ networkx/networkx@6be702047b1bb596a8010cf80911bb6ea939b1d1 🚀
Diffstat (limited to '_downloads/d4ff05da55438abd8747b5d94df09ea1/plot_beam_search.ipynb')
-rw-r--r-- | _downloads/d4ff05da55438abd8747b5d94df09ea1/plot_beam_search.ipynb | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/_downloads/d4ff05da55438abd8747b5d94df09ea1/plot_beam_search.ipynb b/_downloads/d4ff05da55438abd8747b5d94df09ea1/plot_beam_search.ipynb new file mode 100644 index 00000000..c1612ba3 --- /dev/null +++ b/_downloads/d4ff05da55438abd8747b5d94df09ea1/plot_beam_search.ipynb @@ -0,0 +1,72 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Beam Search\n\nBeam search with dynamic beam width.\n\nThe progressive widening beam search repeatedly executes a beam search\nwith increasing beam width until the target node is found.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import math\n\nimport matplotlib.pyplot as plt\nimport networkx as nx\n\n\ndef progressive_widening_search(G, source, value, condition, initial_width=1):\n \"\"\"Progressive widening beam search to find a node.\n\n The progressive widening beam search involves a repeated beam\n search, starting with a small beam width then extending to\n progressively larger beam widths if the target node is not\n found. This implementation simply returns the first node found that\n matches the termination condition.\n\n `G` is a NetworkX graph.\n\n `source` is a node in the graph. The search for the node of interest\n begins here and extends only to those nodes in the (weakly)\n connected component of this node.\n\n `value` is a function that returns a real number indicating how good\n a potential neighbor node is when deciding which neighbor nodes to\n enqueue in the breadth-first search. Only the best nodes within the\n current beam width will be enqueued at each step.\n\n `condition` is the termination condition for the search. This is a\n function that takes a node as input and return a Boolean indicating\n whether the node is the target. If no node matches the termination\n condition, this function raises :exc:`NodeNotFound`.\n\n `initial_width` is the starting beam width for the beam search (the\n default is one). If no node matching the `condition` is found with\n this beam width, the beam search is restarted from the `source` node\n with a beam width that is twice as large (so the beam width\n increases exponentially). The search terminates after the beam width\n exceeds the number of nodes in the graph.\n\n \"\"\"\n # Check for the special case in which the source node satisfies the\n # termination condition.\n if condition(source):\n return source\n # The largest possible value of `i` in this range yields a width at\n # least the number of nodes in the graph, so the final invocation of\n # `bfs_beam_edges` is equivalent to a plain old breadth-first\n # search. Therefore, all nodes will eventually be visited.\n log_m = math.ceil(math.log2(len(G)))\n for i in range(log_m):\n width = initial_width * pow(2, i)\n # Since we are always starting from the same source node, this\n # search may visit the same nodes many times (depending on the\n # implementation of the `value` function).\n for u, v in nx.bfs_beam_edges(G, source, value, width):\n if condition(v):\n return v\n # At this point, since all nodes have been visited, we know that\n # none of the nodes satisfied the termination condition.\n raise nx.NodeNotFound(\"no node satisfied the termination condition\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Search for a node with high centrality.\n\nWe generate a random graph, compute the centrality of each node, then perform\nthe progressive widening search in order to find a node of high centrality.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Set a seed for random number generation so the example is reproducible\nseed = 89\n\nG = nx.gnp_random_graph(100, 0.5, seed=seed)\ncentrality = nx.eigenvector_centrality(G)\navg_centrality = sum(centrality.values()) / len(G)\n\n\ndef has_high_centrality(v):\n return centrality[v] >= avg_centrality\n\n\nsource = 0\nvalue = centrality.get\ncondition = has_high_centrality\n\nfound_node = progressive_widening_search(G, source, value, condition)\nc = centrality[found_node]\nprint(f\"found node {found_node} with centrality {c}\")\n\n\n# Draw graph\npos = nx.spring_layout(G, seed=seed)\noptions = {\n \"node_color\": \"blue\",\n \"node_size\": 20,\n \"edge_color\": \"grey\",\n \"linewidths\": 0,\n \"width\": 0.1,\n}\nnx.draw(G, pos, **options)\n# Draw node with high centrality as large and red\nnx.draw_networkx_nodes(G, pos, nodelist=[found_node], node_size=100, node_color=\"r\")\nplt.show()" + ] + } + ], + "metadata": { + "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.9.15" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}
\ No newline at end of file |