diff --git a/cadCAD/engine/simulation.py b/cadCAD/engine/simulation.py index c80b8da..77c3bf5 100644 --- a/cadCAD/engine/simulation.py +++ b/cadCAD/engine/simulation.py @@ -103,8 +103,20 @@ class Executor: run: int ) -> List[Dict[str, Any]]: - # last_in_obj: Dict[str, Any] = deepcopy(sL[-1]) - last_in_obj: Dict[str, Any] = sL[-1] + # def dp_psu(d): + # for k, v in deepcopy(d).items(): + # yield k, deepcopy(v) + # + # def dp_psub(l): + # for d in l: + # yield dict(dp_psu(d)) + + # last_in_obj: Dict[str, Any] = dict(dp_psu(sL[-1])) + + last_in_obj: Dict[str, Any] = deepcopy(sL[-1]) + # print(last_in_obj) + # last_in_obj: Dict[str, Any] = sL[-1] + # last_in_obj: Dict[str, Any] = sH[-1] # print(last_in_obj) # print(sH[-1]) @@ -155,6 +167,16 @@ class Executor: # ToDo: flatten first # states_list_copy: List[Dict[str, Any]] = simulation_list[-1] states_list_copy: List[Dict[str, Any]] = deepcopy(simulation_list[-1]) + + # def dp_psu(d): + # for k, v in deepcopy(d).items(): + # yield k, deepcopy(v) + # + # def dp_psub(l): + # for d in l: + # yield dict(dp_psu(d)) + + # states_list_copy: List[Dict[str, Any]] = list(dp_psub(simulation_list[-1])) # print(states_list_copy) # ToDo: Causes Substep repeats in sL: diff --git a/dist/cadCAD-0.2-py3-none-any.whl b/dist/cadCAD-0.2-py3-none-any.whl index eb56bb3..ccb0606 100644 Binary files a/dist/cadCAD-0.2-py3-none-any.whl and b/dist/cadCAD-0.2-py3-none-any.whl differ diff --git a/simulations/regression_tests/udo.py b/simulations/regression_tests/udo.py index 65b6b41..f974b3e 100644 --- a/simulations/regression_tests/udo.py +++ b/simulations/regression_tests/udo.py @@ -166,7 +166,8 @@ states = list(state_updates.keys()) # states_noTS = filter_out(['timestamp'], states) # states_grid = [states,states_noTS,states_noTS] -states_grid = [states] * system_substeps #[states,states,states] +# states_grid = [states] * system_substeps # +states_grid = [states,states,states] policy_grid = [['a', 'b'], ['a', 'b'], ['a', 'b']] diff --git a/simulations/validation/marbles.py b/simulations/validation/marbles.py new file mode 100644 index 0000000..8a0f2c3 --- /dev/null +++ b/simulations/validation/marbles.py @@ -0,0 +1,166 @@ +from cadCAD.engine import ExecutionMode, ExecutionContext, Executor +from cadCAD.configuration import Configuration +from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO +import networkx as nx +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd + +import pprint as pp + +T = 50 #iterations in our simulation +n = 3 #number of boxes in our network +m = 2 #for barabasi graph type number of edges is (n-2)*m + +G = nx.barabasi_albert_graph(n, m) +k = len(G.edges) + + +# class udoExample(object): +# def __init__(self, G): +# self.G = G +# self.mem_id = str(hex(id(self))) + + +g = UDO(udo=G) +print() +# print(g.edges) +# print(G.edges) +# pp.pprint(f"{type(g)}: {g}") +# next +balls = np.zeros(n,) + +for node in g.nodes: + rv = np.random.randint(1,25) + g.nodes[node]['initial_balls'] = rv + balls[node] = rv + +# pp.pprint(balls) + +# next +scale=100 +nx.draw_kamada_kawai(G, node_size=balls*scale,labels=nx.get_node_attributes(G,'initial_balls')) + +# next + +initial_conditions = {'balls':balls, 'network':G} +print(initial_conditions) + +# next + +def update_balls(params, step, sL, s, _input): + delta_balls = _input['delta'] + new_balls = s['balls'] + for e in G.edges: + move_ball = delta_balls[e] + src = e[0] + dst = e[1] + if (new_balls[src] >= move_ball) and (new_balls[dst] >= -move_ball): + new_balls[src] = new_balls[src] - move_ball + new_balls[dst] = new_balls[dst] + move_ball + + key = 'balls' + value = new_balls + + return (key, value) + + +def update_network(params, step, sL, s, _input): + new_nodes = _input['nodes'] + new_edges = _input['edges'] + new_balls = _input['quantity'] + + graph = s['network'] + + for node in new_nodes: + graph.add_node(node) + graph.nodes[node]['initial_balls'] = new_balls[node] + graph.nodes[node]['strat'] = _input['node_strats'][node] + + for edge in new_edges: + graph.add_edge(edge[0], edge[1]) + graph.edges[edge]['strat'] = _input['edge_strats'][edge] + + key = 'network' + value = graph + return (key, value) + + +def update_network_balls(params, step, sL, s, _input): + new_nodes = _input['nodes'] + new_balls = _input['quantity'] + balls = np.zeros(len(s['balls']) + len(new_nodes)) + + for node in s['network'].nodes: + balls[node] = s['balls'][node] + + for node in new_nodes: + balls[node] = new_balls[node] + + key = 'balls' + value = balls + + return (key, value) + +# next + + +def greedy_robot(src_balls, dst_balls): + # robot wishes to accumlate balls at its source + # takes half of its neighbors balls + if src_balls < dst_balls: + delta = -np.floor(dst_balls / 2) + else: + delta = 0 + + return delta + + +def fair_robot(src_balls, dst_balls): + # robot follows the simple balancing rule + delta = np.sign(src_balls - dst_balls) + + return delta + + +def giving_robot(src_balls, dst_balls): + # robot wishes to gice away balls one at a time + if src_balls > 0: + delta = 1 + else: + delta = 0 + + return delta + +# next + +robot_strategies = [greedy_robot,fair_robot, giving_robot] + +for node in G.nodes: + nstrats = len(robot_strategies) + rv = np.random.randint(0,nstrats) + G.nodes[node]['strat'] = robot_strategies[rv] + +for e in G.edges: + owner_node = e[0] + G.edges[e]['strat'] = G.nodes[owner_node]['strat'] + +# next + +def robotic_network(params, step, sL, s): + graph = s['network'] + + delta_balls = {} + for e in graph.edges: + src = e[0] + src_balls = s['balls'][src] + dst = e[1] + dst_balls = s['balls'][dst] + + # transfer balls according to specific robot strat + strat = graph.edges[e]['strat'] + delta_balls[e] = strat(src_balls, dst_balls) + + return_dict = {'nodes': [], 'edges': {}, 'quantity': {}, 'node_strats': {}, 'edge_strats': {}, 'delta': delta_balls} + + return (return_dict) \ No newline at end of file diff --git a/simulations/validation/marbles2.py b/simulations/validation/marbles2.py new file mode 100644 index 0000000..91c3f93 --- /dev/null +++ b/simulations/validation/marbles2.py @@ -0,0 +1,205 @@ +from cadCAD.configuration import append_configs +import networkx as nx +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd + +T = 50 #iterations in our simulation +n = 3 #number of boxes in our network +m = 2 #for barabasi graph type number of edges is (n-2)*m + +G = nx.barabasi_albert_graph(n, m) +k = len(G.edges) + +balls = np.zeros(n,) + +for node in G.nodes: + rv = np.random.randint(1,25) + G.nodes[node]['initial_balls'] = rv + balls[node] = rv + +scale=100 +nx.draw_kamada_kawai(G, node_size=balls*scale,labels=nx.get_node_attributes(G,'initial_balls')) + +initial_conditions = {'balls': balls, 'network': G} + + +def update_balls(params, step, sL, s, _input): + delta_balls = _input['delta'] + new_balls = s['balls'] + for e in G.edges: + move_ball = delta_balls[e] + src = e[0] + dst = e[1] + if (new_balls[src] >= move_ball) and (new_balls[dst] >= -move_ball): + new_balls[src] = new_balls[src] - move_ball + new_balls[dst] = new_balls[dst] + move_ball + + key = 'balls' + value = new_balls + + return (key, value) + + +def update_network(params, step, sL, s, _input): + new_nodes = _input['nodes'] + new_edges = _input['edges'] + new_balls = _input['quantity'] + + graph = s['network'] + + for node in new_nodes: + graph.add_node(node) + graph.nodes[node]['initial_balls'] = new_balls[node] + graph.nodes[node]['strat'] = _input['node_strats'][node] + + for edge in new_edges: + graph.add_edge(edge[0], edge[1]) + graph.edges[edge]['strat'] = _input['edge_strats'][edge] + + key = 'network' + value = graph + return (key, value) + + +def update_network_balls(params, step, sL, s, _input): + new_nodes = _input['nodes'] + new_balls = _input['quantity'] + balls = np.zeros(len(s['balls']) + len(new_nodes)) + + for node in s['network'].nodes: + balls[node] = s['balls'][node] + + for node in new_nodes: + balls[node] = new_balls[node] + + key = 'balls' + value = balls + + return (key, value) + + +def greedy_robot(src_balls, dst_balls): + # robot wishes to accumlate balls at its source + # takes half of its neighbors balls + if src_balls < dst_balls: + delta = -np.floor(dst_balls / 2) + else: + delta = 0 + + return delta + + +def fair_robot(src_balls, dst_balls): + # robot follows the simple balancing rule + delta = np.sign(src_balls - dst_balls) + + return delta + + +def giving_robot(src_balls, dst_balls): + # robot wishes to gice away balls one at a time + if src_balls > 0: + delta = 1 + else: + delta = 0 + + return delta + +robot_strategies = [greedy_robot,fair_robot, giving_robot] + +for node in G.nodes: + nstrats = len(robot_strategies) + rv = np.random.randint(0,nstrats) + G.nodes[node]['strat'] = robot_strategies[rv] + +for e in G.edges: + owner_node = e[0] + G.edges[e]['strat'] = G.nodes[owner_node]['strat'] + + +def robotic_network(params, step, sL, s): + graph = s['network'] + + delta_balls = {} + for e in graph.edges: + src = e[0] + src_balls = s['balls'][src] + dst = e[1] + dst_balls = s['balls'][dst] + + # transfer balls according to specific robot strat + strat = graph.edges[e]['strat'] + delta_balls[e] = strat(src_balls, dst_balls) + + return_dict = {'nodes': [], 'edges': {}, 'quantity': {}, 'node_strats': {}, 'edge_strats': {}, 'delta': delta_balls} + + return (return_dict) + + +def agent_arrival(params, step, sL, s): + node = len(s['network'].nodes) + edge_list = s['network'].edges + + # choose a m random edges without replacement + # new = np.random.choose(edgelist,m) + new = [0, 1] # tester + + nodes = [node] + edges = [(node, new_node) for new_node in new] + + initial_balls = {node: np.random.randint(1, 25)} + + rv = np.random.randint(0, nstrats) + node_strat = {node: robot_strategies[rv]} + + edge_strats = {e: robot_strategies[rv] for e in edges} + + return_dict = {'nodes': nodes, + 'edges': edges, + 'quantity': initial_balls, + 'node_strats': node_strat, + 'edge_strats': edge_strats, + 'delta': np.zeros(node + 1) + } + return (return_dict) + + +partial_state_update_blocks = [ + { + 'policies': { + # The following policy functions will be evaluated and their returns will be passed to the state update functions + 'p1': robotic_network + }, + 'variables': { # The following state variables will be updated simultaneously + 'balls': update_balls + + } + }, + { + 'policies': { + # The following policy functions will be evaluated and their returns will be passed to the state update functions + 'p1': agent_arrival + }, + 'variables': { # The following state variables will be updated simultaneously + 'network': update_network, + 'balls': update_network_balls + } + } +] + +simulation_parameters = { + 'T': range(T), + 'N': 1, + 'M': {} +} +append_configs( + sim_configs=simulation_parameters, #dict containing state update functions + initial_state=initial_conditions, #dict containing variable names and initial values + partial_state_update_blocks= partial_state_update_blocks #, #dict containing state update functions + # policy_ops=[lambda a, b: {**a, **b}] +) +# config = Configuration(initial_state=initial_conditions, #dict containing variable names and initial values +# partial_state_update_blocks=partial_state_update_blocks, #dict containing state update functions +# sim_config=simulation_parameters #dict containing simulation parameters +# ) diff --git a/simulations/validation/marbles2_run.py b/simulations/validation/marbles2_run.py new file mode 100644 index 0000000..b275b76 --- /dev/null +++ b/simulations/validation/marbles2_run.py @@ -0,0 +1,25 @@ +import pandas as pd +from tabulate import tabulate +# The following imports NEED to be in the exact order +from cadCAD.engine import ExecutionMode, ExecutionContext, Executor +from simulations.validation import marbles2 +from cadCAD import configs + +exec_mode = ExecutionMode() + +print("Simulation Execution: Single Configuration") +print() +first_config = configs # only contains config1 +single_proc_ctx = ExecutionContext(context=exec_mode.single_proc) +run = Executor(exec_context=single_proc_ctx, configs=first_config) + +raw_result, tensor_field = run.main() +result = pd.DataFrame(raw_result) +print() +print("Tensor Field: config1") +print(tabulate(tensor_field, headers='keys', tablefmt='psql')) +print("Output:") +print(tabulate(result, headers='keys', tablefmt='psql')) +print() + +print(result[['network', 'substep']]) \ No newline at end of file diff --git a/simulations/validation/robot-marbles-agents-advanced-udo.ipynb b/simulations/validation/robot-marbles-agents-advanced-udo.ipynb new file mode 100644 index 0000000..aa848fd --- /dev/null +++ b/simulations/validation/robot-marbles-agents-advanced-udo.ipynb @@ -0,0 +1,1617 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# cadCAD Tutorials: The Robot and the Marbles, Networks Addition\n", + "In [Part 2](https://github.com/BlockScience/SimCAD-Tutorials/blob/master/demos/robot-marbles-part-2/robot-marbles-part-2.ipynb) we introduced the 'language' in which a system must be described in order for it to be interpretable by cadCAD and some of the basic concepts of the library:\n", + "* State Variables\n", + "* Timestep\n", + "* Policies\n", + "* State Update Functions\n", + "* Partial State Update Blocks\n", + "* Simulation Configuration Parameters\n", + "\n", + "In the previous example, we observed how two robotic arms acting in parallel could result in counterintuitive system level behavior despite the simplicity of the individual robotic arm policies. \n", + "In this notebook we'll introduce the concept of networks. This done by extending from two boxes of marbles to *n* boxes which are the nodes in our network. Furthermore, there are are going to be arms between some of the boxes but not others forming a network where the arms are the edges.\n", + "\n", + "__The robot and the marbles__ \n", + "* Picture a set of n boxes (`balls`) with an integer number of marbles in each; a network of robotic arms is capable of taking a marble from their one of their boxes and dropping it into the other one.\n", + "* Each robotic arm in the network only controls 2 boxes and they act by moving a marble from one box to the other.\n", + "* Each robotic arm is programmed to take one marble at a time from the box containing the largest number of marbles and drop it in the other box. It repeats that process until the boxes contain an equal number of marbles.\n", + "* For the purposes of our analysis of this system, suppose we are only interested in monitoring the number of marbles in only their two boxes." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from cadCAD.engine import ExecutionMode, ExecutionContext, Executor\n", + "from cadCAD.configuration import Configuration\n", + "from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO\n", + "import networkx as nx\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "%matplotlib inline\n", + "\n", + "T = 50 #iterations in our simulation\n", + "n=3 #number of boxes in our network\n", + "m= 2 #for barabasi graph type number of edges is (n-2)*m\n", + "\n", + "G = nx.barabasi_albert_graph(n, m)\n", + "k = len(G.edges)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "balls = np.zeros(n,)\n", + "\n", + "for node in G.nodes:\n", + " rv = np.random.randint(1,25)\n", + " G.nodes[node]['initial_balls'] = rv\n", + " balls[node] = rv" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAcUAAAE1CAYAAACWU/udAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3XlcVXX+P/DXOefeyyKbuAAuCEoqcAFlE3cpremr2TJWptZUI8oFNUvbm+93WiZtcilTriZT09hM5UxaaVOZSy4FgQvCBXXKNc0VBNnvdn5/RP6mmZILnHvPvZfX8/Hojwg+59Uf9/Hi/eGczxFkWZZBREREENUOQERE5C5YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC1YikRERC00agew22VUnLuCstM12HuyCvtPVePClSZY7DIgA1pJQGgXHZL6hiA9KhT63sFI6B0MrcQ+JyIiZQmyLMtqXPhyvRnv7f0Of9pzHA1mK+wy0GixXfNnfLUiNKIIUQDuzeiHezOiEB7s66LERETk7VxeilX1Zjy3uQKfmM5CEIAmi71d6/hoRMgARg7ohhduS0DvED9lgxIRUafj0lL8tPwcHv3HQTRZbLDYlLmsJArQSSKemRiLaemREARBkXWJiKjzcUkp1jVb8fB7Jdjz7aVWt0jby08rIS4iCKtnpKBHoI9TrkFERN7N6aV4ud6Mu14vwMmqBpit7dsqdZRGFNCtiw7vG0agT1d/p16LiIi8j1NLsabRgttWfYnT1Q2KbZe2RhIEhPhrsXnuKEQE8++MRETkOKc912C12TE9vxBnXFiIAGCTZVQ3WvBr41eoa7a67LpEROT5nFaKK3d8i6MX62B2YSH+yGaXUVlvxv99ZHL5tYmIyHM5pRSPnKvF6l1H0djOxy2U0Gy14+Oyc9jz7SXVMhARkWdRvBStNjty/rYPzSoW4o+aLDbMe/cAt1GJiMghipfi1sMXcLamCaock/MzGs02vFd8Su0YRETkARQvxdU7j6LB7JxnEduj0WLD67uPQaXT7IiIyIMoWopHL9bh0NkrSi6piLomK746Wql2DCIicnOKluLbhSdhs7vfRFZvtiF/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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "scale=100\n", + "nx.draw_kamada_kawai(G, node_size=balls*scale,labels=nx.get_node_attributes(G,'initial_balls'))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "initial_conditions = {'balls':balls, 'network':G}" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "#input the deltas along the edges and update the boxes\n", + "#mechanism: edge by node dimensional operator\n", + "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n", + "# We make the state update functions less \"intelligent\",\n", + "# ie. they simply add the number of marbles specified in _input \n", + "# (which, per the policy function definition, may be negative)\n", + "\n", + "\n", + "def update_balls(params, step, sL, s, _input):\n", + " \n", + " delta_balls = _input['delta']\n", + " new_balls = s['balls']\n", + " for e in G.edges:\n", + " move_ball = delta_balls[e]\n", + " src = e[0]\n", + " dst = e[1]\n", + " if (new_balls[src] >= move_ball) and (new_balls[dst] >= -move_ball):\n", + " new_balls[src] = new_balls[src]-move_ball\n", + " new_balls[dst] = new_balls[dst]+move_ball\n", + " \n", + " \n", + " key = 'balls'\n", + " value = new_balls\n", + " \n", + " return (key, value)\n", + "\n", + "def update_network(params, step, sL, s, _input):\n", + " \n", + " new_nodes = _input['nodes']\n", + " new_edges = _input['edges']\n", + " new_balls = _input['quantity']\n", + " \n", + " graph = s['network']\n", + " \n", + " for node in new_nodes:\n", + " graph.add_node(node)\n", + " graph.nodes[node]['initial_balls'] = new_balls[node]\n", + " graph.nodes[node]['strat'] = _input['node_strats'][node]\n", + " \n", + " for edge in new_edges:\n", + " graph.add_edge(edge[0], edge[1])\n", + " graph.edges[edge]['strat'] = _input['edge_strats'][edge]\n", + " \n", + " \n", + " key = 'network'\n", + " value = graph\n", + " return (key, value)\n", + "\n", + "def update_network_balls(params, step, sL, s, _input):\n", + " \n", + " new_nodes = _input['nodes']\n", + " new_balls = _input['quantity']\n", + " balls = np.zeros(len(s['balls'])+len(new_nodes))\n", + " \n", + " for node in s['network'].nodes:\n", + " balls[node] = s['balls'][node]\n", + " \n", + " for node in new_nodes:\n", + " balls[node] = new_balls[node]\n", + " \n", + " key = 'balls'\n", + " value = balls\n", + " \n", + " return (key, value)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# this time lets make three kinds of robots\n", + "\n", + "def greedy_robot(src_balls, dst_balls):\n", + " \n", + " #robot wishes to accumlate balls at its source\n", + " #takes half of its neighbors balls\n", + " if src_balls < dst_balls:\n", + " delta = -np.floor(dst_balls/2)\n", + " else:\n", + " delta = 0\n", + " \n", + " return delta\n", + "\n", + "def fair_robot(src_balls, dst_balls):\n", + " \n", + " #robot follows the simple balancing rule\n", + " delta = np.sign(src_balls-dst_balls)\n", + " \n", + " return delta\n", + "\n", + "\n", + "def giving_robot(src_balls, dst_balls):\n", + " \n", + " #robot wishes to gice away balls one at a time\n", + " if src_balls > 0:\n", + " delta = 1\n", + " else:\n", + " delta = 0\n", + " \n", + " return delta" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "#in the previous version the robots were assigned to the edges\n", + "#moving towards an agent based model formulation we assign the stratgies\n", + "#instead to the nodes\n", + "robot_strategies = [greedy_robot,fair_robot, giving_robot]\n", + "\n", + "for node in G.nodes:\n", + " nstrats = len(robot_strategies)\n", + " rv = np.random.randint(0,nstrats)\n", + " G.nodes[node]['strat'] = robot_strategies[rv]\n", + "\n", + "for e in G.edges:\n", + " owner_node = e[0]\n", + " G.edges[e]['strat'] = G.nodes[owner_node]['strat']" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "#Policy: node by edge dimensional operator\n", + "#input the states of the boxes output the deltas along the edges\n", + "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n", + "# We specify the robotic networks logic in a Policy Function\n", + "# unlike previous examples our policy controls a vector valued action, defined over the edges of our network\n", + "def robotic_network(params, step, sL, s):\n", + " \n", + " graph = s['network']\n", + " \n", + " \n", + " delta_balls = {}\n", + " for e in graph.edges:\n", + " src = e[0]\n", + " src_balls = s['balls'][src]\n", + " dst = e[1]\n", + " dst_balls = s['balls'][dst]\n", + " \n", + " #transfer balls according to specific robot strat\n", + " strat = graph.edges[e]['strat']\n", + " delta_balls[e] = strat(src_balls,dst_balls)\n", + " \n", + " return_dict = {'nodes': [],'edges': {}, 'quantity': {}, 'node_strats':{},'edge_strats':{},'delta': delta_balls}\n", + "\n", + " return(return_dict)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def agent_arrival(params, step, sL, s):\n", + " \n", + " node= len(s['network'].nodes)\n", + " edge_list = s['network'].edges\n", + " \n", + " #choose a m random edges without replacement\n", + " #new = np.random.choose(edgelist,m) \n", + " new = [0, 1]#tester\n", + " \n", + " nodes = [node]\n", + " edges = [(node,new_node) for new_node in new]\n", + " \n", + " initial_balls = {node:np.random.randint(1,25) }\n", + " \n", + " rv = np.random.randint(0,nstrats)\n", + " node_strat = {node: robot_strategies[rv]}\n", + " \n", + " edge_strats = {e: robot_strategies[rv] for e in edges}\n", + "\n", + " return_dict = {'nodes': nodes,\n", + " 'edges': edges, \n", + " 'quantity':initial_balls, \n", + " 'node_strats':node_strat,\n", + " 'edge_strats':edge_strats,\n", + " 'delta': np.zeros(node+1)\n", + " } \n", + " return(return_dict)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n", + "# In the Partial State Update Blocks, the user specifies if state update functions will be run in series or in parallel\n", + "partial_state_update_blocks = [\n", + " { \n", + " 'policies': { # The following policy functions will be evaluated and their returns will be passed to the state update functions\n", + " 'p1': robotic_network\n", + " },\n", + " 'variables': { # The following state variables will be updated simultaneously\n", + " 'balls': update_balls\n", + " \n", + " }\n", + " },\n", + " {\n", + " 'policies': { # The following policy functions will be evaluated and their returns will be passed to the state update functions\n", + " 'p1': agent_arrival\n", + " },\n", + " 'variables': { # The following state variables will be updated simultaneously\n", + " 'network': update_network,\n", + " 'balls': update_network_balls\n", + " }\n", + " }\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n", + "# Settings of general simulation parameters, unrelated to the system itself\n", + "# `T` is a range with the number of discrete units of time the simulation will run for;\n", + "# `N` is the number of times the simulation will be run (Monte Carlo runs)\n", + "# In this example, we'll run the simulation once (N=1) and its duration will be of 10 timesteps\n", + "# We'll cover the `M` key in a future article. For now, let's leave it empty\n", + "simulation_parameters = {\n", + " 'T': range(T),\n", + " 'N': 1,\n", + " 'M': {}\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n", + "# The configurations above are then packaged into a `Configuration` object\n", + "config = Configuration(initial_state=initial_conditions, #dict containing variable names and initial values\n", + " partial_state_update_blocks=partial_state_update_blocks, #dict containing state update functions\n", + " sim_config=simulation_parameters #dict containing simulation parameters\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "single_proc: []\n" + ] + } + ], + "source": [ + "exec_mode = ExecutionMode()\n", + "exec_context = ExecutionContext(exec_mode.single_proc)\n", + "executor = Executor(exec_context, [config]) # Pass the configuration object inside an array\n", + "raw_result, tensor = executor.main() # The `main()` method returns a tuple; its first elements contains the raw results" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.DataFrame(raw_result)\n", + "balls_list = [b for b in df.balls]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ballsnetworkrunsubsteptimestep
0[13.0, 16.0, 24.0](0, 1, 2)100
1[25.0, 15.0, 13.0](0, 1, 2, 3)111
2[25.0, 15.0, 13.0, 10.0](0, 1, 2, 3)121
3[25.0, 14.0, 14.0, 10.0](0, 1, 2, 3, 4)112
4[25.0, 14.0, 14.0, 10.0, 9.0](0, 1, 2, 3, 4)122
5[25.0, 13.0, 15.0, 10.0, 9.0](0, 1, 2, 3, 4, 5)113
6[25.0, 13.0, 15.0, 10.0, 9.0, 24.0](0, 1, 2, 3, 4, 5)123
7[25.0, 12.0, 16.0, 10.0, 9.0, 24.0](0, 1, 2, 3, 4, 5, 6)114
8[25.0, 12.0, 16.0, 10.0, 9.0, 24.0, 14.0](0, 1, 2, 3, 4, 5, 6)124
9[25.0, 11.0, 17.0, 10.0, 9.0, 24.0, 14.0](0, 1, 2, 3, 4, 5, 6, 7)115
10[25.0, 11.0, 17.0, 10.0, 9.0, 24.0, 14.0, 5.0](0, 1, 2, 3, 4, 5, 6, 7)125
11[25.0, 10.0, 18.0, 10.0, 9.0, 24.0, 14.0, 5.0](0, 1, 2, 3, 4, 5, 6, 7, 8)116
12[25.0, 10.0, 18.0, 10.0, 9.0, 24.0, 14.0, 5.0,...(0, 1, 2, 3, 4, 5, 6, 7, 8)126
13[25.0, 9.0, 19.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)117
14[25.0, 9.0, 19.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)127
15[25.0, 8.0, 20.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)118
16[25.0, 8.0, 20.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)128
17[25.0, 7.0, 21.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)119
18[25.0, 7.0, 21.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)129
19[25.0, 6.0, 22.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)1110
20[25.0, 6.0, 22.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)1210
21[25.0, 5.0, 23.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)1111
22[25.0, 5.0, 23.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)1211
23[25.0, 4.0, 24.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1112
24[25.0, 4.0, 24.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1212
25[25.0, 3.0, 25.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1113
26[25.0, 3.0, 25.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1213
27[25.0, 2.0, 26.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1114
28[25.0, 2.0, 26.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1214
29[38.0, 1.0, 14.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1115
..................
71[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1136
72[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1236
73[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1137
74[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1237
75[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1138
76[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1238
77[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1139
78[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1239
79[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1140
80[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1240
81[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1141
82[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1241
83[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1142
84[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1242
85[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1143
86[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1243
87[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1144
88[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1244
89[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1145
90[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1245
91[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1146
92[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1246
93[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1147
94[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1247
95[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1148
96[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1248
97[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1149
98[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1249
99[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1150
100[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1250
\n", + "

101 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ballsnetworkrunsubsteptimestep
0[13.0, 16.0, 24.0](0, 1, 2)100
1[25.0, 15.0, 13.0](0, 1, 2, 3)111
2[25.0, 15.0, 13.0, 10.0](0, 1, 2, 3)121
3[25.0, 14.0, 14.0, 10.0](0, 1, 2, 3, 4)112
4[25.0, 14.0, 14.0, 10.0, 9.0](0, 1, 2, 3, 4)122
5[25.0, 13.0, 15.0, 10.0, 9.0](0, 1, 2, 3, 4, 5)113
6[25.0, 13.0, 15.0, 10.0, 9.0, 24.0](0, 1, 2, 3, 4, 5)123
7[25.0, 12.0, 16.0, 10.0, 9.0, 24.0](0, 1, 2, 3, 4, 5, 6)114
8[25.0, 12.0, 16.0, 10.0, 9.0, 24.0, 14.0](0, 1, 2, 3, 4, 5, 6)124
9[25.0, 11.0, 17.0, 10.0, 9.0, 24.0, 14.0](0, 1, 2, 3, 4, 5, 6, 7)115
10[25.0, 11.0, 17.0, 10.0, 9.0, 24.0, 14.0, 5.0](0, 1, 2, 3, 4, 5, 6, 7)125
11[25.0, 10.0, 18.0, 10.0, 9.0, 24.0, 14.0, 5.0](0, 1, 2, 3, 4, 5, 6, 7, 8)116
12[25.0, 10.0, 18.0, 10.0, 9.0, 24.0, 14.0, 5.0,...(0, 1, 2, 3, 4, 5, 6, 7, 8)126
13[25.0, 9.0, 19.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)117
14[25.0, 9.0, 19.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)127
15[25.0, 8.0, 20.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)118
16[25.0, 8.0, 20.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)128
17[25.0, 7.0, 21.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)119
18[25.0, 7.0, 21.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)129
19[25.0, 6.0, 22.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)1110
20[25.0, 6.0, 22.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)1210
21[25.0, 5.0, 23.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)1111
22[25.0, 5.0, 23.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)1211
23[25.0, 4.0, 24.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1112
24[25.0, 4.0, 24.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1212
25[25.0, 3.0, 25.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1113
26[25.0, 3.0, 25.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1213
27[25.0, 2.0, 26.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1114
28[25.0, 2.0, 26.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1214
29[38.0, 1.0, 14.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1115
..................
71[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1136
72[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1236
73[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1137
74[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1237
75[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1138
76[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1238
77[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1139
78[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1239
79[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1140
80[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1240
81[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1141
82[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1241
83[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1142
84[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1242
85[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1143
86[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1243
87[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1144
88[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1244
89[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1145
90[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1245
91[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1146
92[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1246
93[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1147
94[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1247
95[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1148
96[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1248
97[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1149
98[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1249
99[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1150
100[38.0, 0.0, 15.0, 10.0, 9.0, 24.0, 14.0, 5.0, ...(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...1250
\n", + "

101 rows × 5 columns

\n", + "
" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "setting an array element with a sequence.", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtimestep\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mballs_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxlabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'iteration'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mylabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'number of balls'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'balls in each box'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlegend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Box #'\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnode\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mnode\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mncol\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/pyplot.py\u001b[0m in \u001b[0;36mplot\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 3356\u001b[0m mplDeprecation)\n\u001b[1;32m 3357\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3358\u001b[0;31m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3359\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3360\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_hold\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mwashold\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/__init__.py\u001b[0m in \u001b[0;36minner\u001b[0;34m(ax, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1853\u001b[0m \u001b[0;34m\"the Matplotlib list!)\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mlabel_namer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1854\u001b[0m RuntimeWarning, stacklevel=2)\n\u001b[0;32m-> 1855\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0max\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1856\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1857\u001b[0m inner.__doc__ = _add_data_doc(inner.__doc__,\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/axes/_axes.py\u001b[0m in \u001b[0;36mplot\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1526\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1527\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mline\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_lines\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1528\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_line\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1529\u001b[0m \u001b[0mlines\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1530\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/axes/_base.py\u001b[0m in \u001b[0;36madd_line\u001b[0;34m(self, line)\u001b[0m\n\u001b[1;32m 1930\u001b[0m \u001b[0mline\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_clip_path\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1931\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1932\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_update_line_limits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1933\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mline\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_label\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1934\u001b[0m \u001b[0mline\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_label\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'_line%d'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlines\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/axes/_base.py\u001b[0m in \u001b[0;36m_update_line_limits\u001b[0;34m(self, line)\u001b[0m\n\u001b[1;32m 1952\u001b[0m \u001b[0mFigures\u001b[0m \u001b[0mout\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mdata\u001b[0m \u001b[0mlimit\u001b[0m \u001b[0mof\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mgiven\u001b[0m \u001b[0mline\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mupdating\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdataLim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1953\u001b[0m \"\"\"\n\u001b[0;32m-> 1954\u001b[0;31m \u001b[0mpath\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mline\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_path\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1955\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvertices\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msize\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1956\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/lines.py\u001b[0m in \u001b[0;36mget_path\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 949\u001b[0m \"\"\"\n\u001b[1;32m 950\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_invalidy\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_invalidx\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 951\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecache\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 952\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_path\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 953\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/lines.py\u001b[0m in \u001b[0;36mrecache\u001b[0;34m(self, always)\u001b[0m\n\u001b[1;32m 655\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0malways\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_invalidy\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 656\u001b[0m \u001b[0myconv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconvert_yunits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_yorig\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 657\u001b[0;31m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_to_unmasked_float_array\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0myconv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mravel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 658\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 659\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_y\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/cbook/__init__.py\u001b[0m in \u001b[0;36m_to_unmasked_float_array\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 2048\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0masarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfilled\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnan\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2049\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2050\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0masarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2051\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2052\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/numpy/core/numeric.py\u001b[0m in \u001b[0;36masarray\u001b[0;34m(a, dtype, order)\u001b[0m\n\u001b[1;32m 490\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 491\u001b[0m \"\"\"\n\u001b[0;32m--> 492\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0morder\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0morder\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 493\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 494\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: setting an array element with a sequence." + ], + "output_type": "error" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAD8CAYAAAB0IB+mAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAADU9JREFUeJzt3GGI5Hd9x/H3xztTaYym9FaQu9Ok9NJ42ELSJU0Raoq2XPLg7oFF7iBYJXhgGylVhBRLlPjIhloQrtWTilXQGH0gC57cA40ExAu3ITV4FyLb03oXhawxzZOgMe23D2bSna53mX92Z3cv+32/4GD+//ntzJcfe++dndmZVBWSpO3vFVs9gCRpcxh8SWrC4EtSEwZfkpow+JLUhMGXpCamBj/JZ5M8meT7l7g+ST6ZZCnJo0lunP2YkqT1GvII/3PAgRe5/lZg3/jfUeBf1j+WJGnWpga/qh4Efv4iSw4Bn6+RU8DVSV4/qwElSbOxcwa3sRs4P3F8YXzup6sXJjnK6LcArrzyyj+8/vrrZ3D3ktTHww8//LOqmlvL184i+INV1XHgOMD8/HwtLi5u5t1L0stekv9c69fO4q90ngD2ThzvGZ+TJF1GZhH8BeBd47/WuRl4pqp+7ekcSdLWmvqUTpIvAbcAu5JcAD4CvBKgqj4FnABuA5aAZ4H3bNSwkqS1mxr8qjoy5foC/npmE0mSNoTvtJWkJgy+JDVh8CWpCYMvSU0YfElqwuBLUhMGX5KaMPiS1ITBl6QmDL4kNWHwJakJgy9JTRh8SWrC4EtSEwZfkpow+JLUhMGXpCYMviQ1YfAlqQmDL0lNGHxJasLgS1ITBl+SmjD4ktSEwZekJgy+JDVh8CWpCYMvSU0YfElqwuBLUhMGX5KaMPiS1ITBl6QmDL4kNWHwJamJQcFPciDJ40mWktx1kevfkOSBJI8keTTJbbMfVZK0HlODn2QHcAy4FdgPHEmyf9Wyvwfur6obgMPAP896UEnS+gx5hH8TsFRV56rqOeA+4NCqNQW8Znz5tcBPZjeiJGkWhgR/N3B+4vjC+NykjwK3J7kAnADef7EbSnI0yWKSxeXl5TWMK0laq1m9aHsE+FxV7QFuA76Q5Nduu6qOV9V8Vc3Pzc3N6K4lSUMMCf4TwN6J4z3jc5PuAO4HqKrvAq8Cds1iQEnSbAwJ/mlgX5Jrk1zB6EXZhVVrfgy8DSDJmxgF3+dsJOkyMjX4VfU8cCdwEniM0V/jnElyT5KD42UfBN6b5HvAl4B3V1Vt1NCSpJdu55BFVXWC0Yuxk+funrh8FnjLbEeTJM2S77SVpCYMviQ1YfAlqQmDL0lNGHxJasLgS1ITBl+SmjD4ktSEwZekJgy+JDVh8CWpCYMvSU0YfElqwuBLUhMGX5KaMPiS1ITBl6QmDL4kNWHwJakJgy9JTRh8SWrC4EtSEwZfkpow+JLUhMGXpCYMviQ1YfAlqQmDL0lNGHxJasLgS1ITBl+SmjD4ktSEwZekJgy+JDUxKPhJDiR5PMlSkrsuseadSc4mOZPki7MdU5K0XjunLUiyAzgG/BlwATidZKGqzk6s2Qf8HfCWqno6yes2amBJ0toMeYR/E7BUVeeq6jngPuDQqjXvBY5V1dMAVfXkbMeUJK3XkODvBs5PHF8Yn5t0HXBdku8kOZXkwMVuKMnRJItJFpeXl9c2sSRpTWb1ou1OYB9wC3AE+EySq1cvqqrjVTVfVfNzc3MzumtJ0hBDgv8EsHfieM/43KQLwEJV/aqqfgj8gNEPAEnSZWJI8E8D+5Jcm+QK4DCwsGrN1xg9uifJLkZP8Zyb4ZySpHWaGvyqeh64EzgJPAbcX1VnktyT5OB42UngqSRngQeAD1XVUxs1tCTppUtVbckdz8/P1+Li4pbctyS9XCV5uKrm1/K1vtNWkpow+JLUhMGXpCYMviQ1YfAlqQmDL0lNGHxJasLgS1ITBl+SmjD4ktSEwZekJgy+JDVh8CWpCYMvSU0YfElqwuBLUhMGX5KaMPiS1ITBl6QmDL4kNWHwJakJgy9JTRh8SWrC4EtSEwZfkpow+JLUhMGXpCYMviQ1YfAlqQmDL0lNGHxJasLgS1ITBl+SmjD4ktSEwZekJgYFP8mBJI8nWUpy14use0eSSjI/uxElSbMwNfhJdgDHgFuB/cCRJPsvsu4q4G+Ah2Y9pCRp/YY8wr8JWKqqc1X1HHAfcOgi6z4GfBz4xQznkyTNyJDg7wbOTxxfGJ/7P0luBPZW1ddf7IaSHE2ymGRxeXn5JQ8rSVq7db9om+QVwCeAD05bW1XHq2q+qubn5ubWe9eSpJdgSPCfAPZOHO8Zn3vBVcCbgW8n+RFwM7DgC7eSdHkZEvzTwL4k1ya5AjgMLLxwZVU9U1W7quqaqroGOAUcrKrFDZlYkrQmU4NfVc8DdwIngceA+6vqTJJ7khzc6AElSbOxc8iiqjoBnFh17u5LrL1l/WNJkmbNd9pKUhMGX5KaMPiS1ITBl6QmDL4kNWHwJakJgy9JTRh8SWrC4EtSEwZfkpow+JLUhMGXpCYMviQ1YfAlqQmDL0lNGHxJasLgS1ITBl+SmjD4ktSEwZekJgy+JDVh8CWpCYMvSU0YfElqwuBLUhMGX5KaMPiS1ITBl6QmDL4kNWHwJakJgy9JTRh8SWrC4EtSEwZfkpoYFPwkB5I8nmQpyV0Xuf4DSc4meTTJN5O8cfajSpLWY2rwk+wAjgG3AvuBI0n2r1r2CDBfVX8AfBX4h1kPKklanyGP8G8ClqrqXFU9B9wHHJpcUFUPVNWz48NTwJ7ZjilJWq8hwd8NnJ84vjA+dyl3AN+42BVJjiZZTLK4vLw8fEpJ0rrN9EXbJLcD88C9F7u+qo5X1XxVzc/Nzc3yriVJU+wcsOYJYO/E8Z7xuf8nyduBDwNvrapfzmY8SdKsDHmEfxrYl+TaJFcAh4GFyQVJbgA+DRysqidnP6Ykab2mBr+qngfuBE4CjwH3V9WZJPckOThedi/wauArSf49ycIlbk6StEWGPKVDVZ0ATqw6d/fE5bfPeC5J0oz5TltJasLgS1ITBl+SmjD4ktSEwZekJgy+JDVh8CWpCYMvSU0YfElqwuBLUhMGX5KaMPiS1ITBl6QmDL4kNWHwJakJgy9JTRh8SWrC4EtSEwZfkpow+JLUhMGXpCYMviQ1YfAlqQmDL0lNGHxJasLgS1ITBl+SmjD4ktSEwZekJgy+JDVh8CWpCYMvSU0YfElqwuBLUhMGX5KaGBT8JAeSPJ5kKcldF7n+N5J8eXz9Q0mumfWgkqT1mRr8JDuAY8CtwH7gSJL9q5bdATxdVb8L/BPw8VkPKklanyGP8G8ClqrqXFU9B9wHHFq15hDwb+PLXwXeliSzG1OStF47B6zZDZyfOL4A/NGl1lTV80meAX4b+NnkoiRHgaPjw18m+f5aht6GdrFqrxpzL1a4FyvcixW/t9YvHBL8mamq48BxgCSLVTW/mfd/uXIvVrgXK9yLFe7FiiSLa/3aIU/pPAHsnTjeMz530TVJdgKvBZ5a61CSpNkbEvzTwL4k1ya5AjgMLKxaswD85fjyXwDfqqqa3ZiSpPWa+pTO+Dn5O4GTwA7gs1V1Jsk9wGJVLQD/CnwhyRLwc0Y/FKY5vo65txv3YoV7scK9WOFerFjzXsQH4pLUg++0laQmDL4kNbHhwfdjGVYM2IsPJDmb5NEk30zyxq2YczNM24uJde9IUkm27Z/kDdmLJO8cf2+cSfLFzZ5xswz4P/KGJA8keWT8/+S2rZhzoyX5bJInL/VepYx8crxPjya5cdANV9WG/WP0Iu9/AL8DXAF8D9i/as1fAZ8aXz4MfHkjZ9qqfwP34k+B3xxffl/nvRivuwp4EDgFzG/13Fv4fbEPeAT4rfHx67Z67i3ci+PA+8aX9wM/2uq5N2gv/gS4Efj+Ja6/DfgGEOBm4KEht7vRj/D9WIYVU/eiqh6oqmfHh6cYvedhOxryfQHwMUafy/SLzRxukw3Zi/cCx6rqaYCqenKTZ9wsQ/aigNeML78W+MkmzrdpqupBRn/xeCmHgM/XyCng6iSvn3a7Gx38i30sw+5Lramq54EXPpZhuxmyF5PuYPQTfDuauhfjX1H3VtXXN3OwLTDk++I64Lok30lyKsmBTZtucw3Zi48Ctye5AJwA3r85o112XmpPgE3+aAUNk+R2YB5461bPshWSvAL4BPDuLR7lcrGT0dM6tzD6re/BJL9fVf+1pVNtjSPA56rqH5P8MaP3/7y5qv5nqwd7OdjoR/h+LMOKIXtBkrcDHwYOVtUvN2m2zTZtL64C3gx8O8mPGD1HubBNX7gd8n1xAVioql9V1Q+BHzD6AbDdDNmLO4D7Aarqu8CrGH2wWjeDerLaRgffj2VYMXUvktwAfJpR7Lfr87QwZS+q6pmq2lVV11TVNYxezzhYVWv+0KjL2JD/I19j9OieJLsYPcVzbjOH3CRD9uLHwNsAkryJUfCXN3XKy8MC8K7xX+vcDDxTVT+d9kUb+pRObdzHMrzsDNyLe4FXA18Zv27946o6uGVDb5CBe9HCwL04Cfx5krPAfwMfqqpt91vwwL34IPCZJH/L6AXcd2/HB4hJvsToh/yu8esVHwFeCVBVn2L0+sVtwBLwLPCeQbe7DfdKknQRvtNWkpow+JLUhMGXpCYMviQ1YfAlqQmDL0lNGHxJauJ/Acz2XLpusNoKAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(df.timestep.values, balls_list)\n", + "plt.xlabel('iteration')\n", + "plt.ylabel('number of balls')\n", + "plt.title('balls in each box')\n", + "plt.legend(['Box #'+str(node) for node in range(n)], ncol = 2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "end_state_balls = np.array([b for b in balls_list[-1]])\n", + "avg_balls = np.array([np.mean(b) for b in balls_list])\n", + "\n", + "for node in G.nodes:\n", + " G.nodes[node]['final_balls'] = end_state_balls[node]\n", + " G.nodes[node]['avg_balls'] = avg_balls[node]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cmap = plt.cm.jet\n", + "Nc = cmap.N\n", + "Ns = len(robot_strategies)\n", + "d = int(Nc/Ns)\n", + "\n", + "k = len(G.edges)\n", + "strat_color = []\n", + "for e in G.edges:\n", + " \n", + " for i in range(Ns):\n", + " if G.edges[e]['strat']==robot_strategies[i]:\n", + " color = cmap(i*d)\n", + " G.edges[e]['color'] = color\n", + " strat_color = strat_color+[color]\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "nx.draw_kamada_kawai(G, node_size=end_state_balls*scale, labels=nx.get_node_attributes(G,'final_balls'), edge_color=strat_color)\n", + "print(end_state_balls)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rolling_avg_balls = np.zeros((T+1, n))\n", + "for t in range(T+1):\n", + " for node in G.nodes:\n", + " for tau in range(t):\n", + " rolling_avg_balls[t,node] = (tau)/(tau+1)*rolling_avg_balls[t, node]+ 1/(tau+1)*balls_list[tau][node]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot(range(len(rolling_avg_balls)),rolling_avg_balls)\n", + "plt.xlabel('iteration')\n", + "plt.ylabel('number of balls')\n", + "plt.title('time average balls in each box')\n", + "plt.legend(['Box #'+str(node) for node in range(n)], ncol = 2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for node in G.nodes:\n", + " G.nodes[node]['avg_balls'] = int(10*(rolling_avg_balls[node][-1]))/10\n", + "\n", + "nx.draw_kamada_kawai(G, node_size=avg_balls*scale, labels=nx.get_node_attributes(G,'avg_balls'))\n", + "print(end_state_balls)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cmap = plt.cm.jet\n", + "Nc = cmap.N\n", + "Nt = len(simulation_parameters['T'])\n", + "dN = int(Nc/Nt)\n", + "cmaplist = [cmap(i*dN) for i in range(Nt)]\n", + "\n", + "for t in simulation_parameters['T']:\n", + " state = np.array([b for b in balls_list[t]])\n", + " nx.draw_kamada_kawai(G, node_size=state*scale, alpha = .4/(t+1), node_color = cmaplist[t])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/simulations/validation/udo.py b/simulations/validation/udo.py index dc644e5..e3c2e66 100644 --- a/simulations/validation/udo.py +++ b/simulations/validation/udo.py @@ -144,6 +144,7 @@ PSUB = { # needs M1&2 need behaviors partial_state_update_blocks = [PSUB] * substeps +# pp.pprint(partial_state_update_blocks) sim_config = config_sim({ "N": 2,