different output with compilers? - c++

I was solving a programming problem on a site. On my machine (Visual Studio 2010) a test case gives wrong result, while gives correct result on the site. I am not sure what is the compiler of the site's judge, but I think it is something like gcc or cygwin.
THE CODE
A graph problem. The graph here is represnted as a tree. The graph is directed, and doesn't contain loops. The solution is (2 * sum of all edges - max path length from root)
// to-vertex & edge-length
vector<pair<int, int> > pr[100];
int dfs(int i) // to find max path length from root
{
int mx = 0;
for (int j = 0; j < pr[i].size(); ++j)
mx = max(mx, dfs(pr[i][j].first) + pr[i][j].second);
return mx;
}
int PowerOutage::estimateTimeOut(vector <int> from_vertex,
vector <int> to_vertex, vector <int> edge_length)
{
int tot = 0;
for (int i = 0; i < from_vertex.size(); ++i)
{
pr[from_vertex[i]].push_back(make_pair(to_vertex[i], edge_length[i]));
tot += (2 * edge_length[i]);
}
return tot - dfs(0);
}
THE TEST CASE
from_vertex {0, 0, 0, 0, 0}
to_vertex {1, 2, 3, 4, 5}
edge_length {100, 200, 300, 400, 500}
Visual Studio returns: 2493, While the site's compiler returns the correct answer: 2500.
Why the two results are different? I think there is some hidden bug (in my code) that appears in VS giving wrong answer but disapper in the other compiler. Should I determine the site's compiler and use it instead?

Despite my first(wrong) assumption, OP has found out that it was 2500 already but the test-function had the flaw after i asked him "where is 2500 printed?".

Related

C++: SIGBUS Error after increasing stack size to avoid SIGSEV

UPDATE: I solved it, just increased the stack size to 0x40000000, and now my code runs perfectly. (Earlier, I thought the stack size would be sufficient because I was getting a different error before (SIGSEV), and I did not think SIGBUS was also due to stack size)
I am a beginner in C++ and I have to run my recursive code on some very large inputs.
After running, I got SIGSEV Error, and I figured out that it's probably due to low stack size.
I am using CLion and I added
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-stack_size,0x20000000")
to CMakeLists.txt
Now, when I run my code, I get SIGBUS Error (interrupted by signal 10: SIGBUS).
Does anyone know why this could happen and how to fix this?
My Code:
void dfs(int x, int y) {
if (vis[x][y]) {
return;
}
vis[x][y] = 1;
if (!useless[x][y]) {
int cnt_ok = 0;
for (int d = 0; d < 4; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
if (valid(nx, ny)) {
cnt_ok += !useless[nx][ny];
}
}
useless[x][y] = cnt_ok < 2;
}
for (int d = 0; d < 4; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
if (valid(nx, ny)) {
dfs(nx, ny);
}
}
}
This is a DFS on 2-D Grid and function valid() checks for whether the coordinates are valid or not.
dx[4] = {-1, 1, 0, 0}
dy[4] = {0, 0, 1, -1}
The dimensions of vis and useless vectors are just the dimensions of the grid.
When I run with debugger in CLion:
(Line 62 is where the void dfs(int x, int y) is written. Line 86 is where dfs(nx, ny) is written.)
Also, if it's relevant - the file is so large that my computer becomes very slow and laggy when my code is running.
I also ran this code on smaller inputs and the code works perfectly fine.
Surprisingly, if a comment out the if (!useless[x][y]) the code runs fine even on large inputs and exits normally.
(Please focus on the code itself, I am beginner in c++, and I just implement pseudo-code given in books, so my code may not align with best practices.)
Thanks!

C++ Problem filling structs with values from another struct

