Skip to content

Conversation

@jayash1973
Copy link

#2191 issue

Moved https://github.com/projectmesa/mesa/tree/main/mesa/experimental/devs/examples to mesa examples repository

Created a new, separate folder with wolf_sheep_experimental_devs and epstien_civil_violence_experimental_devs.

Put the model and agent code in agent.py and model.py.

Created an app.py file in which SolaraViz is used.

Created/updated the Readme to describe how the experimental features are used.

the results of the updated examples are below

wolf sheep experiment

@EwoutH
Copy link
Member

EwoutH commented Aug 19, 2024

Let me know when this PR is ready for review!

@EwoutH EwoutH mentioned this pull request Aug 19, 2024
@jayash1973
Copy link
Author

Let me know when this PR is ready for review!

it is ready but dont know why it keeps on showing Import block is un-sorted or un-formatted

@EwoutH
Copy link
Member

EwoutH commented Aug 19, 2024

Let me fix that for you, I have a handy tool for that.

Fix ruff error I001. In this case it wants newlines between external library imports and local imports.

https://docs.astral.sh/ruff/rules/unsorted-imports/
@EwoutH
Copy link
Member

EwoutH commented Aug 19, 2024

That's better! The trick is here is using ruff --fix.

@jayash1973
Copy link
Author

That's better! The trick is here using ruff --fix.

okay will use that next time, so is this okay? or do i still need to make any more changes?

@jayash1973
Copy link
Author

jayash1973 commented Aug 19, 2024

and sorry for taking this long, my device stopped working due to overheating had to get it checked

@EwoutH
Copy link
Member

EwoutH commented Aug 19, 2024

Don't worry about the time.


Somehow the whole DEVS part disappeared again.

image
(left: Your code, right: the code it should be)

Can you explain my process to you? Because I don't understand how these models get changed? Or did you copy the wrong model?

@jayash1973
Copy link
Author

Don't worry about the time.

Somehow the whole DEVS part disappeared again.

image (left: Your code, right: the code it should be)

Can you explain my process to you? Because I don't understand how these models get changed? Or did you copy the wrong model?

The lines of code you are referring to:

def step(self):
    if self.condition == AgentState.ARRESTED:
        self.jail_time_remaining -= 1
        if self.jail_time_remaining <= 0:
            self.release_from_jail()
        return

is used to handle the state of the agent when it is arrested. Here's why this is necessary:

State Management: When an agent is arrested it should not perform the usual actions (like updating neighbors, estimating arrest probability, or moving). Instead, it should remain in jail for a certain period. This code ensures that the agent's state is managed correctly by decrementing the jail time and checking if the agent should be released.

Conditional Execution: The return statement ensures that the rest of the step method is not executed if the agent is in the ARRESTED state. This is crucial because an arrested agent should not perform any actions other than waiting for its jail time to expire.

Release Mechanism: The code checks if the jail time has expired self.jail_time_remaining <= 0. If so, it calls the release_from_jail method to change the agent's state back to QUIESCENT and re-add it to the model's schedule.

Here is the complete step method for better clarity:

def step(self):
    if self.condition == AgentState.ARRESTED:
        self.jail_time_remaining -= 1
        if self.jail_time_remaining <= 0:
            self.release_from_jail()
        return

    self.update_neighbors()
    self.update_estimated_arrest_probability()
    net_risk = self.risk_aversion * self.arrest_probability
    if self.grievance - net_risk > self.threshold:
        self.condition = AgentState.ACTIVE
    else:
        self.condition = AgentState.QUIESCENT
    if self.movement and self.empty_neighbors:
        new_pos = self.random.choice(self.empty_neighbors)
        self.model.grid.move_agent(self, new_pos)

If you were to remove the initial check for the ARRESTED state, the agent would continue to perform actions as if it were not in jail, which would violate the logic of the simulation. The agent needs to be inactive while in jail, and the initial check ensures this behavior.

as for the

    def sent_to_jail(self, jail_time):
        self.model.schedule.remove(self)
        self.condition = AgentState.ARRESTED
        self.jail_time_remaining = jail_time

    def release_from_jail(self):
        self.model.schedule.add(self)
        self.condition = AgentState.QUIESCENT

i used this approach cause

