Overwriting vector<vector<> > and segmentation fault - c++

I'm trying to write a program in which at each step of a loop I create an adjacency list representing a graph that changes in time.
Here's the code:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <algorithm>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/exponential_distribution.hpp>
using namespace std;
using std::vector;
typedef boost::mt19937_64 ENG; // use Mersenne Twister 19937 as PRNG engine
typedef boost::uniform_int<> DIST_INT; // define uniform distribution of integers
typedef boost::uniform_real<> DIST_REAL; // define uniform distribution of reals on [0,1)
typedef boost::exponential_distribution<> DIST_EXP; // define exponential distribution
typedef boost::variate_generator<ENG,DIST_INT> VARIATE_INT;
typedef boost::variate_generator<ENG,DIST_REAL> VARIATE_REAL;
typedef boost::variate_generator<ENG,DIST_EXP> VARIATE_EXP;
int main()
{
const unsigned int random_seed = time(NULL);
// ======= initialize BOOST machines
ENG eng(random_seed);
DIST_INT dist_int;
DIST_REAL dist_rand(0,1);
DIST_EXP dist_exp;
VARIATE_INT randint(eng,dist_int); //random integer. use as: randint(N)
VARIATE_REAL rand(eng,dist_rand); //random float on [0,1[. use as: rand()
VARIATE_EXP randexp(eng,dist_exp); //random exponentially distributed float.
int N = 500, Tmax=200000, v, w;
float p = 0.2, s;
vector<vector<int> > contact_list;
for(int i = 0; i < 200000; i++)
{
contact_list.resize(N, vector<int>());
v = 1;
w = -1;
while(v < N)
{
s = rand();
w += 1 + int(log(1-s)/log(1-p));
while((w >= v) && (v < N))
{
w = w - v;
v += 1;
}
if (v < N)
{
contact_list[v].push_back(w);
contact_list[w].push_back(v);
}
}
}
}
However at some point I get segmentation fault. In fact I think this may not be the correct way to overwrite a vector. I also add that I would like to change N_nodes at each step. Any help is appreciated!

For the segmentation fault part you can use Valgrind to try and find out what operation in your code is writing at an invalid location.
Also you can catch Segmantation fault, with the use of signal, but it's not a good practice to catch a segmentation fault

Related

Creating a SET then populating the set with 200 numbers between 10000 + 1, then proceeding to print out each number that is even inside of the set

#include <iostream>
#include <set>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
//Create a set object to store a set of 200 randomly generated numbers from 1 to 10000. Use the for_each function and an anonymous function to display all the even numbers in the set.
using namespace std;
template <typename t>
void prints(t even) {
void prints(t even) {
if (even % 2) == 0;
cout << "All the even numbers in the set are: " << even;
}
}
int main()
{
srand(time(0));
set<int> nums;
for (int i = 0; i < 200; i++) {
nums.insert(rand() % 10000 + 1);
}
int gt50 = count_if(nums.begin(), nums.end(), [](int n) {return (n % 2) == 0}); // this is the issue it says I need ;, but when I put it nothing works.
for_each(nums.begin(), nums.end(), prints<int>);
}
I do not understand why, at the end of line 32 it is asking me to Implement the ; command to end of a line when I do so it still proceeds to give me the same issue. Regardless I don't understand why thats doing what its doing as I've used my debugger but cannot find anything out.
If you run your compiler, it will show you several errors:
So, the compiler tells you the problem and where it is.
Then, after removing they problematic issues and correcting semantic bug in the for loops condition, you will get:
#include <iostream>
#include <set>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
//Create a set object to store a set of 200 randomly generated numbers from 1 to 10000. Use the for_each function and an anonymous function to display all the even numbers in the set.
using namespace std;
template <typename t>
void prints(t even) {
if ((even % 2) == 0)
cout << even << '\n';
}
int main()
{
srand((unsigned int)time(0));
set<int> nums;
for (int i = 0; nums.size() < 200; i++) {
nums.insert(rand() % 10000 + 1);
}
int gt50 = count_if(nums.begin(), nums.end(), [](int n) {return (n % 2) == 0; }); // this is the issue it says I need ;, but when I put it nothing works.
for_each(nums.begin(), nums.end(), prints<int>);
}
This will work.

generate random numbers and put them in an array