I'm having an issue trying to figure out why I am not getting the correct functionality with a piece of code. I have looked around to try and find a solution however, I haven't been able to do so. Below is an example of my code:
//Structs
typedef struct
{
int gene[60];
int fitness;
} individual;
typedef struct
{
int cond[5];
int out;
}rule;
//Array of individuals
individual population[P]
int function(individual solution){
int k = 0;
//Array of rules
rule rulebase[10]
for (int i = 0; i < 10; i++){
for (int j = 0; j < 5; j++){
rulebase[i].cond[j] = solution.gene[k++];
}
rulebase[i].out = solution.gene[k++];
}
for (int i = 0; i < 5; i++){
cout << rulebase[0].cond[i];
}
The solution that is passed into the function is the first individual in 'population' and the gene array contains only binary numbers, for example:
gene = [0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1] //There will be 60 in total
The desired functionality is to fill the rule structures in the rulebase with the values found in the solution. For example, using the example above the first rule in the rulebase will have the values below in the 'cond' array:
[0, 0, 1, 0, 1]
and the 'out' will be the next integer in the solution:
[1]
Then the next rule will be filled with the next values in the solution the same way.
The problem that I am having is the code seems to be filling the 'cond' array of each rule with all of the values in the solution, as oppose to the desired way described above. For example, when I print the genes in 'rulebase[0]' I get:
[0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1]
As oppose to:
[0, 0, 1, 0, 1]
I can't seem to figure out why I am getting this problem as the code looks to me like it should work? Any help would be greatly appreciated as I am seriously struggling!
A rule contains only 5 values in cond, not 10 as you show. Its just your code that prints the values of rulebase[0] that is wrong, i.e. it exceeds array bounds and prints - in addition to the cond-values of rulebase[0] - the values of out and cond of the next rule, which - in memory - come next.

What is the correct way to horizonatally concatenate std::vectors?

I have a 2D-matrix whose column size increases after every iteration but the row size remains fixed. For each iteration, a function returns a matrix which I would like to stack horizontally. Following is the code I tried but I think I am doing something wrong in the big_mat[ii].insert part. But I looked around and found codes for vertical stacking where you can start from big_mat.end() and perform insert. But I want the row size to remain fixed. Can you please help me with this ? Also the maximum final size would be of the order 1,000,000 times 5,000.
std::vector<std::vector<float> > big_mat;
big_mat.reserve(fixed_row_dim);
std::vector<std::vector<float> > small_mat;
for (some condition){
// small_mat is always fixed_row_dim x some_dim
small_mat = GetMat(params,fixed_row_dim);
for (int ii = 0; ii < fixed_row_dim; ii++){
big_mat[ii].insert(big_mat[ii].end(),small_mat[ii].begin(),small_mat[ii].end());
}
}
I have tried to compile your code, with necessary editions of course and it is working just fine. so what is the problem and what kind of error do you get?
int main() {
std::vector<std::vector<float> > big_mat;
big_mat.reserve(5);
std::vector<std::vector<float> > small_mat;
for (int i = 0; i < 10; i++){
// small_mat is always fixed_row_dim x some_dim
std::vector<float> example = { 1, 2, 3, 4, 5 };
std::vector<std::vector<float>> small_mat;
for (int ii = 0; ii < 5; ii++) {
small_mat.push_back(example);
}
for (int ii = 0; ii < 5; ii++){
big_mat[ii].insert(big_mat[ii].end(), small_mat[ii].begin(), small_mat[ii].end());
}
}
}
however I get "debug assertion failed" error while trying to run that code in visual studio 2013. the reason was that big_mat was empty- had size smaller than the number of iterations. changing the initialization of big_mat from:
big_mat.reserve(5);
to:
for (int ii = 0; ii < 5; ii++) {
big_mat.push_back(*(new std::vector<float>()));
}
fixed the issue. I think that this is the problem with your code. I will try to get some information about std::vector::reserve function and explain it to you in next few minutes.
Edit: as #Zereges pointed out. Proposed way of initialization of two dimensional vector will cause memory leaks, safe and more sexy way to achive this is:
std::vector<std::vector<float> > big_mat { 5, std::vector<float>{0f} }
Explanation: as you can read in the documentation, the reserve function
Requests that the vector capacity be at least enough to contain n elements.
just guarantee that the vector of given size will fit in the memory without reallocation required. It does not initialize anything, so your big_mat vector of vectors was empty and you have tried to iterate over it in your loops.

Minimum of subset of vector (c++)

I need the index of the minimum value in a vector<int>, however only some indices must be taken into account. Say we have:
vector<int> distance({5, 5, 4, 3, 5});
vector<int> neighbors({0, 1, 2, 4});
Then the value 3 is not taken into account and thus 4 is the minimum value, hence I need index 2. One could solve it by adding a large constant to the values which are not taken into account:
int City::closest(set<int> const &neighbors) const
{
vector<double> dist(d_distance);
for (size_t idx = 0; idx != dist.size(); ++idx)
{
auto it = find(neighbors.begin(), neighbors.end(), idx);
if (it == neighbors.end())
dist[idx] = __INT_MAX__;
}
auto min_el = min_element(dist.begin(), dist.end());
return distance(dist.begin(), min_el);
}
However I my opinion this method is unreadable and I would prefer a STL algorithm or a combination of two of them. Do you have a more neat solution for this?
Use the variant of min_element taking a comparator, and use neighbors as the range and distance as your cost function:
return *min_element(neighbors.begin(), neighbors.end(),
[&](int i, int j) { return distance[i] < distance[j]; });
Is this what you want to do?
int min=__INT_MAX__;
int minIndex=-1;
for(int i=0;i<neighbours.size();i++){
if(distance[neighbours[i]]<min){
min=distance[neighbours[i]];
minIndex=i;
}
}

find the cluster of a highest number of elements using Kmean?

I'm using kmean function for clustering 8-D vectors into a set of clusters as:
kmeans(Vectors, clusterCount, labels, TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 100, 2), 10, KMEANS_PP_CENTERS, centers);
For me the most successful cluster is the one who contains the higher number of vectors. SO my question is how to find the cluster of highest number of populations?
label param is an indicator to whom each vector belongs, I feel that if I use it to find the frequency it will consume a time.
is there anybody can suggest an idea?
Traditionally, I did this task as following:
int max = -1;int index = -1;
vector<int> classes;
classes.resize(clusterCount);
for (int i=0;i<labels.rows;i++)
{
int idx = labels.at<int>(i,0);
classes[idx]++;
if (classes[idx] > max)
{
max = classes[idx];
index = idx;
}
}
is there a solution faster than this?
I'm looking for the same, but haven't found anything (yet) that is substantially different, However you can speed up your code:
don't update your maximum each time
avoid use of intermediate variables (like your int idx)
Here's my code for this:
int classes[clusterCount];
memset(classes, 0, sizeof(classes[0]) * clusterCount);
int * labels_ptr = labels.ptr<int>(0);
for (int i = 0; i < labels.rows; ++i)
classes[*labels_ptr++]++;
for (int i = 0; i < clusterCount; ++i)
{
if (classes[i] > max)
{
max = count[i];
index = i;
}
}
this code gives the same results as yours, and on my pc (intel core i7) goes roughly 5 times faster than the code you provided (tested on different images for 1000 runs).