Model Scheduling: The self.model.schedule object is used to manage the scheduling of agents in the simulation. When an agent is arrested, it is removed from the schedule, meaning it will not be activated in subsequent steps until it is released. This ensures that arrested agents do not perform any actions while in jail.

State Management: The agent's condition is explicitly set to AgentState.ARRESTED when it is sent to jail and to AgentState.QUIESCENT when it is released. This clear state management helps in maintaining the correct behavior of the agent based on its condition.

Jail Time Tracking: The jail_time_remaining attribute is used to keep track of how long the agent remains in jail. This attribute is decremented in each step, and when it reaches zero, the agent is released. This approach provides a straightforward way to manage the duration of the jail time.

its consistency with the Model's Scheduling Mechanism: The provided code uses the model's built-in scheduling mechanism self.model.schedule to manage when agents are active. This is consistent with the rest of the code and leverages the existing infrastructure of the simulation framework.

@EwoutH
Copy link
Member

EwoutH commented Aug 19, 2024

Sorry, I put my time and effort in, and once I'm getting LLM answers I can just ask the LLM myself (or even beter, just do it myself).

Talk to me properly, or I'm afraid I have to close the PR.

@EwoutH
Copy link
Member

EwoutH commented Aug 19, 2024

well i did leverage the use of coding assistants to debug and fix some issues

And that's fine. Just don't copy and paste them here if I'm asking real questions and trying to help you.

@jayash1973
Copy link
Author

well i did leverage the use of coding assistants to debug and fix some issues

And that's fine. Just don't copy and paste them here if I'm asking real questions and trying to help you.

okay wont do that again

@jayash1973
Copy link
Author

so should i remove those updated features

    def step(self):
        if self.condition == AgentState.ARRESTED:
            self.jail_time_remaining -= 1
            if self.jail_time_remaining <= 0:
                self.release_from_jail()
            return

        self.update_neighbors()
        self.update_estimated_arrest_probability()
        net_risk = self.risk_aversion * self.arrest_probability
        if self.grievance - net_risk > self.threshold:
            self.condition = AgentState.ACTIVE
        else:
            self.condition = AgentState.QUIESCENT
        if self.movement and self.empty_neighbors:
            new_pos = self.random.choice(self.empty_neighbors)
            self.model.grid.move_agent(self, new_pos)
    def sent_to_jail(self, jail_time):
        self.model.schedule.remove(self)
        self.condition = AgentState.ARRESTED
        self.jail_time_remaining = jail_time

    def release_from_jail(self):
        self.model.schedule.add(self)
        self.condition = AgentState.QUIESCENT

back to

    def step(self):
        """
        Decide whether to activate, then move if applicable.
        """
        self.update_neighbors()
        self.update_estimated_arrest_probability()
        net_risk = self.risk_aversion * self.arrest_probability
        if self.grievance - net_risk > self.threshold:
            self.condition = AgentState.ACTIVE
        else:
            self.condition = AgentState.QUIESCENT
        if self.movement and self.empty_neighbors:
            new_pos = self.random.choice(self.empty_neighbors)
            self.model.grid.move_agent(self, new_pos)
    def sent_to_jail(self, value):
        self.model.active_agents.remove(self)
        self.condition = AgentState.ARRESTED
        self.model.simulator.schedule_event_relative(self.release_from_jail, value)

    def release_from_jail(self):
        self.model.active_agents.add(self)
        self.condition = AgentState.QUIESCENT

this.

note: this is not AI generated

@jayash1973
Copy link
Author

and sorry for providing LLM generated response, its just that the LLM generated a better response than me at explaining why i added those features

@EwoutH
Copy link
Member

EwoutH commented Aug 19, 2024

Sorry, I'm closing this PR, because at this point it's an order of magnitude more work to review these PRs than to do it myself. We're maintaining Mesa on volunteer basis and this is just taking too much time. And I'm sorry, I thought this would have been an easier issue.

Also please read our feedback carefully. A few days ago I wrote:

I'm going to close this PR, to make it clear that this huge monolithic PR is not going forward.

Like I said, I would welcome small, atomic PRs that:

  • Add visualisation to one model at the time

This still applies. I like some of the visualisation code you have written, feel free to add it to either the existing wolfsheep or epstein models that are already here in mesa-examples.

If any other maintainer wants to pick this up feel free to reopen the PR.

@EwoutH EwoutH closed this Aug 19, 2024
@jayash1973
Copy link
Author

okay i will work on that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants