I'm having trouble creating a Matrix using Vectors. The rows and columns will all be random doubles and I am trying to fill it in.
I have tried to initialize the size of the vector before hand, I believe it initializes correctly, however, when I try to push onto the rows and columns I get very odd output. Here is my Header File:
#ifndef MATRIX_NORM_HPP
#define MATRIX_NORM_HPP
#include <vector>
class MatrixNorm
{
public:
void initProgram();
void printResults();
double randNumber();
private:
std::vector<std::vector<double>> M;
double mNorm1 = 0.0;
double mNormInf = 0.0;
};
#endif
Here is my CPP File:
#include "matrixNorm.hpp"
#include <iostream>
#include <random>
void initProgram()
{
double ranNum = 0.0;
int size = 0;
std::cout << "Please enter a size of an n by n Matrix: ";
std::cin >> size;
std::vector<std::vector<double>> temp(size, std::vector<double>(size));
for(int i = 0; i < size; ++i)
{
for(int j = 0; j < size; ++j)
{
ranNum = randNumber();
temp[i].push_back(ranNum);
temp[j].push_back(ranNum);
}
}
M = temp;
printResults();
}
void MatrixNorm::printResults()
{
for(auto &&e: M)
{
for(auto && f: e)
{
std::cout << f << " ";
}
std::cout << std::endl;
}
}
double MatrixNorm::randNumber()
{
double ranDouble = 0.0;
std::random_device rd;
std::default_random_engine generator(rd());
std::uniform_real_distribution<double> unif(-1000.0,1000.0);
ranDouble = unif(generator);
return ranDouble;
}
The output I receive when I run the program from main.cpp is:
Please enter a size of an n by n Matrix: 3
0 0 0 792.208 792.208 -361.248 -776.871 742.521 116.732
0 0 0 -361.248 742.521 411.965 411.965 909.313 -50.0048
0 0 0 -776.871 909.313 116.732 -50.0048 79.6189 79.6189
As you can see, it seems to get the column size correctly, but it does not get the row size correctly, and if you look very closely. Some of the numbers are duplicates, I wish I knew how to format it more clearly but if you start at the top left you see 792.208 792.208 then go down a row and you see 411.965 411.965 and last it finishes off at 79.6189 79.6189 in the lower right.
What am I doing wrong? How do I do this correctly? Any help would be appreciated.
Seems to me that the correct way to initialize your matrix is:
(...)
std::vector<std::vector<double>> temp;
for(int i = 0; i < size; ++i)
{
std::vector<double> k;
for(int j = 0; j < size; ++j)
{
ranNum = randNumber();
k.emplace_back(ranNum);
}
temp.emplace_back(k);
}
(...)
Explanation:
with this constructor:
std::vector<std::vector<double>> temp(size, std::vector<double>(size));
you are creating size copies of default vector constructed of size elements (std::vector<double>(size)). In other words, you have a size x size matrix.
So, instead of pushing new values in your code, you should be changing it. In the code I proposed, it is just simpler to populated this matrix when you are creating it.
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'm trying to fill 2D vector in C++ with characters, but when I run this code it ends with one line characters (*..).
How can I fill 2D vector like this:
*.*
.**
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<char> > vec2D;
std::vector<char> rowV;
unsigned int row=2;
unsigned int col=3;
char c;
unsigned int temp=0;
while(temp!=col)
{
while(rowV.size()!=row)
{
std::cin>>c;
rowV.push_back(c);
}
vec2D.push_back(rowV);
++temp;
}
return 0;
}
You should clear rowV after each insertion, otherwise it will be full and no other characters will be added. Also, row should be swapped by col and vice-versa, otherwise you will get a 3x2 (and not 2x3) 2D vector.
while(temp!=row)
{
while(rowV.size()!=col)
{
std::cin>>c;
rowV.push_back(c);
}
vec2D.push_back(rowV);
rowV.clear(); // clear after inserting
++temp;
}
It helps to know what [pushing back a 2DVector with an empty 1D vector] looks like.
See the example below.
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
//-v-----A FUNCTION TO PRINT 2D VECTORS
template<typename T> //We don't know what type the elements are yet, so we use a template
void printVec2D(vector<vector<T>> a) // a is the name of our input 2Dvector of type (T)
{
for (int i = 0; i < a.size(); i++) {// a.size() will equal the number of rows (i suppose rows/columns can depend on how you look at it)
for (int j = 0; j < a[i].size(); j++) {// a[i].size() is the size of the i'th row (which equals the number of columns, foro a square array)
std::cout << a[i][j] << "\t";
}
std::cout << "\n";
}
return;
}
//-^--------
int main()
{
int X = 3; int Y = 3;
int VectorAsArray[3][3] = {{1,2,3},
{14,15,16},
{107,108,109}};
vector<vector<int>> T;
for (int i = 0; i < X; i++)
{
T.push_back({});// We insert a blank row until there are X rows
for (int j = 0; j < Y; j++)
{
T[i].push_back(VectorAsArray[i][j]); //Within the j'th row, we insert the element corresponding to the i'th column
}
}
printVec2D(T);
//system("pause"); //<- I know that this command works on Windows, but unsure otherwise( it is just a way to pause the program)
return 0;
}
I have made this code that should build two vectors, one with the integers up to 100 and the other with the squares of these integers, and would like to write two columns so that the values line up in two columns. The program compiles ok, but the output is empty, i.e., nothinkg appears but only the message "Process returned 0 (0x0)". What exactly am I missing here?
#include <iostream>
#include <cmath>
#include <iomanip>
#include <vector>
using namespace std;
int main()
{
vector<int> numbers;
typedef vector<int>::size_type vec_sz;
vec_sz size = numbers.size();
for (vec_sz i = 0; i != numbers.size(); ++i)
{
numbers.push_back(i);
}
vector<int> squares;
for (vec_sz i = 0; i!= squares.size(); i++)
{
squares.push_back(i^2);
}
for (vec_sz i = 0; i != numbers.size(); ++i)
{
cout << setw(3)
<< numbers[i]
<< setw(6)
<< squares[i]
<< endl;
}
return 0;
}
When you write this line at the beginning of your main function,
vec_sz size = numbers.size();
you want to obtain the size of the vector. However, numbers is empty, it does not contain any data. Hence size will be 0. Here numbers.size() is going to return 0.
Hence for (vec_sz i = 0; i != numbers.size(); ++i) will not execute even once.
Let's say that you want to fill numbers, then you should know how many values do you want to fill in numbers. Once you know this value, store it in a variable let's say count.
Sample:
const int count = 10;
for (int i = 0; i < count; ++i) {
numbers.push_back(i);
}
// now numbers.size() will return 10;
Same goes for your squares vector.
As practice for myself I'm trying to create a genetic algorithm that will solve equations. So far my program can generate random "genes", fill up individuals with these "genes", and do some basic calculations with the genes (at the moment, simply summing the "genes").
However, I've realised now that I want to implement my fitness function that I would have been better off creating a struct for individual, since I need to keep the genes and the fitness outcome together to have the fittest genes reproduce again.
Anyway, here's my code:
// GA.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <random>
#include <string>
const int population_size = 10;
const int number_of_variables = 7;
struct one_individual
{
std::vector<std::vector<double>>individual;;
double evaluation = 0;
double fit = 0;
};
int main()
{
// Generate random number
std::random_device rd;
std::mt19937 rng(rd()); // random-number engine (Mersenne-Twister in this case)
std::uniform_real_distribution<double> dist(-10.0, 10.0);
// Create vector that holds vectors called individual and fill size it to the amount of individuals I want to have.
std::vector<std::vector<double>>individual;
for (int i = 0; i < population_size; i++)
{
std::vector<double>variables;
for (int j = 0; j < number_of_variables; j++)
{
variables.push_back(dist(rng));
}
individual.push_back(variables);
}
// Display entire population
for (auto &count : individual)
{
for (auto &count2 : count)
{
std::cout << count2 << " ";
}
std::cout << "\n";
}
// Do calculation with population. At the moment I just add up all the genes (sum) and display the sum for each individual.
for (int i = 0; i < population_size; i++)
{
int j = 0;
std::cout << "Organism "<< i;
double sum = individual[i].at(j) + individual[i].at(j + 1) + individual[i].at(j + 2) + individual[i].at(j + 3) + individual[i].at(j + 4) + individual[i].at(j + 5) + individual[i].at(j + 6);
std::cout << " is " << sum << "\n";
}
std::cout << "\n";
return 0;
}
What I think I should be doing is something like this:
for (int i = 0; i < population_size; i++)
{
one_individual individual;
std::vector<double>variables;
for (int j = 0; j < number_of_variables; j++)
{
variables.push_back(dist(rng));
}
one_individual.individual.push_back(variables);
}
The above code is not working. What happens when I try to compile is I get a list of errors, I just pasted it into pastebin since it's a pretty big list: www.pastebin.com/EVJaV0Ex. If I remove everything except the parts needed for the "creating individuals part" the errors that remain are: www.pastebin.com/djw6JmXZ. All errors are on line 41 which is the final line one_individual.individual.push_back(variables);
Edited for clarity, apologies that it was unclear.
Consider the instruction
one_individual.individual.push_back(variables);
where one_individual is a type (struct one_individual).
I suppose you should use the defined variable of type one_individual, so
individual.individual.push_back(variables);
I'm attempting to build a genetic algorithm that can take a certain amount of variables (say 4), and use these in a way so that you could have 2a + 3b + c*c + d = 16. I realise there are more efficient ways to calculate this, but I want to try and build a genetic algorithm to expand later.
I'm starting by trying to create "organisms" that can compete later. What I've done is this:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <random>
// Set population size
const int population_size = 10;
const int number_of_variables = 4;
int main()
{
// Generate random number
std::random_device rd;
std::mt19937 rng(rd()); // random-number engine (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(-10, 10);
// Set gene values.
std::vector<int>chromosome;
std::vector<int>variables;
for (int i = 0; i < number_of_variables; ++i)
{
double rand_num = uni(rng);
variables.push_back (rand_num);
std::cout << variables[i] << "\n";
}
return 0;
}
What happens is it will fill up the number_of_variables vector, and output these just because that makes it clear for me that it's actually doing what I intend for it to do. What I want it to do however is to fill up each "chromosome" with one variables vector, so that for example chromosome 0 would have the values {1, 5, -5, 9} etc.
The following code obviously isn't working, but this is what I'd like it to do:
for (int j = 0; j < population_size; ++j)
{
for (int i = 0; i < number_of_variables; ++i)
{
double rand_num = uni(rng);
variables.push_back(rand_num);
}
chromosome.push_back(variables[j]);
std::cout << chromosome[j] << "\n";
}
Meaning it'd fill up the variables randomly, then chromosome1 would take those 4 values that "variables" took, and repeat. What actually happens is that (I think) it only takes the first value from "variables" and copies that into "chromosome" rather than all 4.
If anyone could help it'd be very much appreciated, I realise this might be simply a rookie mistake that is laughably simply in the eyes of someone more experienced with vectors (which would probably be 99% of the people on this website, hah).
Anyway, thanks :)
#include <iostream>
#include <vector>
#include <random>
// Set population size
const int population_size = 10;
const int number_of_variables = 4;
int main()
{
// Generate random number
std::random_device rd;
std::mt19937 rng(rd()); // random-number engine (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(-10, 10);
// Set gene values.
std::vector< std::vector<int>>chromosome;
for( int kp = 0; kp < population_size; kp++ )
{
std::vector<int>variables;
for (int i = 0; i < number_of_variables; ++i)
{
double rand_num = uni(rng);
variables.push_back (rand_num);
}
chromosome.push_back( variables );
}
// display entire population
for( auto c : chromosome )
{
for( auto v : c )
{
std::cout << v << " ";
}
std::cout << "\n";
}
// display 4th member of population
for( auto v : chromosone[ 3 ] )
{
std::cout << v << " ";
}
std::cout << "\n";
return 0;
}
http://ideone.com/2jastJ
You can place a vector inside a vector with the syntax:
std::vector<std::vector<int>>
but you will need to make the outer vector large enough for num_variables.
#include <vector>
#include <cstdlib>
using Individual = std::vector<int>;
using Population = std::vector<Individual>;
// short for std::vector<std::vector<int>>;
const size_t number_of_variables = 8;
int main() {
Population population(10);
for (auto& individual : population) {
individual.resize(number_of_variables);
for (size_t j = 0; j < number_of_variables; ++j) {
individual[j] = j; // replace with random number
}
}
}
Live demo: http://ideone.com/pfufGt