Your
Candidate Struct
is painful in its omissions.You need something like this:
void free_candidate(struct Candidate* c) { free(c->bitstring); free(c); }
Used like:
[...] for (int i = 0; i < n_strings; i++) { free_candidate(pop[i]); } free(pop); [...]
You can speed this up a bit by adding some early termination logic also:
float prev_best_score = -1.0; int stagnant_epochs = 0; for (int epoch = 0; epoch < n_epochs; epoch++) { // ... Your existing implementation ... if (best->score == prev_best_score) { stagnant_epochs++; if (stagnant_epochs >= MAX_STAGNANT_EPOCHS) { printf("Terminating due to lack of progress.\n"); break; } } else { stagnant_epochs = 0; } prev_best_score = best->score; }
I’m introducing
MAX_STAGNANT_EPOCHS
as a predefined constant that specifies the number of epochs the algorithm should tolerate without improvement.Thanks. I left out free()'s to get the thing working fast, but you’re right, they should be in there.
Nod, I’m leaving out early stopping so all versions are comparable.
Check out evotroch :D genetic algorithms on the gpu using torch, cool project
Very cool! Thanks.
Your C implementation leaks memory.
Noted, thanks. I may swing back around and add some free() calls.
UPDATE: I’ve added an optimized numpy version that is as fast (actually slightly) faster than the naive c version. Yay!
It’s faster because the people writing C for numpy are better than us at writing C 🤣.
For sure!
Wait until you learn numpy is written in C 😉
Python is written in C
C compilers are written in C.
bootstrapping, maybe the first C compiler was created during the big bang 🙄
See C C!
Si!
Argh
C:\dos\run
The ideas is to see the progression as the code is optimized away for readability toward performance.
You’d prefer the files to be named meaningfully? Or you’d prefer to use “git diff” to see changes and have a single copy?
The risk is a new version has a good idea, but is slower. It should not be the canonical version, just a stepping stone.
I think you made the right call. Especially if the intent is to show it to other people.
These guys are pedantic. No way in hell are you going to convince me to go and do git dif in an article/educational post lol.
Or you’d prefer to use “git diff” to see changes and have a single copy?
Yes. Let git do it’s job.
I struggle with the same naming and versioning challenge when doing coding puzzles like Advent of Code. On the one hand I’m slowly improving and optimising my solution by trying different approaches, and doing the usual regular commits on a single file. And on the other hand, it seems like with respect to the context of being code puzzles and exploring ideas, it’s useful to keep all the versions around named like you’ve done here.
I’d love to have a clean way to manage these two layers of versioning together!
Good point.
I used to struggle in the same way with kaggle competitions. Whole parts of my pipeline would change, but wanted/needed to preserve each pipeline independently for ad hoc experimentation. I used parallel dirs in the git repo.
Branches are the answer.
Agreed. My git fu was weak in 2010.