Something to change - c++

as the title, i don't know how to convert this struct into a class?
Also i've another problem, how can i convert the array Sets[][] and top[] into vector?
I tried, but i have problem with editing in a vector of [i] position.
//*******************************
// Class Kruskal *
//*******************************
class kruskal
{
private:
struct Edge {
//Arco: vertice V -> vertice U : peso W
int v, u, w;
Edge(int v, int u, int w) : v(v), u(u), w(w) {}
bool operator < (const Edge& c) const{
if (w != c.w)
return w < c.w;
if (v != c.v)
return v < c.v;
return u < c.u;
}
};
int n; //n. nodes
int nre; //n. edges
vector<Edge> edges; //vector contenente tutti gli archiì
vector<Edge> tree; //Albero che conterrà tutti gli archi dell'MST
int sets[100][10]; //matrice contente i sets (tagli)
int top[100]; //supporto alla matrice dei sets
public:
kruskal(){};
~kruskal(){ cout << "Grafo distrutto"; };
void read_graph();
void sort_edges();
void algorithm();
int find_node(int);
void print_min_span_t();
};
//*******************************************
// read_graph() *
// Legge in input n, nre, e i vari archi *
//*******************************************
void kruskal::read_graph()
{
cout << "Algoritmo di Kruskal" << endl;
cout << "Minimum Spanning Tree su Grafo non orientato e pesato" << endl << endl;
cout << "-Inserire numero di nodi e numero di archi: ";
cin >> n >> nre;
int v, u, w;
cout << "-Inserire vertice 1, vertice 2 e peso:" << endl;
for (int i = 0; i < nre; i++)
{
cin >> v >> u >> w;
if (w != 0)
{
edges.push_back(Edge(v, u, w));
}
}
//Print graph edges
cout << endl << endl << "Archi del grafo:" << endl;
for (unsigned int i = 0; i < edges.size(); i++)
{
cout << " < " << edges[i].v
<< " , " << edges[i].u
<< " > " << edges[i].w << endl;
}
}
//*******************************************
// sort_edges() *
// Ordina gli archi per peso con sort() *
//*******************************************
void kruskal::sort_edges()
{
sort(edges.begin(), edges.end());
//Print graph edges
cout << endl << endl << "Archi del grafo dopo l'ordinamento:" << endl;
for (unsigned int i = 0; i < edges.size(); i++)
{
cout << " < " << edges[i].v
<< " , " << edges[i].u
<< " > " << edges[i].w << endl;
}
}
//***********************************************
// algorithm() *
// Inizializza i sets (make-set) *
// Trova i sets dei due nodi (Find_node) *
// Controlla se i sets sono diversi (Findset) *
// Se si lo inserisce nel vector "tree" (MST) *
// E unisce i due sets (Union) *
// Altrimenti "scarta" l'arco *
//***********************************************
void kruskal::algorithm()
{
//Make-set
for (int i = 1; i <= n; i++)
{
sets[i][1] = i;
top[i] = 1;
}
cout << endl << "Avvio algoritmo di Kruskal:" << endl << endl;
for (unsigned int i = 0; i < edges.size(); i++)
{
int p1 = find_node(edges[i].v);
int p2 = find_node(edges[i].u);
//Findset(p1) != Findset(p2)
if (p1 != p2)
{
cout << "Arco preso nell'albero:"
<< " < " << edges[i].v << " , "
<< edges[i].u << " > " << endl << endl;
//Union
tree.push_back(Edge(edges[i].v, edges[i].u, edges[i].w));
//Union two sets
for (int j = 1; j <= top[p2]; j++)
{
top[p1]++;
sets[p1][top[p1]] = sets[p2][j];
}
top[p2] = 0;
}
else
{
cout << "Questo arco"
<< " < " << edges[i].v << " , "
<< edges[i].u << " > " << "forma un ciclo ed e' stato rimosso" << endl << endl;
}
}
}
//*******************************************
// find_node() *
// Trova il sets di appartenenza del nodo *
//*******************************************
int kruskal::find_node(int n)
{
for (int i = 1; i <= nre; i++)
{
for (int j = 1; j <= top[i]; j++)
{
if (n == sets[i][j])
return i;
}
}
return -1;
}
//*******************************
// print_min_span_t() *
//*******************************
void kruskal::print_min_span_t()
{
cout << endl << "Minimum Spanning Tree del grafo:" << endl;
for (unsigned int i = 0; i < tree.size(); i++)
{
cout << " < " << tree[i].v
<< " , " << tree[i].u
<< " > " << tree[i].w << endl;
}
}

