EwoutH / World-model-prototype

A quick and dirty prototype to discover the processes and technical challenges of building and ABM world model.
GNU Lesser General Public License v2.1
1 stars 1 forks source link

Determine on which level behaviors interact with agents #4

Open EwoutH opened 9 months ago

EwoutH commented 9 months ago

There should be a consistent level (or maybe multiple supported levels) on which behaviors interact with agents. Possibilities:

Maybe more?

EwoutH commented 9 months ago

Some ideas.

There are two dimensions of this problem:

  1. Which entities does the behavior interact with?
  2. What does the behavior want to do with those entities?

The first one is probably splitable in:

  1. Entities to interact with a. Nothing (maybe regular input or output arguments) b. The own Agent's states c. Other Agent's states (one or multiple) d. The Model's states

Then, it can do some things with those entities

  1. What does it: a. Nothing b. Use the states as input c. Modify the states d. Use the states as input and modify the states

So, this theoretically creates 16 options. However, a lot of them are the same. I think we can classify it into 4 distinct categories:

Screenshot_264 agent-interaction-states-table.xlsx

EwoutH commented 9 months ago

We might be able to simplify this to only two or three options:

Based on the entity-interaction classification provided, here's how we could structure behaviors for each class. These are conceptual structures that would need to be adapted into actual code within the context of your ABM framework:

1. No Interaction (Gray Area)

  • Structure: Regular function
  • Description: These are standalone functions that do not interact with any entities; they perform calculations or logic based solely on input arguments and produce outputs.
  • Example:
    def calculate_tax(income):
      return income * 0.3 # Fixed tax rate for example

2. Interaction with Own Agent's State (Green Area)

  • Structure: Agent Method or Mixin Class
  • Description: Methods within the Agent class or a Mixin class that operate on the agent's internal state. Mixins can be used to add shared behavior across different types of agents.
  • Example:
    class HealthMixin:
      def update_health(self, health_change):
          self.health += health_change
          self.health = max(min(self.health, 100), 0) # Clamp health between 0 and 100

3. Interaction with Other Agents' and/or Model's States (Blue and Orange Areas)

  • Structure: Agent Method with External References
  • Description: Methods within the Agent class that reference other agents or model states. These can either modify other agents' states directly or use them as input for decision-making.
  • Example:
    class TradeMixin:
      def trade_with_others(self, market):
          for other_agent in market.agents:
              if self.can_trade(other_agent):
                  self.conduct_trade(other_agent)

Basically, there isn't a big difference between the orange and blue categories. Even more, the green might just need to pass self, while the orange/blue needs an additional input parameter (a list of) other agents or the model categories.

Of course, there will be cases where both a function or Mixin should be possible, for example if only one or two of the agent (or other agent's or model) states are need, only as input.

So currently, I think the conclusion is that a function should either be a function (stateless) or a Mixin (non stateless).

EwoutH commented 9 months ago

Every behavior could have an interaction dictionary, that could look something like this:

interaction_dict = {
    "Self": {"state1": int, "state2": str, "state3": float},
    "Model": {"state1": int, "state2": str, "state3": float},
    "Agents": {"AgentType1": {"state1": int, "state2": str, "state3": float},
               "AgentType2": {"state1": int, "state2": str, "state3": float}},
}

Example

interaction_dict = {
    "Self": {
        "location": tuple,  # (x, y) coordinates
        "speed": float,     # in km/h
        "destination": str  # e.g., "Home", "Work", "Shop"
    },
    "Model": {
        "current_time": int,         # e.g., in minutes past midnight
        "weather_condition": str,    # e.g., "Sunny", "Rainy", "Snowy"
        "traffic_density": float     # e.g., vehicles per square km
    },
    "Agent": {
        "Vehicle": {
            "fuel_level": float,    # in liters
            "occupancy": int,       # number of passengers
            "type": str             # e.g., "Car", "Bus", "Truck"
        },
        "Pedestrian": {
            "walking_speed": float, # in km/h
            "is_jaywalking": bool,  # True or False
            "destination_type": str # e.g., "Residential", "Commercial"
        },
        "TrafficControl": {
            "signal_status": str,   # e.g., "Red", "Green", "Yellow"
            "signal_timing": int,   # in seconds
            "congestion_level": float # e.g., 0.0 (no congestion) to 1.0 (high congestion)
        }
    }
}