Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMPROVEMENT] From TKinter to PyGame #14

Open
riiswa opened this issue Feb 9, 2023 · 7 comments
Open

[IMPROVEMENT] From TKinter to PyGame #14

riiswa opened this issue Feb 9, 2023 · 7 comments

Comments

@riiswa
Copy link
Owner

riiswa commented Feb 9, 2023

It would be really cool to switch from TKinter to PyGame, especially for performance reasons and to allow the simulation of many more ants!

@emmanuel-ch
Copy link
Contributor

The issue of speed is when we have a high number of pheromones.
Since pheromones stack up on 1 position, maybe we could increase the "intensity" of the existing pheromones instead of creating new ones? It would imply a rework of the functions creating move_tab, but surely will be demanding less efforts!

If you can explain the logic behind the move_tab, find_nest(), pheromones_affinity(), STEP_GRID, then i could give a try to the suggestion above.

@emmanuel-ch
Copy link
Contributor

emmanuel-ch commented Mar 2, 2023

@riiswa I'm working on a workaround using dataframes to store pheromones information, but that implies reworking functions pheromones_affinity and find_nest.

pheromones_affinity:
Can you confirm that the intend is to have HG to store the number of pheromones in the top-left (Haut Gauche) corner of the canvas (relative to ant's position)? (And same for HD, BG, BD)


    HG_o = canvas.find_overlapping(0, 0, ant_coords[0], ant_coords[1])
    HD_o = canvas.find_overlapping(e_w, 0, ant_coords[0], ant_coords[1])
    BG_o = canvas.find_overlapping(0, e_h, ant_coords[0], ant_coords[1])
    BD_o = canvas.find_overlapping(e_w, e_h, ant_coords[0], ant_coords[1])
    HG = len(HG_o) - (2 + sim_args.n_ants)
    HD = len(HD_o) - (2 + sim_args.n_ants)
    BG = len(BG_o) - (2 + sim_args.n_ants)
    BD = len(BD_o) - (2 + sim_args.n_ants)

find_nest:
Is it the same intend?

    HD_o = canvas.find_overlapping(e_w, 0, ant_coords[0], ant_coords[1])
    BG_o = canvas.find_overlapping(0, e_h, ant_coords[0], ant_coords[1])
    BD_o = canvas.find_overlapping(e_w, e_h, ant_coords[0], ant_coords[1])
    HGn = HG_o[0]
    HDn = HD_o[0]
    BGn = BG_o[0]
    BDn = BD_o[0]

    HG = len(HG_o) - 2 - sim_args.n_ants
    HD = len(HD_o) - 2 - sim_args.n_ants
    BG = len(BG_o) - 2 - sim_args.n_ants
    BD = len(BD_o) - 2 - sim_args.n_ants

Thanks for confirming! :)

@dragonpop76
Copy link

Is this still something that's being pursued for this project? Agree that it would be a great way to improve simulation performance

@nickumia
Copy link
Contributor

I agree with @emmanuel-ch.. I don't think the GUI framework is the root cause of performance issues. I was trying to find out what the most performant GUI framework is, but to no avail. I think @emmanuel-ch is correct in saying that the slowdown is attributable to the creation of memory components all of which grow exponentially with the number of ants. To refactor the code and represent each cell as a single unit that has a pheromone value is more trouble than I would put effort towards, but it is the better solution.

I haven't looked at the code in great detail in a while, but the Nest, Food and Ant classes all track position in itself. So if there are 1,000,000 ants, there are 1,000,000 objects with position data as opposed to 400,000 position boxes (assuming the 800x500 grid). It could be further optimized and discretized to a smaller level (i.e. 4,000 for 80x50 grid each box representing 10 sub-cells). Performance optimizations are always a delicate tradeoff.

The best solution that I can think of is a sort of sparse matrix or dictionary lookup of initialized positions. Essentially, you don't need to track 400,000 positions at the start. You can start with just the positions that have a Nest, an Ant or some Food and if the Ant moves to a valid position that hasn't been initialized, then create it. It'll grow to a maximum of the largest size of the m x n grid, but it might never reach the full amount still.

I'm happy to help again if we come up with an accepted solution and break it up into manageable pieces 🏗️

P.S. I was the one who converted the original code into the code fragments you referenced @emmanuel-ch, but I don't know if it was supposed to be (0,0) at the top-left. The general standard for TK is for (0,0) in the top-left though and I don't suspect we changed that default.

References:

@emmanuel-ch
Copy link
Contributor

@nickumia - I have a branch ready with the solution you mentioned: a numpy array storing pheromones. Displaying only the "reduced" version on the screen: 1 circle for each location of pheromone. I'll make a PR for it in the next couple of days.

@riiswa
Copy link
Owner Author

riiswa commented Aug 28, 2023

Thank you for you research @nickumia , and I think you're right, we should save time in the data management, and not on the GUI part.

@emmanuel-ch It could be interesting to see if we can use numba, to have a GPU compatible simulation. I can't wait to see your PR :)

@emmanuel-ch
Copy link
Contributor

Challenge accepted! I'll share my conclusions once the current PR is accepted and we perform additional refactoring - I can still see places where code is suboptimal.

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

No branches or pull requests

4 participants