As top is just the size of corresponding sets, you may remove top, and change std::vector<std::vector<int> > sets.
Then
MakeSet:
//Make-set
sets.resize(nre); // or n, not sure of the definition of each one...
for (std::size_t i = 0; i != nre; ++i)
{
sets[i].push_back(i);
}
UnionSet:
//Union two sets
sets[p1].insert(sets[p1].end(), sets[p2].begin(), sets[p2].end());
sets[p2].clear();
Find node:
int kruskal::find_node(int n) const
{
for (size_t i = 0; i != sets.size(); ++i)
{
if (std::find(sets[i].begin(), sets[i].end(), n) != sets[i].end())
{
return i;
}
}
return -1;
}

Related

Quicksort not sorting one element in the list of strings

Could anyone tell me what is wrong with my code:
int Partition(vector<string>& userIDs, int i, int k) {
int pivot = (i + (k - i) / 2);
string temp;
while(i<k) {
cout << "pivot:" << pivot << endl;
while (userIDs.at(i).compare(userIDs.at(pivot))<0) {
cout << "1. i:"<<i<<" UserIDs.at(i):" << userIDs.at(i) << " UserID.at(pivot): " << userIDs.at(pivot) << endl;
i += 1;
}
while (userIDs.at(pivot).compare(userIDs.at(k))<0) {
cout << "2. k:" << k << " UserIDs.at(k):" << userIDs.at(k) << " UserID.at(pivot): " << userIDs.at(pivot) << endl;
k -= 1;
}
if(i<k){
cout << "3. i:" << i << " k:"<<k<<" UserIDs.at(i):" << userIDs.at(i) << " UserID.at(k) : " << userIDs.at(k) << endl;
temp = userIDs.at(i);
userIDs.at(i) = userIDs.at(k);
userIDs.at(k) = temp;
i++;
k--;
}
cout << "4. i:" << i << " k:" << k << endl;
}
cout << " 5. k:" << k << endl;
return k;
}
void Quicksort(vector<string>& userIDs, int i, int k) {
cout << "Quicksort i:" << i << " k:" << k << endl;
if (i >= k) {
return;
}
int lowEndIndex = Partition(userIDs, i, k);
cout << "Quicksort lowEndIndex:" << lowEndIndex << endl;
Quicksort(userIDs, i, lowEndIndex);
Quicksort(userIDs, lowEndIndex+1, k);
}
When I input this list:
BigBen
GardenHeart
GreyMare
TeenPunch
WhiteSand
LifeRacer
Doom
AlienBrain
I get:
AlienBrain
BigBen
GreyMare
GardenHeart
Doom
LifeRacer
TeenPunch
WhiteSand
Why is Doom not in the correct place?
#include <bits/stdc++.h>
using namespace std;
int Partition(vector<string>& userIDs, int i, int k) {
int pivot = i;
string pivotValue = userIDs[pivot];
string temp;
int leftIndex = i;
int rightIndex = k;
while(i<k) {
while (userIDs[i].compare(pivotValue)<=0) {
i++;
if(i >= rightIndex) break;
}
while (pivotValue.compare(userIDs[k])<=0) {;
k--;
if(k <= leftIndex) break;
}
if(i<k){
temp = userIDs[i];
userIDs[i] = userIDs[k];
userIDs[k] = temp;
}
}
// swap
userIDs[pivot] = userIDs[k];
userIDs[k] = pivotValue;
return k;
}
void Quicksort(vector<string>& userIDs, int i, int k) {
if (i >= k) {
return;
}
int lowEndIndex = Partition(userIDs, i, k);
Quicksort(userIDs, i, lowEndIndex - 1);
Quicksort(userIDs, lowEndIndex + 1, k);
}
int main() {
vector<string> userIDs = {"BigBen", "GardenHeart", "GreyMare", "TeenPunch",
"WhiteSand", "LifeRacer", "Doom", "AlienBrain" };
Quicksort(userIDs, 0, userIDs.size() - 1);
for(auto& c: userIDs) cout << c << " ";
cout << endl;
return 0;
}
Fixed the code and tested. Now it works. What were the problems?
As far as I noticed, firstly you didn't put break() statements within the while loops in case i or k exceeds the boundaries of the vector. I've changed the pivot from middle element to first element, but it's just my preference, you can implement the quicksort algorithm with your pivot in the middle, not a big deal. I've called first Quicksort() with lowEndIndex - 1 rather than lowEndIndex. I've used [] operator rather than at(), but again it's my preference. I guess the main problems were that break stuff and calling the quicksort method with lowEndIndex rather than lowEndIndex - 1.
Output:
AlienBrain BigBen Doom GardenHeart GreyMare LifeRacer TeenPunch WhiteSand

