most efficient way to have a if statement in C++ - c++

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);
}

Related

Comparing Values in a Single Vector

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)

Efficiency of an algorithm for scrambled input

I am currently writing a program, its done for the most part, in CPP that takes in a file, with numbered indices and then pushes out a scrambled quiz based on the initial input, so that no two are, theroretically, the same.
This is the code
// There has to be a more efficient way of doing this...
for (int tempCounter(inputCounter);
inputCounter != 0;
/* Blank on Purpose*/) {
randInput = (rand() % tempCounter) + 1;
inputIter = find (scrambledArray.begin(),
scrambledArray.end(),
randInput);
// Checks if the value passed in is within the given vector, no duplicates.
if (inputIter == scrambledArray.end()) {
--inputCounter;
scrambledArray.push_back(randInput);
}
}
The first comment states my problem. It will not happen, under normal circumstances, but what about if this were being applied to a larger application standpoint. This works, but it is highly inefficient should the user want to scramble 10000 or so results. I feel as if in that point this would be highly inefficient.
I'm not speaking about the efficiency of the code, as in shortening some sequences and compacting it to make it a bit prettier, I was more or less teaching someone, and upon getting to this point I came to the conclusion that this could be done in a way better manner, just don't know which way it could be...
So you want just the numbers 1..N shuffled? Yes, there is a more efficient way of doing that. You can use std::iota to construct your vector:
// first, construct your vector:
std::vector<int> scrambled(N);
std::iota(scrambled.begin(), scrambled.end(), 1);
And then std::shuffle it:
std::shuffle(scrambled.begin(), scrambled.end(),
std::mt19937{std::random_device{}()});
If you don't have C++11, the above would look like:
std::vector<int> scrambled;
scrambled.reserve(N);
for (int i = 1; i <= N; ++i) {
scrambled.push_back(i);
}
std::random_shuffle(scrambled.begin(), scrambled.end());

Is there any way of optimising this function?

This piece of code seems to be the worst offender in terms of time in my program. What my program is trying to do find the minimum number of individual "nodes" required to satisfy a network with two constraints:
Each node must connect to x number of other nodes
Each node must have y degrees of separation between it and each of the nodes it's connected to.
However for values of x greater than 600 this task takes a very long time, the task is on the order of exponential anyway so I expect it to take forever at some point but that also means that if any small changes could be made here it'd speed up the entire program by alot.
uniint = unsigned long long int (64-bit)
network is a vector of the form vector<vector<uniint>>
The piece of code:
/* Checks if id2 is in id1's list of connections */
inline bool CheckIfInList (uniint id1, uniint id2)
{
uniint id1size = network[id1].size();
for (uniint itr = 0; itr < id1size; ++itr)
{
if (network[id1][itr] == id2)
{
return true;
}
}
return false;
}
The only way is to sort the network[id1] array when you build it.
If you arrive here with a sorted array you can easiliy find, if exists, what you are looking for using a dichotomic search.
Use std::map or std::unordered_map for fast search. I guess it's impossible to MICRO optimize this code, std::vector is cool. But not for 600 elements search.
I'm guessing CheckIfInList() is called in a loop? Perhaps a vector is not the best choice, you could try vector<set<uniint>>. This will give you O(log n) for a look up of the inner collection instead of O(n)
For quick microoptimization, check whether your compiler optimizes the multiple calls to network[id1] away. If not, that is where you loose a lot of time, so remember the address:
vector<uniint>& connectedNodes = network[id1];
uniint id1size = connectedNodes.size();
for (uniint itr = 0; itr < id1size; ++itr)
{
if (connectedNodes[itr] == id2)
{
return true;
}
}
return false;
If your compiler already took care of that, I'm afraid that there's not much you can micro optimize about this method. The only real optimization can be achieved on the algorithmic level, starting with sorting the neighbour lists, moving on to using unordered_map<> instead of vector<>, and ending with asking yourself whether you can't somehow reduce the number of calls to CheckIfInList().
This is not as effective as HAL9000's suggestion, and is good for cases when you have an unsorted list/array. What you can do is to ask less question in each iteration if you put the value you looking for at the end of the vector.
uniint id1size = network[id1].size();
network[id1][id1size] = id2;
for (uniint itr = 0; network[id1][itr] == id2; ++itr);
//if itr != id1size return true else flase....
need to add checks if the last member in the vector was your id2.
This way you don't need to ask each time whether you get to the end of the list.

Optimize my code? C++ Compare arrays & calculate prize

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.

no duplicate function for a lottery program

right now im trying to make a function that checks to see if the user’s selection is already in the array , and if it does itll tell you to choose a diff number. how can i do this?
Do you mean something like this?
bool CheckNumberIsValid()
{
for(int i = 0 ; i < array_length; ++i)
{
if(array[i] == user_selection)
return false;
}
return true;
}
That should give you a clue, at least.
What's wrong with std::find? If you get the end iterator back, the
value isn't in the array; otherwise, it is. Or if this is homework, and
you're not allowed to use the standard library, a simple while loop
should do the trick: this is a standard linear search, algorithms for
which can be found anywhere. (On the other hand, some of the articles
which pop up when searching with Google are pretty bad. You really
should use the standard implementation:
Iterator
find( Iterator begin, Iterator end, ValueType target )
{
while ( begin != end && *begin != target )
++ begin;
return begin;
}
Simple, effective, and proven to work.)
[added post factum]Oh, homework tag. Ah well, it won't really benefit you that much then, still - I'll leave my answer since it can be of some use to others browsing through SO.
If you'd need to have lots of unique random numbers in a range - say 45000 random numbers from 0..45100 - then you should see how this is going to get problematic using the approach of:
while (size_of_range > v.size()) {
int n = // get random
if ( /* n is not already in v */ ) {
v.push_back(n);
}
}
If the size of the pool and the range you want to get are close, and the pool size is not a very small integer - it'll get harder and harder to get a random number that wasn't already put in the vector/array.
In that case, you'll be much better of using std::vector (in <vector>) and std::random_shuffle (in <algorithm>):
unsigned short start = 10; // the minimum value of a pool
unsigned short step = 1; // for 10,11,12,13,14... values in the vector
// initialize the pool of 45100 numbers
std::vector<unsigned long> pool(45100);
for (unsigned long i = 0, j = start; i < pool.size(); ++i, j += step) {
pool[i] = j;
}
// get 45000 numbers from the pool without repetitions
std::random_shuffle(pool.begin(), pool.end());
return std::vector<unsigned long>(pool.begin(), pool.begin() + 45000);
You can obviously use any type, but you'll need to initialize the vector accordingly, so it'd contain all possible values you want.
Note that the memory overhead probably won't really matter if you really need almost all of the numbers in the pool, and you'll get good performance. Using rand() and checking will take a lot of time, and if your RAND_MAX is equal 32767 then it'd be an infinite loop.
The memory overhead is however noticeable if you only need few of those values. The first approach would usually be faster then.
If it really needs to be the array you need to iterate or use find function from algorithm header. Well, I would suggest you go for putting the numbers in a set as the look up is fast in sets and handy using set::find function
ref: stl set
These are some of the steps (in pseudo-code since this is a homework question) on how you may get around to doing this:
Get user to enter a new number.
If the number entered is the first, push it to the vector anyway.
Sort the contents of the vector in case size is > 1.
Ask user to enter the number.
Perform a binary search on the contents to see if the number was entered.
If number is unique, push it into vector. If not unique, ask again.
Go to step 3.
HTH,
Sriram.