I'm working on a GA and seem to be having problems with the tournament selection. I think this is due to the fact that I'm not comparing what I want to compare (in terms of fitness values)
srand(static_cast <unsigned> (time(0)));
population Pop;
vector<population> popvector;
vector<population> survivors;
population *ptrP;
for (int i = 0; i <= 102; i++)
{
ptrP = new population;
ptrP->generatefit;
ptrP->findfit;
popvector.push_back(*ptrP);
//include finding the persons "overall". WIP
}
cout << "The fit values of the population are listed here: " << endl;
vector<population> ::iterator it; //iterator to print everything in the vector
for (it = popvector.begin(); it != popvector.end(); ++it)
{
it->printinfo();
}
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); // generate a seed for the shuffle process of the vector.
cout << "Beggining selection process" << endl;
shuffle(popvector.begin(), popvector.end(), std::default_random_engine(seed));
//Shuffling done to randomize the parents I will be taking.
// I also want want to pick consecutive parents
for (int i = 0; i <= 102; i = i + 3)
{
if (popvector[i] >= popvector[i++]);
}
}
Now what I think my problem is, is that when im trying to compare the Overall values (Not found yet, working on how to properly model them to give me accurate Overall fitness values) I'm not comparing what I should be.
I'm thinking that once I find the persons "Overall" I should store it in a Float vector and proceed from there, but I'm unsure if this is the right way to proceed if I wish to create a new "parent" pool, since (I think) the "parent pool" has to be part of my population class.
Any feedback is appreciated.
srand(static_cast <unsigned> (time(0)));
This is useless: you're calling std::shuffle in a form not based on std::rand:
shuffle(popvector.begin(), popvector.end(), std::default_random_engine(seed));
If somewhere else in the program you need to generate random numbers, do it via functions / distributions / engines in random pseudo-random number generation library (do not use std::rand).
Also consider that, for debugging purpose, you should have a way to initialize the random engine with a fixed seed (debug needs repeatable results).
for (int i = 0; i <= 102; i++)
Do not use magic numbers.
Why 102? If it's the population size, store it in a constant / variable (populationSize?), document the variable use and "enjoy" the fact that when you need to change the value you haven't to remember the locations where it's used (just in this simple snippet there are two distinct use points).
Also consider that the population size is one of those parameters you need to change quite often in GA.
ptrP = new population;
ptrP->generatefit;
ptrP->findfit;
popvector.push_back(*ptrP);
Absolutely consider Sam Varshavchik's and paddy's remarks.
for (int i = 0; i <= 102; i = i + 3)
{
if (popvector[i] >= popvector[i++]);
// ...
Generally it's not a good practice to change the index variable inside the body of a for loop (in some languages, not C / C++, the loop variable is immutable within the scope of the loop body).
Here you also have an undefined behaviour:
popvector[i] >= popvector[i++]
is equivalent to
operator>=(popvector[i], popvector[i++])
The order that function parameters are evaluated is unspecified. So you may have:
auto a = popvector[i];
auto b = popvector[i++];
operator>=(a, b); // i.e. popvector[i] >= popvector[i]
or
auto b = popvector[i++];
auto a = popvector[i];
operator>=(a, b); // i.e. popvector[i + 1] >= popvector[i]
Both cases are wrong.
In the first case you're comparing the same elements and the expression is always true.
In the second case the comparison probably is the opposite of what you were thinking.
Take a look at:
Undefined behavior and sequence points
What are all the common undefined behaviours that a C++ programmer should know about?
and always compile source code with -Wall -Wextra (or their equivalent).
I'm not sure to correctly understand the role of the class population. It may be that the name is misleading.
Other questions / answers you could find interesting:
C++: "std::endl" vs "\n"
http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/ (the section about premature pessimization)
Related
I am trying to do some Monte Carlo simulation, and as it is with this kind of simulation, it requires a lot of iterations, even for the smallest system. Now I want to do some tweaks with my previous code but it increases the wall time or running time, by 10 fold, which makes a week of calculations to more than two months. I wonder whether I am doing the most efficient way to do the simulation.
Before that, I was using a set of fixed intervals to get the properties of the simulations, but now I want to record a set of random intervals to get the system information as it is the most logical thing to do. However I don't know how to do it.
The code that I was using was basically something like that:
for(long long int it=0; it<numIterations; ++it)
{
if((numIterations>=10) && (it%1000==0))
{
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile1000, it);
}
}
As you see, before the tweaks made it was going through the simulation and only record the data, every 1000th iterations.
Now I want to do something like this
for(long long int it=0; it<numIterations; ++it)
{
for(int j = 1; j <= n_graph_points; ++j){
for (int i = 0; i < n_data_per_graph_points; ++i){
if (it == initial_position_array[j][i] || it == (initial_position_array[j][i] + delta_time_arr[j])) {
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile, it);
}
}
}
}
In this part, the initial position array is just an array with lots of random numbers. The two for loop inside of each other checks every iteration and if the iterations is equal to that random number, it starts recording. I know this is not the best method as it is checking lots of iterations that are not necessary. But, I don't know how can I improve my code. I am a little helpless at this point, so any comment would be appreciated
This does not answer the implied question
[What is the] most efficient way to have [an] if statement in C++ (all of them should be equivalent), but
Supposing varying intervals between exports were logical, how do I code that adequately?
Keep a sane Monte Carlo control, initialise a nextExport variable to a random value to your liking, and whenever it equals nextExport, export and increase nextExport by the next random interval.
if (it == initial_position_array[j][i] || it == (initial_position_array[j][i] + delta_time_arr[j]))
you can use references for both expressions.(please use meaningful names as per your convinience)
int& i_p_a = initial_position_array[j][i];
int& i_p_a_d = (initial_position_array[j][i] + delta_time_arr[j]);
now you final if statement will be readable and maintainable.
if (it == i_p_a || it == i_p_a_d) {
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile, it);
}
My assignment involves writing several classes that will work together to randomly sort 28 dominoes for the user and display them. The main trouble I'm having so far is just creating the dominoes without any duplication. If you're familiar with dominoes, you know that each half of them are either blank or have 1-6 dots. Basically I'll have a dynamic array of 28 unique structs (dominoes) but I'm just stuck on generating these dominoes without having identical ones. I was thinking of using FOR loops to just go through and assign values within each struct but I figured there had to be some easier way.
This is what I have so far below; I know it's not much but I can't and don't want to go on with writing methods for sorting and display without getting this right first.
class CDominoes{
public:
struct Data
{
int top;
int bottom;
Data()
{
top = 0;
bottom = 0;
}
} domino[28];
//methods to assign spots to halves
};
The simplest solution is to generate, and then shuffle. To generate, you need to avoid wasting time generating duplicates. For example, (4,5) is the same as (5,4), so you don't want to generate both. That means that your inner loop should always begin at the current value of the outer loop. In so doing, you'll never repeat a combination. Here's an example:
int main () {
for( int t = 0; t <= 6; ++t ) {
for( int b = t; b <= 6; ++b ) {
std::cout << "(" << t << "," << b << ")\n";
}
}
return 0;
}
In this example, we're considering '0' to be the same as a blank domino.
Next, instead of printing these, put them into a random access container such as std::array or std::vector, and then use std::shuffle to shuffle your container.
OK, so the goal of this was to write some code for the Fibonacci numbers itself then take those numbers figure out which ones were even then add those specific numbers together. Everything works except I tried and tried to figure out a way to add the numbers up, but I always get errors and am stumped as of how to add them together. I looked elsewhere but they were all asking for all the elements in the vector. Not specific ones drawn out of an if statement.
P.S. I know system("pause") is bad but i tried a few other options but sometimes they work and sometimes they don't and I am not sure why. Such as cin.get().
P.S.S I am also new to programming my own stuff so I have limited resources as far as what I know already and will appreciate any ways of how I might "improve" my program to make it work more fluently. I also take criticism well so please do.
#include "../../std_lib_facilities.h"
int main(){
vector<int>Fibonacci;
int one = 0;
int two = 1;
int three = 0;
int i = 0;
while (i < 4000000){
i += three;
three = two + one; one = two; two = three;
cout << three << ", ";
Fibonacci.push_back(three);
//all of the above is to produce the Fibonacci number sequence which starts with 1, 2 and adds the previous one to the next so on and so forth.
//bellow is my attempt and taking those numbers and testing for evenness or oddness and then adding the even ones together for one single number.
}
cout << endl;
//go through all points in the vector Fibonacci and execute code for each point
for (i = 0; i <= 31; ++i)
if (Fibonacci.at(i) % 2 == 0)//is Fibonacci.at(i) even?
cout << Fibonacci.at(i) << endl;//how to get these numbers to add up to one single sum
system("pause");
}
Just do it by hand. That is loop over the whole array and and keep track of the cumulative sum.
int accumulator = 0; // Careful, this might Overflow if `int` is not big enough.
for (i = 0; i <= 31; i ++) {
int fib = Fibonacci.at(i);
if(fib % 2)
continue;
cout << fib << endl;//how to get these numbers to add up to one single sum
accumulator += fib;
}
// now do what you want with "accumulator".
Be careful about this big methematical series, they can explode really fast. In your case I think the calulation will just about work with 32-bit integers. Best to use 64-bit or even better, a propery BigNum class.
In addition to the answer by Adrian Ratnapala, I want to encourage you to use algorithms where possible. This expresses your intent clearly and avoids subtle bugs introduced by mis-using iterators, indexing variables and what have you.
const auto addIfEven = [](int a, int b){ return (b % 2) ? a : a + b; };
const auto result = accumulate(begin(Fibonacci), end(Fibonacci), 0, addIfEven);
Note that I used a lambda which is a C++11 feature. Not all compilers support this yet, but most modern ones do. You can always define a function instead of a lambda and you don't have to create a temporary function pointer like addIfEven, you can also pass the lambda directly to the algorithm.
If you have trouble understanding any of this, don't worry, I just want to point you into the "right" direction. The other answers are fine as well, it's just the kind of code which gets hard to maintain once you work in a team or have a large codebase.
Not sure what you're after...
but
int sum=0; // or long or double...
for (i = 0; i <= 31; ++i)
if (Fibonacci.at(i) % 2 == 0) {//is Fibonacci.at(i) even?
cout << Fibonacci.at(i) << endl;//how to get these numbers to add up to one single sum
sum+=Fibonacci.at(i);
}
// whatever
}
I'm doing this slot machine game where a 3x3 2D-array is being generated with random letters.
I have successfully made the game work as I want but I wonder if you have any tips on how I can optimize or improve my code.
What I've gotten my code to do:
Generate an 2D-array (3x3) and randomly assign chars out of 3
letters.
An "if" that will compare and see what elements in the array belong
to each other (same char next to eachother for getting
columns/rows/diagonals).
An "if else" that will take total amount of columns/rows/diagonals
and make a prize out of it, depending on total amounts of row in the
slot machine and the bet.
So I'm now wondering if you have any suggestions on how I can improve the "if" code where the program checks if there are any rows/columns/diagonals? The game works as it should but I just wonder if there's any way of optimizing it - Perhaps with a "for-loop"?
I also wonder if you have any tips on the "prize" code where the code calculates total amout of rows/columns/diagonals and multiplies that with the bet.
I mean, there must be a way to optimize this. If I was to do a 100x100 array, the code where the elements are compared would be awfully long :)
I'm new to C++ (this is a course) so I'm looking forward to optimize this.
PS! I'm not asking for a solution but rather suggestions/tips of methods I can use to optimize it.
This is a homework so no solutions please, only suggestions/tips!
My code for the array comparison and prize calculation:
To optimize, running a profiler would give you a lot of information. If you're talking about general guidelines to optimizing your application, here are some:
1 - use threads to process in parallel
2 - reduce cache miss by keeping the data properly aligned depending on the processing done on it. For instance, if you need to use the speed to process the position, keeping them both near each other in memory will reduce cache-misses.
ie:
struct Particle
{
float position;
float speed;
};
Particle particles[NUM_PARTICLES];
vs
float positions[NUM_PARTICLES];
float speeds[NUM_PARTICLES];
3- Don't process what you don't need to process or user can't see. For instance, some stuff may not affect the current states - no need to process it (in graphics, we use scene management like octtrees but the same applies to all - if you don't need it, don't process it).
4- Reduce the amount of floating point operations.
See this post as well - it provices with some good C++ references for optimizations: C++ Optimization Techniques.
About optimizing:
Don't optimize prematurely - it won't help anything. I'm too lazy to write about that, but search internet, read "Code Complete" and "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices" books.
Don't waste - if optimization won't take more time and is at same readability level, than you can use it.
Optimize AFTER a speed problem arise.
About your problem:
You are absolutely right that there should be better ways to write a code. What you wrote is what workers do, but you need to be smart programmer to make it more easy.
But what you need is more knowledge about language.
Yes, there is a looping possibility for C++. For example following code checks whether a line contains same values:
const int rowCount = 3; // Number of rows
const int colCount = 3; // Number of columns
// Variable for counting same rows
int sameRowsCount = 0;
// Following line is loop: first it sets variable row to 0
// and for each pass it increments it until rowCount is reached
for(int row = 0; row < rowCount; ++row)
{
// This variable stores whether the row contains same values.
// At beginning we assume that it does.
bool isSame = true;
// Now we will check each column in current row. Note that
// we begin with 1 and not 0 - at 0 position is value which
// we check against all others.
for(int col = 1; (col < colCount) && isSame; ++col)
{
if(matrix[0] != matrix[col])
{
// We found different values
isSame = false;
}
}
// If row contains same values, isSame remained true and
// we increment same-rows counter.
if(isSame)
{
++sameRowsCount;
}
}
cout << "Number of same rows: " << sameRowsCount << "." << endl;
Depends on the array size(s) as you mentioned. With small arrays the if statements may be more efficient than using a loop (or two nested) to iterate over all the elements (this is also called 'loop unrolling' and is considered a performance improvement).
To 'optimize' (I'd better say generalize) your code for any array sizes you should use for loops of course to iterate over the x/y indices.
Completed code:
//Check all horiztonal and vertical locations
for(int i = 0; i <= 2; i++)
{
if(matris[i][0] == matris[i][1] && matris[i][1] == matris[i][2])
rows++;
if(matris[0][i] == matris[1][i] && matris[1][i] == matris[2][i])
rows++;
}
//Now check diagonals
if(matris[0][0] == matris[1][1] && matris[1][1] == matris[2][2])
if(matris[0][2] == matris[1][1] && matris[1][1] == matris[2][0])
//Calculate prize
prize = g_satsning*(1 << rows);
In terms of speed, what you have is not going to be inefficient. If you are looking to generalize the code and make it scalable (e.g. if you wanted to add 2 more rows/columns), there are several things you could do (e.g. looping and a more mathematical form of prize calculation).
The looping has already been discussed, but the prize calculation could be simplified a bit using something like the following:
if (rows > 0 && rows < SOMEMAXIMUMVALUE)
{
prize = g_satsning * (1 << rows);
}
else
{
prize = 0;
}
Since your multiplier is an exponent of 2, the math is fairly straight forward. SOMEMAXIMUMVALUE should be declared to be the maximum number of matching rows you expect. For a 3x3 setup, there would be 8 potential matches (3 rows, 3 columns, 2 diagonals), so SOMEMAXIMUMVALUE should be set to 8.
I was implementing a recursive function with memoization for speed ups. The point of the program is as follows:
I shuffle a deck of cards (with an equal number of red and black
cards) and start dealing them face up.
After any card you can say “stop”, at which point I pay you $1 for
every red card dealt and you pay me $1 for every black card dealt.
What is your optimal strategy, and how much would you pay to play
this game?
My recursive function is as follows:
double Game::Value_of_game(double number_of_red_cards, double number_of_black_cards)
{
double value, key;
if(number_of_red_cards == 0)
{
Card_values.insert(Card_values.begin(), pair<double, double> (Key_hash_table(number_of_red_cards, number_of_black_cards), number_of_black_cards));
return number_of_black_cards;
}
else if(number_of_black_cards == 0)
{
Card_values.insert(Card_values.begin(), pair<double, double> (Key_hash_table(number_of_red_cards, number_of_black_cards), 0));
return 0;
}
card_iter = Card_values.find(Key_hash_table(number_of_red_cards, number_of_black_cards));
if(card_iter != Card_values.end())
{
cout << endl << "Debug: [" << number_of_red_cards << ", " << number_of_black_cards << "] and value = " << card_iter->second << endl;
return card_iter->second;
}
else
{
number_of_total_cards = number_of_red_cards + number_of_black_cards;
prob_red_card = number_of_red_cards/number_of_total_cards;
prob_black_card = number_of_black_cards/number_of_total_cards;
value = max(((prob_red_card*Value_of_game(number_of_red_cards - 1, number_of_black_cards)) +
(prob_black_card*Value_of_game(number_of_red_cards, number_of_black_cards - 1))),
(number_of_black_cards - number_of_red_cards));
cout << "Check: value = " << value << endl;
Card_values.insert(Card_values.begin(), pair<double, double> (Key_hash_table(number_of_red_cards, number_of_black_cards), value));
card_iter = Card_values.find(Key_hash_table(number_of_red_cards , number_of_black_cards ));
if(card_iter != Card_values.end());
return card_iter->second;
}
}
double Game::Key_hash_table(double number_of_red_cards, double number_of_black_cards)
{
double key = number_of_red_cards + (number_of_black_cards*91);
return key;
}
The third if statement is the "memoization" part of the code, it stores all the necessary values. The values that are kept in the map can be thought of as a matrix, these values will correspond to a certain #red cards and #black cards. What is really werid is that when I execute the code for 8 cards in total (4 blacks and 4 reds), I get an incorrect answer. But when I execute the code for 10 cards, my answer is wrong, but now my answer for 4 blacks and 4 reds are correct (8 cards)! Same can be said for 12 cards, where I get the wrong answer for 12 cards, but the correct answer for 10 cards, so on and so forth. There is some bug in the code, however, I can't figure it out.
Nobody actually answered this question with an answer. So I will give it a try, though nneonneo actually put his or her finger on the likely source of your problem.
The first problem that's probably not actually a problem in this case, but sticks out like a sore thumb... you are using double to hold a value that you mostly treat as an integer. In this case, on most systems, this is probably OK. But as a general practice, it is very bad. In particular because you check if a double is exactly equal to 0. It probably will be as, on most systems, with most compilers, a double can hold integers values up to a fairly large size with perfect precision as long as you restrict yourself to adding, subtracting and multiplying by other integers or doubles masquerading as integers to get a new value.
But, that's likely not the source of the error you're seeing, it's just trips every good programmer's alarm bells for smelly code. It should be fixed. The only time you really need them to be doubles is when you're calculating the relative probability of red or black.
And that brings me to the thing that probably is your problem. You have these two statements in your code:
number_of_total_cards = number_of_red_cards + number_of_black_cards;
prob_red_card = number_of_red_cards/number_of_total_cards;
prob_black_card = number_of_black_cards/number_of_total_cards;
which, of course, should read:
number_of_total_cards = number_of_red_cards + number_of_black_cards;
prob_red_card = number_of_red_cards/double(number_of_total_cards);
prob_black_card = number_of_black_cards/double(number_of_total_cards);
because you've been a good programmer and declared those variables as integers.
Presumably prob_red_card and prob_black_card are variables of type double. But they are not declared anywhere in the code you show us. This means that no matter where they are declared, or what their types are, they must be effectively shared by all sub-calls in the recursive call tree for Game::Value_of_game.
The is almost certainly not what you want. It makes it extremely difficult to reason about what values those variables have and what those values represent during any given call in the recursive call tree for your function. They really have to be local variables in order for the algorithm to be tractable to analyze. Luckily, they seem to only be used within the else clause of a particular if statement. So they can be declared when they are initially assigned values. Here is probably what this code should read:
unsigned const int number_of_total_cards = number_of_red_cards + number_of_black_cards;
const double prob_red_card = number_of_red_cards/double(number_of_total_cards);
const double prob_black_card = number_of_black_cards/double(number_of_total_cards);
Note that I also declare them const. It is good practice to declare any variable who's value you don't expect to change during the lifetime of the variable as const. It helps you write code that is more correct by asking the compiler to tell you when you accidentally write code that is incorrect. It also can help the compiler generate better code, though in this case even a trivial analysis of the code reveals that they are not modified during their lifetimes and can be treated as const, so most decent optimizers will essentially put the const in for you for the purposes of code optimization, though that still will not give you the benefit of having the compiler tell you if you accidentally use them in a non-const way.