How to format output like this

My code is like this so far :
void matrix::print(int colWidth) const
{
cout << getRows() << " x " << getCols() << endl;
cout << "-";
for (unsigned int d = 0; d < getCols(); d++) {
cout << "--------";
}
cout << endl;
for (unsigned x = 0; x < getRows(); x++) {
cout << "|";
for (unsigned y = 0; y < getCols(); y++) {
cout << setw(colWidth) << at(x, y) << " |";
}
cout << endl;
}
cout << "-";
for (unsigned int d = 0; d < getCols(); d++) {
cout << "--------";
}
cout << endl;
}
But the output depends on the colWidth which will be the space between each number printed. So how can I adjust my dashes to be printed like the following no matter the colWidth it should align.
One output should look like this:
Second output is like this:
If the column width is a parameter, you're almost done with your code. Just turn the cout<<"--------" into:
std::cout << std::string(getCols()*(colWidth + 2) + 1, '-');
That code prints a string of dashes, which width is: number of matrix columns, times column width plus 2, plus 1:
Plus 2 because you are appending a " |" to each column.
Plus 1 because you are adding a '|' at the beginning of each row.
You may want to check for empty matrices at the beginning of your print method.
[Demo]
#include <initializer_list>
#include <iomanip> // setw
#include <iostream> // cout
#include <vector>
class matrix
{
public:
matrix(std::initializer_list<std::vector<int>> l) : v{l} {}
size_t getRows() const { return v.size(); }
size_t getCols() const { if (v.size()) { return v[0].size(); } return 0; }
int at(size_t x, size_t y) const { return v.at(x).at(y); }
void print(int colWidth) const
{
std::cout << "Matrix: " << getRows() << " x " << getCols() << "\n";
// +2 due to " |", +1 due to initial '|'
std::cout << std::string(getCols()*(colWidth + 2) + 1, '-') << "\n";
for (unsigned x = 0; x < getRows(); x++) {
std::cout << "|";
for (unsigned y = 0; y < getCols(); y++) {
std::cout << std::setw(colWidth) << at(x, y) << " |";
}
std::cout << "\n";
}
std::cout << std::string(getCols()*(colWidth + 2) + 1, '-') << "\n";
}
private:
std::vector<std::vector<int>> v{};
};
int main()
{
matrix m{{1, 2}, {-8'000, 100'000}, {400, 500}};
m.print(10);
}
// Outputs
//
// Matrix: 3 x 2
// -------------------------
// | 1 | 2 |
// | -8000 | 100000 |
// | 400 | 500 |
// -------------------------

error: overloaded function with no contextual type information usinf LEMON-graph-library

