Skip to content

Commit

Permalink
Merge pull request #24 from Macr0Nerd/node_generators
Browse files Browse the repository at this point in the history
Add node generators
  • Loading branch information
Macr0Nerd authored Dec 29, 2023
2 parents 97f0363 + a6aeb06 commit 8b4c9fd
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 64 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The schema has been provided below:
```toml
simulation_id = "name of simulation"
algorithms_directory = "/path/to/algorithms/"
nodes = [ { node_id = "node_1", algorithm = { file = "foo.py", object = "Foo" } },
nodes = [ { node_id = "node_1", algorithm = { file = "foo.py", object = "Foo" }, quantity = 11 },
{ node_id = "node_2", algorithm = { file = "bar/baz.py", object = "Baz" } } ]
simulation = { file = "foobar.py", object = "GenerationalFooBar" }
generational_simulation = { file = "foobar.py", object = "FooBar" }
Expand All @@ -54,7 +54,11 @@ simulations_directory = "/path/to/simulations/"
* generational_simulation
* The simulation to run for each generation in a generational simulation as a [Dynamic Import](#dynamic-imports)
* nodes
* An array of tables that specify a node id and an algorithm, as defined in the [Dynamic Imports](#dynamic-imports)
* An array of tables that specify:
* node id
* algorithm, as defined in the [Dynamic Imports](#dynamic-imports)
* quantity, if not specified then 1 node is assumed
* Note: the node index will be appended to the node_id
section
* simulation
* The simulation to run as a [Dynamic Import](#dynamic-imports)
Expand Down
2 changes: 2 additions & 0 deletions docs/simulations.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ points per algorithm to the average points per algorithm.
This simulation accepts one additional argument:
* generations | int
* The number of generations to run

**WARNING: USING A LOT OF GENERATIONS, ROUNDS, AND NODES CAN CAUSE THIS SIMULATION TO USE A LOT OF PROCESSING POWER**
16 changes: 8 additions & 8 deletions examples/config/complete_generational_mss.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
simulation_id = "Complete StandardGenerationalSimulation for MultiprocessStandardSimulation"
algorithms_directory = "examples/algorithms/"
nodes = [ { node_id = "always_cooperate", algorithm = { file = "simple.py", object = "AlwaysCooperate" } },
{ node_id = "always_defect", algorithm = { file = "simple.py", object = "AlwaysDefect" } },
{ node_id = "grim_trigger", algorithm = { file = "grudge.py", object = "GrimTrigger" } },
{ node_id = "random_cooperation", algorithm = { file = "simple.py", object = "RandomCooperation" } },
{ node_id = "tit_for_tat", algorithm = { file = "tit_for_tat.py", object = "TitForTat" } },
{ node_id = "tit_for_two_tats", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" } },
{ node_id = "two_tits_for_tat", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" } } ]
nodes = [ { node_id = "always_cooperate_", algorithm = { file = "simple.py", object = "AlwaysCooperate"}, quantity = 10 },
{ node_id = "always_defect_", algorithm = { file = "simple.py", object = "AlwaysDefect" }, quantity = 10 },
{ node_id = "grim_trigger_", algorithm = { file = "grudge.py", object = "GrimTrigger" }, quantity = 10 },
{ node_id = "random_cooperation_", algorithm = { file = "simple.py", object = "RandomCooperation" }, quantity = 10 },
{ node_id = "tit_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TitForTat" }, quantity = 10 },
{ node_id = "tit_for_two_tats_", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" }, quantity = 10 },
{ node_id = "two_tits_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" }, quantity = 10 } ]
simulation = { object = "StandardGenerationalSimulation" }
generational_simulation = { object = 'MultiprocessStandardSimulation' }
simulation_arguments = { generations = 10, rounds = 200 }
simulation_arguments = { generations = 10, rounds = 200, pool_size = 4 }
simulation_data_output = "examples/rounds/complete_generational_mss.json"
simulation_results_output = "examples/results/complete_generational_mss.json"
14 changes: 7 additions & 7 deletions examples/config/complete_generational_ss.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
simulation_id = "Complete StandardGenerationalSimulation for StandardSimulation"
algorithms_directory = "examples/algorithms/"
nodes = [ { node_id = "always_cooperate", algorithm = { file = "simple.py", object = "AlwaysCooperate" } },
{ node_id = "always_defect", algorithm = { file = "simple.py", object = "AlwaysDefect" } },
{ node_id = "grim_trigger", algorithm = { file = "grudge.py", object = "GrimTrigger" } },
{ node_id = "random_cooperation", algorithm = { file = "simple.py", object = "RandomCooperation" } },
{ node_id = "tit_for_tat", algorithm = { file = "tit_for_tat.py", object = "TitForTat" } },
{ node_id = "tit_for_two_tats", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" } },
{ node_id = "two_tits_for_tat", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" } } ]
nodes = [ { node_id = "always_cooperate_", algorithm = { file = "simple.py", object = "AlwaysCooperate"}, quantity = 10 },
{ node_id = "always_defect_", algorithm = { file = "simple.py", object = "AlwaysDefect" }, quantity = 10 },
{ node_id = "grim_trigger_", algorithm = { file = "grudge.py", object = "GrimTrigger" }, quantity = 10 },
{ node_id = "random_cooperation_", algorithm = { file = "simple.py", object = "RandomCooperation" }, quantity = 10 },
{ node_id = "tit_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TitForTat" }, quantity = 10 },
{ node_id = "tit_for_two_tats_", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" }, quantity = 10 },
{ node_id = "two_tits_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" }, quantity = 10 } ]
simulation = { object = "StandardGenerationalSimulation" }
generational_simulation = { object = 'StandardSimulation' }
simulation_arguments = { generations = 10, rounds = 200 }
Expand Down
16 changes: 8 additions & 8 deletions examples/config/mutable_complete_generational_mss.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
simulation_id = "Mutable Complete StandardGenerationalSimulation for MultiprocessStandardSimulation"
algorithms_directory = "examples/algorithms/"
nodes = [ { node_id = "always_cooperate", algorithm = { file = "simple.py", object = "AlwaysCooperate" } },
{ node_id = "always_defect", algorithm = { file = "simple.py", object = "AlwaysDefect" } },
{ node_id = "grim_trigger", algorithm = { file = "grudge.py", object = "GrimTrigger" } },
{ node_id = "random_cooperation", algorithm = { file = "simple.py", object = "RandomCooperation" } },
{ node_id = "tit_for_tat", algorithm = { file = "tit_for_tat.py", object = "TitForTat" } },
{ node_id = "tit_for_two_tats", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" } },
{ node_id = "two_tits_for_tat", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" } } ]
nodes = [ { node_id = "always_cooperate_", algorithm = { file = "simple.py", object = "AlwaysCooperate"}, quantity = 10 },
{ node_id = "always_defect_", algorithm = { file = "simple.py", object = "AlwaysDefect" }, quantity = 10 },
{ node_id = "grim_trigger_", algorithm = { file = "grudge.py", object = "GrimTrigger" }, quantity = 10 },
{ node_id = "random_cooperation_", algorithm = { file = "simple.py", object = "RandomCooperation" }, quantity = 10 },
{ node_id = "tit_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TitForTat" }, quantity = 10 },
{ node_id = "tit_for_two_tats_", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" }, quantity = 10 },
{ node_id = "two_tits_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" }, quantity = 10 } ]
simulation = { object = "StandardGenerationalSimulation" }
generational_simulation = { object = 'MultiprocessStandardSimulation' }
simulation_arguments = { generations = 10, rounds = 200, simulation_mutations = true, mutations_per_mille = 100 }
simulation_arguments = { generations = 10, rounds = 200, simulation_mutations = true, mutations_per_mille = 100, pool_size = 4 }
simulation_data_output = "examples/rounds/mutable_complete_generational_mss.json"
simulation_results_output = "examples/results/mutable_complete_generational_mss.json"
14 changes: 7 additions & 7 deletions examples/config/mutable_complete_generational_ss.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
simulation_id = "Mutable Complete StandardGenerationalSimulation for StandardSimulation"
algorithms_directory = "examples/algorithms/"
nodes = [ { node_id = "always_cooperate", algorithm = { file = "simple.py", object = "AlwaysCooperate" } },
{ node_id = "always_defect", algorithm = { file = "simple.py", object = "AlwaysDefect" } },
{ node_id = "grim_trigger", algorithm = { file = "grudge.py", object = "GrimTrigger" } },
{ node_id = "random_cooperation", algorithm = { file = "simple.py", object = "RandomCooperation" } },
{ node_id = "tit_for_tat", algorithm = { file = "tit_for_tat.py", object = "TitForTat" } },
{ node_id = "tit_for_two_tats", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" } },
{ node_id = "two_tits_for_tat", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" } } ]
nodes = [ { node_id = "always_cooperate_", algorithm = { file = "simple.py", object = "AlwaysCooperate"}, quantity = 10 },
{ node_id = "always_defect_", algorithm = { file = "simple.py", object = "AlwaysDefect" }, quantity = 10 },
{ node_id = "grim_trigger_", algorithm = { file = "grudge.py", object = "GrimTrigger" }, quantity = 10 },
{ node_id = "random_cooperation_", algorithm = { file = "simple.py", object = "RandomCooperation" }, quantity = 10 },
{ node_id = "tit_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TitForTat" }, quantity = 10 },
{ node_id = "tit_for_two_tats_", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" }, quantity = 10 },
{ node_id = "two_tits_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" }, quantity = 10 } ]
simulation = { object = "StandardGenerationalSimulation" }
generational_simulation = { object = 'StandardSimulation' }
simulation_arguments = { generations = 10, rounds = 200, simulation_mutations = true, mutations_per_mille = 100 }
Expand Down
16 changes: 8 additions & 8 deletions examples/config/mutable_noisy_complete_generational_mss.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
simulation_id = "Mutable Noisy Complete StandardGenerationalSimulation for MultiprocessStandardSimulation"
algorithms_directory = "examples/algorithms/"
nodes = [ { node_id = "always_cooperate", algorithm = { file = "simple.py", object = "AlwaysCooperate" } },
{ node_id = "always_defect", algorithm = { file = "simple.py", object = "AlwaysDefect" } },
{ node_id = "grim_trigger", algorithm = { file = "grudge.py", object = "GrimTrigger" } },
{ node_id = "random_cooperation", algorithm = { file = "simple.py", object = "RandomCooperation" } },
{ node_id = "tit_for_tat", algorithm = { file = "tit_for_tat.py", object = "TitForTat" } },
{ node_id = "tit_for_two_tats", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" } },
{ node_id = "two_tits_for_tat", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" } } ]
nodes = [ { node_id = "always_cooperate_", algorithm = { file = "simple.py", object = "AlwaysCooperate"}, quantity = 10 },
{ node_id = "always_defect_", algorithm = { file = "simple.py", object = "AlwaysDefect" }, quantity = 10 },
{ node_id = "grim_trigger_", algorithm = { file = "grudge.py", object = "GrimTrigger" }, quantity = 10 },
{ node_id = "random_cooperation_", algorithm = { file = "simple.py", object = "RandomCooperation" }, quantity = 10 },
{ node_id = "tit_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TitForTat" }, quantity = 10 },
{ node_id = "tit_for_two_tats_", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" }, quantity = 10 },
{ node_id = "two_tits_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" }, quantity = 10 } ]
simulation = { object = "StandardGenerationalSimulation" }
generational_simulation = { object = 'MultiprocessStandardSimulation' }
simulation_arguments = { generations = 10, rounds = 200, noise = true, noise_per_mille = 250, simulation_mutations = true, mutations_per_mille = 100 }
simulation_arguments = { generations = 10, rounds = 200, noise = true, noise_per_mille = 250, simulation_mutations = true, mutations_per_mille = 100, pool_size = 4 }
simulation_data_output = "examples/rounds/mutable_noisy_complete_generational_mss.json"
simulation_results_output = "examples/results/mutable_noisy_complete_generational_mss.json"
14 changes: 7 additions & 7 deletions examples/config/mutable_noisy_complete_generational_ss.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
simulation_id = "Mutable Noisy Complete StandardGenerationalSimulation for StandardSimulation"
algorithms_directory = "examples/algorithms/"
nodes = [ { node_id = "always_cooperate", algorithm = { file = "simple.py", object = "AlwaysCooperate" } },
{ node_id = "always_defect", algorithm = { file = "simple.py", object = "AlwaysDefect" } },
{ node_id = "grim_trigger", algorithm = { file = "grudge.py", object = "GrimTrigger" } },
{ node_id = "random_cooperation", algorithm = { file = "simple.py", object = "RandomCooperation" } },
{ node_id = "tit_for_tat", algorithm = { file = "tit_for_tat.py", object = "TitForTat" } },
{ node_id = "tit_for_two_tats", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" } },
{ node_id = "two_tits_for_tat", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" } } ]
nodes = [ { node_id = "always_cooperate_", algorithm = { file = "simple.py", object = "AlwaysCooperate"}, quantity = 10 },
{ node_id = "always_defect_", algorithm = { file = "simple.py", object = "AlwaysDefect" }, quantity = 10 },
{ node_id = "grim_trigger_", algorithm = { file = "grudge.py", object = "GrimTrigger" }, quantity = 10 },
{ node_id = "random_cooperation_", algorithm = { file = "simple.py", object = "RandomCooperation" }, quantity = 10 },
{ node_id = "tit_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TitForTat" }, quantity = 10 },
{ node_id = "tit_for_two_tats_", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" }, quantity = 10 },
{ node_id = "two_tits_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" }, quantity = 10 } ]
simulation = { object = "StandardGenerationalSimulation" }
generational_simulation = { object = 'StandardSimulation' }
simulation_arguments = { generations = 10, rounds = 200, noise = true, noise_per_mille = 250, simulation_mutations = true, mutations_per_mille = 100 }
Expand Down
16 changes: 8 additions & 8 deletions examples/config/noisy_complete_generational_mss.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
simulation_id = "Noisy Complete StandardGenerationalSimulation for MultiprocessStandardSimulation"
algorithms_directory = "examples/algorithms/"
nodes = [ { node_id = "always_cooperate", algorithm = { file = "simple.py", object = "AlwaysCooperate" } },
{ node_id = "always_defect", algorithm = { file = "simple.py", object = "AlwaysDefect" } },
{ node_id = "grim_trigger", algorithm = { file = "grudge.py", object = "GrimTrigger" } },
{ node_id = "random_cooperation", algorithm = { file = "simple.py", object = "RandomCooperation" } },
{ node_id = "tit_for_tat", algorithm = { file = "tit_for_tat.py", object = "TitForTat" } },
{ node_id = "tit_for_two_tats", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" } },
{ node_id = "two_tits_for_tat", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" } } ]
nodes = [ { node_id = "always_cooperate_", algorithm = { file = "simple.py", object = "AlwaysCooperate"}, quantity = 10 },
{ node_id = "always_defect_", algorithm = { file = "simple.py", object = "AlwaysDefect" }, quantity = 10 },
{ node_id = "grim_trigger_", algorithm = { file = "grudge.py", object = "GrimTrigger" }, quantity = 10 },
{ node_id = "random_cooperation_", algorithm = { file = "simple.py", object = "RandomCooperation" }, quantity = 10 },
{ node_id = "tit_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TitForTat" }, quantity = 10 },
{ node_id = "tit_for_two_tats_", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" }, quantity = 10 },
{ node_id = "two_tits_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" }, quantity = 10 } ]
simulation = { object = "StandardGenerationalSimulation" }
generational_simulation = { object = 'MultiprocessStandardSimulation' }
simulation_arguments = { generations = 10, rounds = 200, noise = true, noise_per_mille = 250 }
simulation_arguments = { generations = 10, rounds = 200, noise = true, noise_per_mille = 250, pool_size = 4 }
simulation_data_output = "examples/rounds/noisy_complete_generational_mss.json"
simulation_results_output = "examples/results/noisy_complete_generational_mss.json"
14 changes: 7 additions & 7 deletions examples/config/noisy_complete_generational_ss.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
simulation_id = "Noisy Complete StandardGenerationalSimulation for StandardSimulation"
algorithms_directory = "examples/algorithms/"
nodes = [ { node_id = "always_cooperate", algorithm = { file = "simple.py", object = "AlwaysCooperate" } },
{ node_id = "always_defect", algorithm = { file = "simple.py", object = "AlwaysDefect" } },
{ node_id = "grim_trigger", algorithm = { file = "grudge.py", object = "GrimTrigger" } },
{ node_id = "random_cooperation", algorithm = { file = "simple.py", object = "RandomCooperation" } },
{ node_id = "tit_for_tat", algorithm = { file = "tit_for_tat.py", object = "TitForTat" } },
{ node_id = "tit_for_two_tats", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" } },
{ node_id = "two_tits_for_tat", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" } } ]
nodes = [ { node_id = "always_cooperate_", algorithm = { file = "simple.py", object = "AlwaysCooperate"}, quantity = 10 },
{ node_id = "always_defect_", algorithm = { file = "simple.py", object = "AlwaysDefect" }, quantity = 10 },
{ node_id = "grim_trigger_", algorithm = { file = "grudge.py", object = "GrimTrigger" }, quantity = 10 },
{ node_id = "random_cooperation_", algorithm = { file = "simple.py", object = "RandomCooperation" }, quantity = 10 },
{ node_id = "tit_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TitForTat" }, quantity = 10 },
{ node_id = "tit_for_two_tats_", algorithm = { file = "tit_for_tat.py", object = "TitForTwoTats" }, quantity = 10 },
{ node_id = "two_tits_for_tat_", algorithm = { file = "tit_for_tat.py", object = "TwoTitsForTat" }, quantity = 10 } ]
simulation = { object = "StandardGenerationalSimulation" }
generational_simulation = { object = 'StandardSimulation' }
simulation_arguments = { generations = 10, rounds = 200, noise = true, noise_per_mille = 250 }
Expand Down
2 changes: 1 addition & 1 deletion src/project_dilemma/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
__version__ = '1.0.0'
__version__ = '1.1.0'

__all__ = ['config', 'interfaces', 'object_loaders', 'simulations']
1 change: 1 addition & 0 deletions src/project_dilemma/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class DynamicImport(TypedDict):
class NodeConfig(TypedDict):
node_id: str
algorithm: DynamicImport
quantity: NotRequired[int]


class ProjectDilemmaConfig(TypedDict):
Expand Down
7 changes: 6 additions & 1 deletion src/project_dilemma/object_loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ def create_nodes(config: ProjectDilemmaConfig, algorithms_map: Dict[str, type[Al
nodes = []

for node in config['nodes']:
nodes.append(Node(node['node_id'], algorithms_map[node['algorithm']['object']]))
if not node.get('quantity'):
nodes.append(Node(node["node_id"], algorithms_map[node['algorithm']['object']]))
continue

for i in range(node['quantity']):
nodes.append(Node(f'{node["node_id"]}{i}', algorithms_map[node['algorithm']['object']]))

return nodes

Expand Down

0 comments on commit 8b4c9fd

Please sign in to comment.