I'm looking to write a little dice game called Farkle (you may know it from Kingdom come delivarance) in C++ but I'm still learning, so I have some trouble with it.
atm I'm trying to roll 6 dice and put every rolled number in an array to be able to work with it afterwards. everything seem to work fine but Visual Studio ist outputting this error Code:
Run-Time Check Failure #2 - Stack around the variable 'die' was corrupted.
this is my code:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
void dice() {
int die[5];
int i = 1;
while (i <= 6) {
die[i] = rand() % 6 + 1;
cout << die[i];
i++;
}
}
int main()
{
srand(time(NULL));
dice();
system("STOP");
return 0;
}
is ths actually the right approach for this kind of programm?
No, a better way to generate uniformly distributed random numbers would be
#include <random>
#include <algorithm>
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> d6(1, 6); // {1, 2, 3, 4, 5, 6} with equal probability
int die[5];
std::generate(die, die + 5, [&gen, &d6](){ return d6(gen); });
If you were generating multiple sets of 5d6, you can re-use the same gen rather than re-initialising it each time
As others pointed out. Your error stems from using a too small array. This post will be more about your code being more like C.
It is more idiomatic in C++ to use std::array instead of raw arrays.
Also it is recommended not to use rand() since it produces bad random numbers and by using the modulo operation you are introducing additional bias to you random numbers. Instead one should use the classes from the <random> header.
To make the code even more readable you could try to use the functions from the <algorithm> to replace you loops by named algorithms.
This leads to following code:
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <random>
void dice() {
std::array<int, 6> die;
std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution<int> dice_roll{1, 6};
std::generate(begin(die), end(die), [&] { return dice_roll(gen); });
std::copy(begin(die), end(die), std::ostream_iterator<int>{std::cout});
}
int main() {
dice();
std::cin.get();
}
You have 2 problems in your code:
The size of your array is 5, but you access 6 indices (1 to 6), you can avoid this by changing the <= to < in the condition.
The indices of an array in C++ start with 0, but you start with 1. You can fix that if you change each die[i] to die[i-1] in your code.
Another approach (fixing both problems) would be to initialize i=0 and go with while (i < 5)
index i should be from 0 to 5, not 1 to 6.
It's obvious that when i = 6, it run out of the range of dice which made an error.
Edit these lines:
int i = 0;
while (i <= 5) {
....
Try this code :
#include <iostream>
#include <cstdlib>
#include <ctime>
void populateArray( int ar[], /*const*/ int n )
{
for( int i = 0 ; i < n ; ++i ) ar[i] = std::rand() % 50 + 1 ;
}
int main()
{
// http://en.cppreference.com/w/cpp/numeric/random/srand
std::srand( std::time(nullptr) ) ; // **** important ****
const int ARRAY_SIZE = 50;
int ar[ARRAY_SIZE] = {0} ;
populateArray( ar, ARRAY_SIZE ) ;
for( int v : ar ) std::cout << v << ' ' ;
}

How to speed up a C++ sparse matrix manipulation?

I have a small script for manipulating a sparse matrix in C++. It works perfectly fine except taking too much time. Since I'm doing this manipulation over and over, it is critical to speed it up. I appreciate any idea.Thanks
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <iostream> /* cout, fixed, scientific */
#include <string>
#include <cmath>
#include <vector>
#include <list>
#include <string>
#include <sstream> /* SJW 08/09/2010 */
#include <fstream>
#include <Eigen/Dense>
#include <Eigen/Sparse>
using namespace Eigen;
using namespace std;
SparseMatrix<double> MatMaker (int n1, int n2, double prob)
{
MatrixXd A = (MatrixXd::Random(n1, n2) + MatrixXd::Ones(n1, n2))/2;
A = (A.array() > prob).select(0, A);
return A.sparseView();
}
////////////////This needs to be optimized/////////////////////
int SD_func(SparseMatrix<double> &W, VectorXd &STvec, SparseMatrix<double> &Wo, int tauR, int tauD)
{
W = W + 1/tauR*(Wo - W);
for (int k = 0; k < W.outerSize(); ++k)
for (SparseMatrix<double>::InnerIterator it(W, k); it; ++it)
W.coeffRef(it.row(),it.col()) = it.value() * (1-STvec(it.col())/tauD);
return 1;
}
int main ()
{
SparseMatrix<double> Wo = MatMaker(5000, 5000, 0.1);
SparseMatrix<double> W = MatMaker(5000, 5000, 0.1);
VectorXd STvec = VectorXd::Random(5000);
clock_t tsd1,tsd2;
float Timesd = 0.0;
tsd1 = clock();
///////////////////////////////// Any way to speed up this function???????
SD_func(W, STvec, Wo, 8000, 50);
//////////////////////////////// ??????????
tsd2 = clock();
Timesd += (tsd2 - tsd1);
cout<<"SD time: " << Timesd / CLOCKS_PER_SEC << " s" << endl;
return 0;
}
The most critical performance improvement (IMO) you can make is to not use W.coeffRef(it.row(),it.col()). It performs a binary search in W for the element each time. As you are already using SparseMatrix<double>::InnerIterator it(W, k); it is very simple to change your function to skip the binary search:
int SD_func_2(SparseMatrix<double> &W, VectorXd &STvec, SparseMatrix<double> &Wo, int tauR, int tauD)
{
W = W + 1/tauR*(Wo - W);
double tauDInv = 1./tauD;
for (int k = 0; k < W.outerSize(); ++k)
for (SparseMatrix<double>::InnerIterator it(W, k); it; ++it)
it.valueRef() *= (1-STvec(it.col())*tauDInv);
return 1;
}
This results in a roughly x3 speedup. Note that I've incorporated #dshin's comment that multiplying is faster than division, however the performance improvement is about 90% removing the binary search, 10% multiplication vs. division.

Segmentation fault in c++ code unable to find reason

I am getting segmentation for the last test case (Don't know what it is ) while solving the problem GREATESC.
Concept of the problem is basic bfs. Given an undirected graph |V| <= 3500 and |E| <= 1000000
Find the minimum distance between two given vertices.
Here's the problem link http://opc.iarcs.org.in/index.php/problems/GREATESC
Here's my solution link
http://ideone.com/GqTc6k
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#define Pi 3.14159
#define vi vector<int>
#define pi pair<int,int>
#define si stack<int>
typedef long long int ll;
using namespace std;
bool b[3501][3501]={0};
int main ()
{
int n,m;
cin >>n>>m;
int u,v;
for (int i =1;i<= m;i++)
{
scanf("%d",&u);
scanf("%d",&v);
b[u][v]=b[v][u]=1;
}
// input completed.
int dist[n+1];
int h,V;
cin >>h>>V;
dist[h]=0;
//cout<<"hero "<<h<<" "<<V<<endl;
queue<int> q;
bool bfs[3501];
for (int i=1;i<= n;i++)bfs[i]=1;
q.push(h);
bfs[h]=0;
while (!q.empty())
{
int top = q.front();
// cout<<top<<endl;
q.pop();
for (int i = 1 ;i <= 3500;i++)
{
if(bfs[i] && b[i][top])
{
int x = i;
dist[i] = dist[top] +1;
if(x == V){cout<<dist[x]<<endl;return 0;}
bfs[x]=0;
q.push(x);
}
}
}
cout<<0<<endl;
}
You have this:
cin >>n>>m;
...
int dist[n+1];
Hence the array dist may have size less than 3500. But:
for (int i = 1 ;i <= 3500;i++)
...
dist[i] = dist[top] +1;
This code might be indexing outside of dist.
You seem to need in general to be more careful that when indexing into an array, you're inside the bounds of the array.
Consider using std::vector instead of arrays, then indexing with at to get bounds checking. Or alternatively, manually assert that values are within range:
#include <assert.h>
...
for (int i = 1 ;i <= 3500;i++)
...
assert(i >= 0 && i <= n && top >= 0 && top <= n);
dist[i] = dist[top] +1;

random function in C++

Is there a function that generates k random numbers within a specified range.
For example I want 5 random numbers between 0 to 100, with or without replacement.
You could use std::generate_n with either rand() or a generator from the new C++11 random number generators.
There is the Boost library, which you can use to generate random numbers, for example.
The following code generates 5 random numbers from [0, 100] with replacement:
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
std::vector<int> result;
for (int i = 0; i < numWantedNumbers; ++i)
result.push_back(distribution(generator));
}
If you want to generate the numbers without replacement, simply check if they are
still available:
#include <algorithm>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
std::vector<int> result;
while (result.size() < numWantedNumbers)
{
int number = distribution(generator);
if (std::find(result.begin(), result.end(), number) == result.end())
result.push_back(number);
}
}
Note: The rejection sampling in the example without replacement has the obvious drawback that longer vectors are quite difficult to create. Just try to draw 99 out
of 100 numbers, to see what I mean (or even better draw 9999 out of 10000). If this
is a problem, I would suggest to create a random permutation of all possible numbers
and then cut the vector at the requested size:
#include <algorithm>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
// Generate a vector with all possible numbers and shuffle it.
std::vector<int> result;
for (int i = 0; i <= 100; ++i)
result.push_back(i);
for (int i = 0; i <= 100; ++i)
{
int x = distribution(generator);
std::swap(result[i], result[x]);
}
// Truncate to the requested size.
result.resize(numWantedNumbers);
}
Edit based on suggestion by juanchopanza:
In C++11 manner, the last variant would look like this
#include <algorithm>
#include <random>
#include <vector>
const int numWantedNumbers = 5;
int main()
{
std::random_device device;
std::mt19937 generator(device());
std::uniform_int_distribution<> distribution(0, 100);
// Generate a vector with all possible numbers and shuffle it.
std::vector<int> result;
for (int i = 0; i <= 100; ++i)
result.push_back(i);
std::random_shuffle(result.begin(), result.end());
// Truncate to the requested size.
result.resize(numWantedNumbers);
}
g++-4.6 compiles it happily, if you add the -std=c++0x switch.
Edit: Make use of std::random_shuffle() (tanks to James Kanze).
Yes there is a rand() function in C++ which can be used including cstdlib header file in your program.
You can implement your program using the following code.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int max {100};
int min {0};
int number;
int count = 5; //assuming that only 10 numbers we need to print
srand(time(0));
for(int i=1;i<=count;i++)
{
number = rand() % (max - min +1) + min;``
cout<<number<<endl;
}
}