So I am implementing a Benders procedure using lazy constraints from GUROBI. As part of the subproblem procedure I need to process a graph using Breadth First Search, for which I am using LEMON. I am trying to implement use a visitor for the BFS search. However when I try to access the map of reached nodes using bfs.reached() I get a compiler (I suppose) error.
Here is the callback class implementation so far:
typedef ListDigraph::Node Node;
typedef ListDigraph::Arc Arc;
typedef ListDigraph::ArcMap<double> ArcDou;
typedef ListDigraph::NodeMap<double> NodeDou;
typedef ListDigraph::ArcMap<int> ArcInt;
typedef ListDigraph::ArcMap<bool> ArcBool;
typedef ListDigraph::NodeMap<int> NodeInt;
typedef ListDigraph::NodeIt NodeIt;
typedef ReverseDigraph<ListDigraph>::NodeIt NodeIt_rev;
typedef ListDigraph::ArcIt ArcIt;
class BendersSub: public GRBCallback
{
public:
const Instance_data &ins;
const vec4GRBVar &X;
const vec1GRBvar &u;
vec2GRBVar &p;
GRBModel &modelSubD;
BendersSub(const Instance_data &ins, const vec4GRBVar &X, const vec1GRBvar &u, vec2GRBVar &p, GRBModel &modelSubD)
:ins(ins), X(X), u(u), p(p),modelSubD(modelSubD){
//cout << "\n\tI:" << ins.I << " J:" << ins.J << " T:" << ins.T << " V:" << ins.V << flush;
}
protected:
void callback() {
try {
if (where == GRB_CB_MIPSOL) {
cout << "\n -- Entering Callback -- " << flush;
string var_name;
int I = ins.I , J = ins.I , T = ins.T , V = ins.V,i,j,k,t,v;
ListDigraph grafo;
Node x;
for( int t(0); t < ins.T+1; t++)
for ( int i(0); i < ins.I; i++)
x = grafo.addNode();
Arc arco;
int count( 0 );
for(t = 0; t < ins.T; ++t){
for(i = 0; i < ins.I; ++i){
for(j = 0; j < ins.J; ++j){
if ( i == j ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(j + (ins.I * (t+1))));
}else if ( (t + ins.tau.at(i).at(j)) <= ins.T-1 ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(j + ins.I * (t + ins.tau.at(i).at(j))));
}
else if ( (t + ins.tau.at(i).at(j)) > ins.T-1 ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(((ins.I*(ins.T+1)+1))-1-(ins.I)+j)) ;
}
}
}
}
NodeDou divergence (grafo);
ArcDou costo (grafo);
ArcBool filter (grafo, true);
NodeDou potential (grafo);
ReverseDigraph<ListDigraph> grafo_r(grafo);
using Visitor = Visitor_AcSup<NodeDou>;
for ( int v(0); v < V; v++){
double sum_sup(0.0);
Visitor visitor(grafo_r, divergence, sum_sup);
cout << "\nsum_sup: " << sum_sup << flush;
for (t = 0; t < T; t++){
for(i = 0; i < I ; i++){
if(divergence[grafo.nodeFromId(flat_ixt(ins,t,i))] < -EPS3){
BfsVisit<ReverseDigraph<ListDigraph>, Visitor> bfs(grafo_r,visitor);
bfs.run(grafo.nodeFromId(flat_ixt(ins,t,i)));
if( (sum_sup-fabs(divergence[grafo.nodeFromId(flat_ixt(ins,t,i))])) < -EPS4 ){
cout << "\nBuild Ray" << flush;
}
}
}
}
for (NodeIt_rev u(grafo_r); u != INVALID; ++u){
/*The error does not show when I comment this line.*/
cout << "\nId: " << grafo.id(u) << setw(10) << bfs.reached(u) << flush;
}
cout << "\nsum_sup: " << sum_sup << flush;
.
/* Remaining code */
.
.
}/*end_if v*/
//cout << "\n -- Exiting Callback -- " << flush;
}
}catch (GRBException e) {
cout << "Error number: " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
exit(EXIT_FAILURE);
}catch (const exception &exc){
cerr << "\nCallback - " << exc.what() << flush;
exit(EXIT_FAILURE);
}catch (...) {
cout << "Error during callback" << endl;
exit(EXIT_FAILURE);
}
}
};
Here is the (incomplete visitor) implementation.
template <typename DivMap >
class Visitor_AcSup : public BfsVisitor< const ReverseDigraph<ListDigraph> > {
public:
Visitor_AcSup(const ReverseDigraph<ListDigraph>& _graph, DivMap& _dirMap, double& _sum_sup)
: graph(_graph), dirMap(_dirMap), sum_sup(_sum_sup){
cout << "\n --Calling constructor of Visitor_AcSup -- " << endl;
sum_sup = 0.0;
}
void start (const Node &node){
//cout << "\nstart Node: " << graph.id(node) << flush;
sum_sup -= dirMap[node];
}
void reach (const Node &node){
//cout << "\nReach Node: " << graph.id(node) << flush;
}
void process (const Node &node){
//cout << "\nProcess Node: " << graph.id(node) << setw(5) << dirMap[node] << flush;
sum_sup += dirMap[node];
}
void discover(const Arc& arc) {
//cout << "\tDiscover Arc: " << graph.id(arc) << flush;
}
void examine(const Arc& arc) {
//cout << "\tExamine Arc: " << graph.id(arc) << flush;
}
private:
const ReverseDigraph<ListDigraph>& graph;
DivMap& dirMap;
double& sum_sup;
The error looks like this
functions.cpp:1845:59: error: overloaded function with no contextual type information
cout << "\nId: " << grafo.id(u) << setw(10) << bfs.reached(u) << flush;
^~~~~~~
Makefile:27: recipe for target 'VAP' failed
I am clueless about what is happening as the only error that comes up to my mind is conflict of keywords between namespaces
using namespace lemon;
using namespace lemon::concepts;
using namespace std;
but have found no resolution to this. I am a newbie in C++, so that I am asking you guys where this could possibly come from.

C++ programming problem, failed to assign pointers to correct objects

I've been working on a problem which involves an size-N square matrix maze with N^2 nodes and 2N(N-1) edges connecting vertical and horizontal neighbours. The codes are as follows:
//Node.h
#pragma once
#define NULL 0
using namespace std;
class Edge;
class Node {
public:
int id, row, col;
Edge* EL, * ER, * EU, * ED;
vector<int> connected;
Node(int id, int row, int col);
Node* get_L();
Node* get_R();
Node* get_U();
Node* get_D();
void print();
};
//Edge.h
#pragma once
#include "Node.h"
class Edge {
public:
int id, type;
bool state;
Node* N1, * N2;
Edge(int id, Node n1, Node n2, int type);
void setState(bool b);
void print();
};
//Maze.h
#pragma once
#include <vector>
#include "Node.h"
#include "Edge.h"
using namespace std;
class Maze {
public:
int size;
vector<Node> nodes;
vector<Edge> edges;
Maze(int N);
void print();
};
//main.cpp
#include <iostream>
#include <vector>
#include "Node.h"
#include "Edge.h"
#include "Maze.h"
Node::Node(int id, int row, int col) {
this->id = id;
this->row = row;
this->col = col;
this->EL = NULL;
this->ER = NULL;
this->EU = NULL;
this->ED = NULL;
}
Node* Node::get_L() {
if (EL) {
return EL->N1;
}
else {
cerr << "Node " << id << "does not have left neighbour.";
}
}
Node* Node::get_R() {
if (ER) {
return ER->N2;
}
else {
cerr << "Node " << id << "does not have right neighbour.";
}
}
Node* Node::get_U() {
if (EU) {
return EU->N1;
}
else {
cerr << "Node " << id << "does not have up neighbour.";
}
}
Node* Node::get_D() {
if (ED) {
return ED->N2;
}
else {
cerr << "Node " << id << "does not have down neighbour.";
}
}
void Node::print() {
int l, r, u, d;
l = EL ? EL->N1->id : -1;
r = ER ? ER->N2->id : -1;
u = EU ? EU->N1->id : -1;
d = ED ? ED->N2->id : -1;
cout << "Node " << id << " (Row " << row << " Col " << col << "), neighbours <L,R,U,D>: <" << l << "," << r << "," << u << "," << d << ">" << endl;
}
Edge::Edge(int id, Node n1, Node n2, int type) {
this->id = id;
this->N1 = &n1;
this->N2 = &n2;
this->state = false;
this->type = type;
}
void Edge::print() {
if (type == 0) {
cout << "Horizontal ";
}
else {
cout << "Vertical ";
}
cout << "edge " << id << " between <" << N1->id << ", " << N2->id << ">, " << state << endl;
}
void Edge::setState(bool b) {
this->state = b;
}
Maze::Maze(int N) {
size = N;
for (int i = 0; i < N * N; ++i) {
Node n = Node(i, i / N, i % N);
nodes.push_back(n);
}
int eid = 0;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N - 1; ++j) {
Node n1 = nodes[i * N + j];
Node n2 = nodes[i * N + j + 1];
Edge e = Edge(eid, n1, n2, 0);
/*
// &n1 and &n2 retain the same throughout the loop
cout << &n1 << endl;
cout << &n2 << endl;
cout << e.N1->id << "," << e.N2->id << endl; // This line gives correct result
e.print(); // Incorrect
*/
n1.ER = &e;
n2.EL = &e;
edges.push_back(e);
eid++;
}
}
cout << nodes[0].ER << endl;
for (int i = 0; i < N - 1; ++i) {
for (int j = 0; j < N; ++j) {
Node n1 = nodes[i * N + j];
Node n2 = nodes[i * N + j + 1];
Edge e = Edge(eid, n1, n2, 1);
n1.ED = &e;
n2.EU = &e;
edges.push_back(e);
eid++;
}
}
}
void Maze::print() {
cout << size << " x " << size << " Maze" << endl;
cout << nodes.size() << " nodes:" << endl;
for (auto& i : nodes) {
i.print();
}
cout << edges.size() << " edges:" << endl;
for (auto& i : edges) {
i.print();
}
}
int main()
{
Maze m = Maze(8);
m.print();
}
However after compiling and running I found out that the nodes and edges are NOT connected to each other as I expected. In the codes of creating edges I tried to figure out the reason (see the commented part), I found that in the entire loop, the addresses of n1 and n2 always retain the same. Still have no idea why this is happening. Please help.

