I want to read Graph from file and start function to get max flow but i get some error when i pass this graph as function argument. What am I doing wrong?
int main() {
fstream file;
file.open( "macierz.txt", ios::in );
int n = 7;
int graph[n][n];
int v;
for(int i = 0; i < n; i++){
for(int j = 0 ; j < n; j++){
file >> v;
graph[i][j] = v;
}
}
cout << "Ford-Fulkerson -MATRIX- The maximum possible flow: " << fordFulkersonMatrix(graph, 0, 6) << endl;
function :
int fordFulkersonMatrix(int graph[7][7], int start, int target) {
int u, v;
int rGraph[7][7];
int parent[7];
int max_flow = 0;
for (u = 0; u < 7; u++) {
for (v = 0; v < 7; v++)
{
rGraph[u][v] = graph[u][v];
}
}
Error:
main.cpp|200|error: cannot convert 'int (*)[(((unsigned int)(((int)n) + -0x000000001)) + 1)]' to 'const int (*)[7]' for argument '1' to 'int fordFulkersonMatrix(const int (*)[7], int, int)'|
If you program in Java, for sure you will like the C++ STL interfaces:
// or even better - use Eigen as Peter K mentioned
using MyCustomMatrix = std::vector<std::vector<int> >;
// input by const ref to prevent std::vector copy
int fordFulkersonMatrix(const MyCustomMatrix& input, int start, int target) {
// do whatever you need to do
// you can access your matrix elements like this:
int elem34 = input[3][4]; // only if your matrix if big enough, of course
// you can iterare using C++11 range loops
for (const auto& row : input) {
for(auto elem : row) {
std::cout << "My elem: " << elem << std::endl;
}
}
// and you can access your matrix dim information like this:
int numRows = input.size();
if (numRows > 0) {
int numCols = input[0].size();
}
return 0;
}
Later in the code, you can construct your matrix like that:
MyCustomMatrix mat;
mat.push_back(MyCustomMatrix::value_type()); // add one row
mat[0].push_back(69); // add one elem to the first row
fordFulkersonMatrix(mat, 0, 6);
Expected output:
My elem: 69
This is of course very lazy solution, but maybe you don't need anything more. For some serious linear algebra operations consider using specialized libraries (like already mentioned Eigen, or boost uBLAS).
Related
So, I need to make a function that is going to return the chromatic number of a graph. The graph is given through an adjecency matrix that the function finds using a file name. I have a function that should in theory work and which the compiler is throwing no issues for, yet when I run it, it simply prints out an empty line and ends the program.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int Find_Chromatic_Number (vector <vector <int>> matg, int matc[], int n) {
if (n == 0) {
return 0;
}
int result, i, j;
result = 0;
for (i = 0; i < n; i++) {
for (j = i; j < n; j++) {
if (matg[i][j] == 1) {
if (matc[i] == matc[j]) {
matc[j]++;
}
}
}
}
for (i = 0; i < n; i++) {
if (result < matc[i]) {
result = matc[i];
}
}
return result;
}
int main() {
string file;
int n, i, j, m;
cout << "unesite ime datoteke: " << endl;
cin >> file;
ifstream reader;
reader.open(file.c_str());
reader >> n;
vector<vector<int>> matg(n, vector<int>(0));
int matc[n];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
reader >> matg[i][j];
}
matc[i] = 1;
}
int result = Find_Chromatic_Number(matg, matc, n);
cout << result << endl;
return 0;
}
The program is supposed to use an freader to convert the file into a 2D vector which represents the adjecency matrix (matg). I also made an array (matc) which represents the value of each vertice, with different numbers corresponding to different colors.
The function should go through the vector and every time there is an edge between two vertices it should check if their color value in matc is the same. If it is, it ups the second vale (j) by one. After the function has passed through the vector, the matc array should contain n different number with the highest number being the chromatic number I am looking for.
I hope I have explained enough of what I am trying to accomplish, if not just ask and I will add any further explanations.
Try to make it like that.
Don't choose a size for your vector
vector<vector<int> > matg;
And instead of using reader >> matg[i][j];
use:
int tmp;
reader >> tmp;
matg[i].push_back(tmp);
I have a two-dimensional static vector ( std::vector< std::vector<double> > ) which needs to be populated and I am working on an old project which requires to be compiled using C++98. Therefore, I am not allowed to use std::vector<...> v = { {1,2}, {3,4} }; syntax.
For unidimensional vectors, assigning an array as double a[] = {1,2}; and then using the std::vector<double> v(a, a+2) does the trick; however, it is not working for two dimensional vectors.
std::vector< std::vector<double> >
x1_step_lw_2(__x1_step_lw_2,
__x1_step_lw_2 + ARRAY_SIZE(__x1_step_lw_2));
I get the following error:
../src/energyConsumption/ue-eennlite-model-param-7IN-30NN.cpp:193:33: required from here
/usr/include/c++/4.8/bits/stl_construct.h:83:7: error: invalid conversion from ‘const double*’ to ‘std::vector<double>::size_type {aka long \
unsigned int}’ [-fpermissive]
::new(static_cast<void*>(__p)) _T1(__value);
(ARRAY_SIZE(x) is a macro which calculates the size of an array)
And since these vectors are attributes of the class, It would make no sense to initiate them on a constructor.
I am fighting against this problem for some time, and most of the 'solutions' involve to switch to C++11, which is not an option.
Any help is appreciated.
My C++98 is rusty, but something like this should work:
double a[] = { 1, 2 };
double b[] = { 3, 4 };
double c[] = { 5, 6 };
std::vector<double> v[] =
{
std::vector<double>(a, a + ARRAY_SIZE(a)),
std::vector<double>(b, b + ARRAY_SIZE(b)),
std::vector<double>(c, c + ARRAY_SIZE(c))
};
std::vector< std::vector<double> > vv(v, v + ARRAY_SIZE(v));
Try this:
#include <iostream>
#include <vector>
/**this generates a vector of T type of initial size N, of course it is upto you whether you want to use N or not, and returns the vector*/
template<class T>
std::vector<T> generateInitVecs(size_t N)
{
std::vector<T> returnable;
for(int i = 0; i < N; i++)
returnable.push_back(0);
return returnable;
}
int main()
{
std::vector< std::vector<double> > twoDvector;
/**Since twoDvector stores double type vectors it will be first populated by double type vectors*/
for(int i = 0; i < 10; i++){
twoDvector.push_back(generateInitVecs<double>(10));
}
/**populating the vector of vectors*/
for(int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++){
/**can be treated as 2D array*/
twoDvector[i][j] = 50;
}
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
std::cout << twoDvector[i][j] << " ";
}
std::cout << "\n";
}
}
It will print a 10 x 10 matrix, with all values assigned 50.
If i had an array of lets say 15 elements is there anyway for me to make it into a 2d array having it 5x3?
Or if i had a string with 15 letters would it be possible to make it into a 2d array having it 5x3?
This is what i have(using variables but using 5 as a and 3 as b in console)
void finishMap(string map, int a, int b)
{
string finalMap[a][b];
for(int i = 0; b>i; i++)
{
for(int x = 0; a>x; x++)
{
finalMap[a][b] += {{map[x]}, {i}};
}
}
}
Also pretty new to c++ so if you see anything i shouldn't be please tell me :3
I'm using char arrays (c strings) in my answer because I think they are useful to illustrate how arrays work - and thre really isn't a point in using std::string in your case. std::string hides a lot of the underlying nuts and bolts so I would generally recommend to play around with C strings first to understand how std::string works. Also, check out this tutorial: http://www.cplusplus.com/doc/tutorial/arrays/
A 2-dimensional array has the same memory layout as a 1-d array. In terms of memory layout, char[3][5] is the same as char[3*5] is the same as char[15]. You can use a 1-d array as a 2-d array using char[column+row*width]. The only difference if you use subscripts is that the compiler remembers how many dimensions there are and will do the whole column+row*width calculation for you.
Take this example:
char temp[5] = "abcd"; //need 5 for string termination char `\0`
for(int i = 0; i < 4; ++i) {
std::cout << temp[i];
}
std::cout << "\n\n";
for(int i = 0; i < 2; ++i) {
for(int j = 0; j < 2; ++j) {
std::cout << temp[j+2*i];
}
std::cout << std::endl;
}
Will print:
abcd
ab
cd
You can always access an array in strides. Here's a possible example using templates to restride a 1D array as a 2D array:
template <typename T, unsigned int N1, unsigned int N2>
struct strider
{
using array_type = T[N1 * N2];
array_type & data_;
Strider(array_type & data) : data_(data) {}
T & operator()(std::size_t i1, std::size_t i2)
{
return data_[i1 * N2 + i2];
}
};
template <unsigned int N1, unsigned int N2, T>
strider<T, N1, N2> stride(T (&a)[N1, N2]) { return {a}; }
Usage:
int a[15] = {};
strider<int, 3, 5> s(a);
s(1, 2) = 20;
assert(a[7] == 20);
stride<5, 3>(a)(4, 2) = 10;
assert(a[14] == 10);
I've overloaded operator() for the strided access, since unlike operator[] it can have arbirary signatures.
With some more work you could make the rank of the strided view variadic.
Okey so i used something a bit different then what i mentioned. What i did was have the user enter 3 lines of 5 length letters, which i figured out how to add into the 2d array. If your having the same issue as me, heres my code:
int main()
{
string path;
int a, b;
cin >> a >> b;
string finalMap[a][b];
for(int i = 0; b>i; i++){
cin >> path;
for(int x = 0; a>x; x++){
finalMap[x][i] = (path[x]);
}
}
for(int x = 0; b>x; x++)
{
for(int y = 0; a>y; y++)
{
cout << finalMap[y][x];
}
cout << endl;
}
return 0;
}
Thanks for trying tho, really appreciate it ^.-
You can try to use reinterpret_cast. Complete example:
#include <iostream>
using namespace std;
typedef char mtrx[5][3];
int main(){
char data[15] = "Some String";
mtrx &m = *reinterpret_cast<mtrx*>(&data);
m[1][2] = '*';
cout << data << endl;
return 0;
}
I'm wondering if something is wrong with my code especially the vector implementation?
Well,I was just exposed to the use of vector yesterday by people here.
In my college,I only learnt array.So,the usage of vector is kinda new to me.
To my understanding,vector is basically a dynamic array.-Correct me if I were wrong
Well,so lets go with my code.I got the following error: "Vector subscript out of range" after inputting n value.
EDIT:Fixed my earlier issue.Thanks to #quantdev .Now I noticed that my values aren't sorted.
#include<iostream>
#include<vector>
using namespace std;
//Function prototype
void Insertion_sort(vector<int> AR, int n);
void random_store(int val, vector<int> &aVec);
int main()
{
int nvalue;
vector<int> int_vector;
cout << "How many numbers would you like to generate?\n";
cin >> nvalue;//get input from user
random_store(nvalue, int_vector);//pass user input into random() function
system("pause");
return 0;
}
void random_store(int val, vector<int> &aVec)//store randomly generated value
{
int num;//represent random integer output
for (int i = 0; i < val; i++)
{
aVec.push_back(rand() % val + 1);//push each generated value into vector
}
Insertion_sort(aVec,val);//Pass the vector into a function to perform sorting
cout << " \n The sorted array is as follows \n ";
for (int i = 1; i <= val; i++)//Print sorted array
{
cout << " \n Element " << i << " : " << aVec[i] << endl;//will loop from aVec 1st array till n value
}
}
void Insertion_sort(vector<int> AR, int n)//insertion sort function
{
int j, val;//iterate through entire list
for (int i = 1; i < n; i++)
{
val = AR[i];
j = i - 1;
while (j >= 0 && AR[j] > val){
AR[j + 1] = AR[j];
j = j - 1;
}
AR[j + 1] = val;
}
} // end of insertion sort function
The problem is that your vector contains val values, so indexes are in [0, val-1], but within this loop :
for (int i = 1; i <= val; i++)
The last iteration will try to access the element at index val+1, which is out of bounds (it also misses the first element, at index 0)
Change it to :
for (int i = 0; i < val; i++)
And since indexes are of type std::size_t :
for (std::size_t i = 0; i < val; i++)
Note:
Your sort function takes a vector by value, sorting a copy of the vector. You probably want to pass by reference instead :
void Insertion_sort(vector<int>& AR, int n)
I have a matrix of values (stored as an array of values) and a vector with the matrix dimensions( dims[d0, d1, d2]).
I need to build a string like that:
"matA(j, k, l) = x;"
where j, k, l are the indices of the matrix and x the value of the element. I need to write this for each value of the matrix and for matrices with 2 to n dimensions.
I have a problem isolating the base case and replicating it in a useful way. I did a version in a switch case with a case for each dimension and a number of for cycles equal to the number of dimensions:
for (unsigned int k=1; k<=(dims[2]); k++)
{
for (unsigned int j=1; j<=(dims[1]); j++)
{
for (unsigned int i=1; i<=(dims[0]); i++)
{
strs << matName << "(" << i << "," << j << ","<< k << ")="<< tmp[t]<< "; ";
....
but is not what I wanted.. Any idea for a more general case with a variable number of dimensions?
You need a separate worker function to recursively generate the series of indices and main function which operates on it.
For example something like
void worker(stringstream& strs, int[] dims, int dims_size, int step) {
if (step < dims_size) {
... // Add dims[step] to stringstream. Another if may be necessary for
... // whether include `,` or not
worker(strs, dims, dims_size, step + 1);
} else {
... // Add cell value to stringstream.
}
}
string create_matrix_string(int[] dims, int dims_size, int* matrix) {
... // Create stringstream, etc.
strs << ... // Add matrix name etc.
worker(strs, dims, dims_size, 0);
strs << ... // Add ending `;` etc.
}
The main problem here is the value, since the dimension is not known during compilation. You can avoid that by encoding matrix in single-dimensional table (well, that's what C++ is doing anyway for static multidimensional tables) and call it using manually computed index, eg. i + i * j (for two-dimensional table). You can do it, again, by passing an accumulated value recursively and using it in final step (which I omitted in example above). And you probably have to pass two of them (running sum of polynomial components, and the i * j * k * ... * x product for indices from steps done so far.
So, the code above is far from completion (and cleanliness), but I hope the idea is clear.
You can solve this, by doing i, j and k in a container of the size of dim[] - sample:
#include <iostream>
#include <vector>
template< typename Itr >
bool increment( std::vector< int >& ijk, Itr idim, int start )
{
for( auto i = begin(ijk); i != end(ijk); ++i, ++idim )
{
if( ++*i <= *idim )
return true;
*i = start;
}
return false;
}
int main()
{
using namespace std;
int dim[] = { 5, 7, 2, 3 };
const int start = 1;
vector< int > ijk( sizeof(dim)/sizeof(*dim), start );
for( bool inc_done = true; inc_done
; inc_done = increment( ijk, begin(dim), start ) )
{
// .. here make what you want to make with ijk
cout << "(";
bool first = true;
for( auto j = begin(ijk); j != end(ijk); ++j )
{
if( !first )
cout << ",";
else
first = false;
cout << *j;
}
cout << ")= tmp[t] " << endl;
}
return 0;
}