segmentation fault for string function argument

I have a simple main code that gives me segmentation fault when calling a function. In the following code, I have two functions, the first one works correctly but the program doesn't enter the second one and gives me segmentation fault error. Is there any reason for that? I have made sure about the following:
The variables o and c are not out of bound.
cn is initialized correctly.
I have a read-only access to cm and argv. Plus it does not even enter the function evaluate
Here is the code:
void print_cm(vector<vector<int> > *cm, char* gtf);
void evaluate(vector<vector<int> > *cm, char* gtf);
int main(int argc, char** argv)
{
int o = 2; // It is initialized
int c = 4; // It is initialized
vector<vector<int> > cm; // It is initialized
if (argc>4)
print_cm(&cm, argv[o]);
if (argc>4)
{
cout << argv[c] << endl; // Works
// The following also works
for (int i=0; i<cm.size(); i++)
for (int j=0; j<cm[i].size(); j++)
cout << cm[i][j] << " ";
// The following causes segmentation fault;
evaluate(&cm, argv[c]);
}
return 0;
}
void evaluate(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
void print_cm(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
Here is the complete code:
#include "includes/Utility.h"
#include "includes/Graph.h"
void print_cm(vector<vector<int> > *cores, char* output);
void evaluate(vector<vector<int> > const *cm, char* gtf);
int main(int argc, char** argv)
{
int g = -1, c = -1, o = -1;
for (int i=1; i<argc-1; i++)
if (argv[i][0]=='-')
{
if (argv[i][1]=='g')
g = i + 1;
else if (argv[i][1]=='c')
c = i + 1;
else if (argv[i][1]=='k')
ki = i + 1;
else if (argv[i][1]=='s')
si = i + 1;
else if (argv[i][1]=='o')
o = i + 1;
}
Graph G;
if (c>0) G.read_input(argv[g], argv[c]);
else G.read_input(argv[g]);
if (ki > 0)
{
int k = atoi(argv[ki]);
cout << k << endl;
}
if (si > 0)
{
int s = atoi(argv[si]);
cout << s << endl;
}
// Find communities
vector<vector<int> > cores;
G.partitioning(&cores);
if (o>0)
print_cm(&cores, argv[o]);
if (c>0)
{
cout << "here" << endl;
for (size_t i=0; i<cores.size(); i++)
for (size_t j=0; j<cores[i].size(); j++)
if (cores.at(i).at(j)<0) cout << "here";
cout << "here" << endl;
evaluate(&cores, argv[c]);
}
}
return 0;
}
void print_cm(vector<vector<int> > *cores, char* output)
{
ofstream out;
out.open(output);
for(size_t i=0; i<(*cores).size(); i++)
{
for(size_t j=0; j<(*cores)[i].size(); j++)
out << (*cores)[i][j] << " ";
out << endl;
}
out.close();
return ;
}
void evaluate(vector<vector<int> > const *cm, char* gtf)
{
// we evaluate precision, recall, F1 and F2
vector<vector<int> > gt;
ifstream in;
char str[100000000];
in.open(gtf);
while(in.getline(str, 100000000))
{
stringstream s;
s << str;
int a;
gt.resize(gt.size()+1);
while (s >> a) gt[gt.size()-1].push_back(a);
}
in.close();
cout << "==================== Evaluation Results ====================" << endl;
int imax = 0;
for(size_t i=0; i<(*cm).size(); i++)
imax = max(imax, *max_element((*cm)[i].begin(), (*cm)[i].end()));
for(size_t i=0; i<gt.size(); i++)
imax = max(imax, *max_element(gt[i].begin(), gt[i].end()));
vector<bool> flag(imax, false);
vector<double> recall((*cm).size(), 0), precision((*cm).size(), 0), f1((*cm).size(), 0), f2((*cm).size(), 0);
int overlap;
double size = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
// evaluate
size += (double) (*cm)[i].size();
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = true;
double p, r, ff1, ff2;
for(size_t j=0; j<gt.size(); j++)
{
overlap = 0;
for(size_t k=0; k<gt[j].size(); k++)
if (flag[gt[j][k]]) overlap++;
p = (double) overlap / (double) (*cm)[i].size();
if (p > precision[i])
precision[i] = p;
r = (double) overlap / (double) gt[j].size();
if (r > recall[i])
recall[i] = r;
ff1 = (double) 2*(p*r)/(p+r);
if (ff1 > f1[i])
f1[i] = ff1;
ff2 = (double) 5*(p*r)/(4*p + r);
if (ff2 > f2[i])
f2[i] = ff2;
}
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = false;
}
double Recall = 0, Precision = 0, F1 = 0, F2 = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
Recall += recall[i];
Precision += precision[i];
F1 += f1[i];
F2 += f2[i];
}
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << "Precision";
cout << " | " << setiosflags( ios::left ) << setw(10) << "Recall";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F1-measure";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F2-measure";
cout << " |" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << Precision/(*cm).size() ;
cout << " | " << setiosflags( ios::left ) << setw(10) << Recall/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F1/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F2/(*cm).size();
cout << " |" << endl;
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "Number of communities: " << (*cm).size() << endl;
cout << "Average community size: " << size/(*cm).size() << endl;
return ;
}
char str[100000000];
This is in your evaluate function. This are 100 million bytes, or about 95 MB that you're allocating on the stack.
Typical stack sizes are far less than that, around 1 MB.
So apart from possible other problems this is most likely causing a stack overflow.
When entering the function, the stack frame gets extended to be large enough to hold the local variables. As soon as the stack is used then (to write a default value) you're accessing invalid (non stack, thankfully protected) memory.