Here's the code that I'm currently using
template <class T>
float Knapsack<T>::knapTable()
{
const int MAXSIZE = 40000;
int temps = nObjects - 1;
float** memoize = new float*[MAXSIZE];
for(int y = 0; y < weight[nObjects]; y++)
memoize[nObjects][y] = 0;
for(int y = weight[nObjects]; y < knapCap; y++)
memoize[nObjects][y] = price[y];
for(int i = temps; i >= 1; i--)
{
for(int y = weight[i]; y < knapCap; y++)
memoize[i][y]= max(memoize[i+1][y], (memoize[i+1][y-weight[i]]+price[i]));
}
return memoize[1][nObjects];
}
For some reason I keep getting the error: knapsack.hpp:68:64: error: invalid types ‘float*[float]’ for array subscript.
That's this line: float** memoize = new float*[MAXSIZE];
For some reason the compiler seems to be recognizing MAXSIZE as a float, it's a const int.
Is there a way I can fix this?
Edited for more code
header file
#ifndef KNAPSACK_H
#define KNAPSACK_H
#include <stdexcept>
#include <assert.h>
#include <iostream>
#include <limits.h>
using namespace std;
template <class T>
class Knapsack
{
private:
float knapPrice;
int knapCap, nObjects;
float weight[40000];
float price[40000];
public:
Knapsack(): knapPrice(0), knapCap(0), nObjects(0) {}
~Knapsack() {knapPrice = 0; knapCap = 0;}
float knapFull (int position, int currentCap);
float knapTable ();
float greedyKnap (int currentCap);
float max(float noAdd,float addOb);
void printPrice();
//valueized and valued are modified versions of mergeSort and merge
//designed to sort two arrays by a fraction of the two.
void valueize(int ini, int last);
void valued(int ini, int middle, int last);
void fillWandP();
void setNObjects(int n);
void setKnapCap(int boom);
};
#include "knapsack.hpp"
#endif
Main function //Though I don't think this would affect it
#include "sortClass.h"
#include "knapsack.h"
#include
#include
#include
#include
using namespace std;
//mergeSort main;
int main()
{
Knapsack<float> a;
float sacked = 0;
int nO = 18;
int cap = 700;
a.setNObjects(nO);
a.setKnapCap(cap);
a.fillWandP();
for(int b = 0; b <3800000; b++)//for getting good times
sacked = b;
int startAll = clock()*1000000;
sacked = a.knapFull(1, cap);
int knapped = clock()*1000000;
int boom = a.knapTable();
int tabled = clock()*1000000;
a.valueize(1, cap);
int andDone = a.greedyKnap(cap);
int greedified = clock()*1000000;
cout<<startAll<<endl;
greedified = greedified - tabled;
tabled = tabled - knapped;
knapped = knapped - startAll;
cout<<"Recursion profit:"<<sacked<<" Time: "<<knapped<<endl;
cout<<"Memoization profit:"<<boom<<" Time: "<<tabled<<endl;
cout<<"Greedy profit: "<<andDone<<" Time: "<<greedified<<endl;
return 0;
}
weight is declared as float weight[40000] in class Knapsack.
You then use an element of weight as an index into memoize in the knaptable() function:
memoize[i][y]= max(memoize[i+1][y], (memoize[i+1][y-weight[i]]+price[i]));
// ^^^^^^^^^
And for the record, that's the line that the error is produced for by g++ 4.6.1; it doesn't point to the line where memoize is declared.
Not necessarily related, but you're not using your arrays/pointers correctly. You create your first level of pointers when you call float** memoize = new float*[MAXSIZE] but you then just have an array of pointers, not a double array. You need to initialize each of memoize[i] as an array as well.
That being said, it doesn't look like you should be allocating memory for your memoize array anyway. Just declare it as
float memoize[SIZE][SIZE];
That way, you won't have to worry about memory cleanup or anything, and it makes a lot more sense.
for(int i = temps; i >= 1; i--)
{
for(int y = weight[i]; y < knapCap; y++)
memoize[i][y]= max(memoize[i+1][y], (memoize[i+1][y-weight[i]]+price[i]));
}
y-weight[i] is a float. This is your problem.
Once you fix this you will discover that you still have an issue, you're allocating an array of pointers but you also need to allocate the second dimension for each of those pointers before you can use that array.
Something along the lines of:
float** memoize = new float*[MAXSIZE];
for(size_t i = 0; i < MAXSIZE; ++i)
{
memoize[i] = new float[MAXSIZE];
}
i think maybe you just need to allocate memory for the second pointer ,something like
float** memoize = new float*[MAXSIZE];
memoize=(float**)malloc(sizeof(float*)*MAXSIZE);
for(int i=0;i<MAXSIZE;i++)
{
memoize[i]=(float*)malloc(sizeof(float)*MAXSIZE);
}
Related
I am kind of new to C++ and I was doing a physics simulation in python which was taking forever to finish so I decided to switch to C++, and I don t understand how to make a function which will return a 2D array (or 3D array)
#include <iostream>
#include <cmath>
// #include <complex> //
using namespace std;
double** psiinit(int L, int n, double alpha){
double yj[400][400] = {};
for (int j = 0; j < n; j++)
{
double xi[400] = {};
for (int i = 0; i < n; i++)
{
xi[i] = exp(-(pow((i-(L/4)), 2) + (pow((j-(L/4)), 2)))/alpha) / (sqrt(2)*3.14159*alpha);
};
yj[j] = xi;
};
return yj;
}
int main(){
int L = 10;
int n = 400;
int nt = 200*n;
double alpha = 1;
double m = 1;
double hbar = 1;
double x[n] = {};
double y[n] = {};
double t[nt] = {};
double psi[nt][n][n] = {};
psi[0] = psiinit(L, n, alpha);
cout << psi <<endl;
return 0;
}
I have look for answers but it doesn't seems to be for my kind of problems
Thanks
If you're new to c++ you should read about the concepts of heap and stack, and about stack frames. There are a ton of good resources for that.
In short, when you declare a C-style array (such as yj), it is created in the stack frame of the function, and therefore there are no guarantees about it once you exit the frame, and your program invokes undefined behavior when it references that returned array.
There are 3 options:
Pass the array to the function as an output parameter (very C-style and not recommended).
Wrap the array in a class (like std::array already does for you), in which case it remains on the stack and is copied to the calling frame when returned, but then its size has to be known at compile time.
Allocate the array on the heap and return it, which seems to me to best suit your case. std::vector does that for you:
std::vector<std::vector<double>> psiinit(int L, int n, double alpha){
std::vector<std::vector<double>> yj;
for (int j = 0; j < n; j++)
{
std::vector<double> xi;
for (int i = 0; i < n; i++)
{
const int value = exp(-(pow((i-(L/4)), 2) + (pow((j-(L/4)), 2)))/alpha) / (sqrt(2)*3.14159*alpha);
xi.push_back(value);
}
yj.push_back(xi);
}
return yj;
}
If you're concerned with performance and all of your inner vectors are of a fixed size N, it might be better to use std::vector<std::array<double, N>>.
Either make a wrapper as said above, or use a vector of vectors.
#include <vector>
#include <iostream>
auto get_2d_array()
{
// use std::vector since it will allocate (the large amount of) data on the heap
// construct a vector of 400 vectors with 400 doubles each
std::vector<std::vector<double>> arr(400, std::vector<double>(400));
arr[100][100] = 3.14;
return arr;
}
int main()
{
auto arr = get_2d_array();
std::cout << arr[100][100];
}
Your understanding of arrays, pointers and return values is incomplete. I cannot write you a whole tutorial on the topic but I recommend you read up on this.
In the mean time, I recommend you use std::vector instead of C-style arrays and treat your multidimensional arrays as 1D vectors with proper indexing, e.g. cell = vector[row * cols + col]
Something like this:
#include <cmath>
// using std::exp, M_PI, M_SQRT2
#include <vector>
std::vector<double> psiinit(int L, int n, double alpha) {
std::vector<double> yj(n * n);
double div = M_SQRT2 * M_PI * alpha;
for (int j = 0; j < n; j++)
{
double jval = j - L/4;
jval = jval * jval;
for (int i = 0; i < n; i++)
{
double ival = i - L/4;
ival = ival * ival;
yj[j * n + i] = std::exp(-(ival + jval) / alpha) / div;
}
}
return yj;
}
Addendum: There are also specialized libraries to support matrices better and faster. For example Eigen
https://eigen.tuxfamily.org/dox/GettingStarted.html
heap allocating and returning that pointer will also work...
instead of
double yj[400][400] = {};
do,
double** yj;
yj = new double*[400];
yj[i] = new double[400];
then just,
return yj;
I'm new to c++, and fairly sure the error is in the variables I'm passing into the function. Essentially, I have two functions defined in a double_arrays.cpp file - first is to determine the Euclidian distance between two vectors (passed in as arrays with 10 values, this function works great). The other (closestPair) is to find which two vectors (again, each being defined as an array with 10 values) are closest in distance. When I am calling this function in my "main.cpp" file, I am getting a "no matching function called closestPair" error.
I am fairly sure that the error is either in the values I am passing into the function, or in the way I am trying to return it (by printing the values to the console).
DISCLAIMER - THIS IF FOR AN ASSIGNMENT :), so hints towards a solution will be more than welcome!
Here are my files:
main.cpp :
#include <iostream>
#include "double_arrays.h"
int main(int argc, const char * argv[])
{
//Define test values to test vectDistance
double first[10] = {
0.595500, 0.652927, 0.606763, 0.162761, 0.980752, 0.964772, 0.319322, 0.611325, 0.012422, 0.393489
};
double second[10] = {
0.416132, 0.778858, 0.909609, 0.094812, 0.380586, 0.512309, 0.638184, 0.753504, 0.465674, 0.674607
};
//call vectDistance with test values, should equal 1.056238
std::cout << "Euclidian distance is " << vectDistance(first, second) << std::endl;
std::cout << "Should equal ~1.056238" << std::endl;
//Define test values for closestPair
double a[10] = {
0.183963, 0.933146, 0.476773, 0.086125, 0.566566, 0.728107, 0.837345, 0.885175, 0.600559, 0.142238
};
double b[10] = {
0.086523, 0.025236, 0.252289, 0.089437, 0.382081, 0.420934, 0.038498, 0.626125, 0.468158, 0.247754
};
double c[10] = {
0.969345, 0.127753, 0.736213, 0.264992, 0.518971, 0.216767, 0.390992, 0.242241, 0.516135, 0.990155
};
//create 2D array to send to closestPair
double** test = new double*[3];
test[0] = a;
test[1] = b;
test[2] = c;
//output the values of the two vectors which are closest, in Euclidian distance
std::cout << closestPair(test) << std::endl;
return 0;
}
double_arrays.cpp :
#include "double_arrays.h"
#include <iostream>
#include <vector>
#include <math.h>
double vectDistance( double first[], double second[]) {
int i = 0;
double distance = 0.0;
for (int j = 0; j < 10; ++j) {
distance += pow((first[j] - second[i]), 2);
++i;
}
return distance = pow(distance, 0.5);
}
double** closestPair(double arrays[][10]) {
double** closest = new double*[2];
closest[0] = new double[10];
closest[0] = arrays[0];
closest[1] = new double[10];
closest[1] = arrays[1];
double minDistance = vectDistance(arrays[0], arrays[1]);
for (int i = 0; i < 9; ++i){
for (int j = i + 1; j < 10; ++j) {
if (vectDistance(arrays[i], arrays[j]) < minDistance) {
minDistance = vectDistance(arrays[i], arrays[j]);
closest[0] = arrays[i];
closest[1] = arrays[j];
}
}
}
return closest;
}
And, finally, the header file, header.h:
#ifndef double_arrays_double_arrays_h
#define double_arrays_double_arrays_h
double vectDistance( double first[], double second[]);
double** closestPair(double arrays[][10]);
#endif
The type double** is not compatible with the argument type of closestPair.
Valid arguments to closestPair:
const int N = 20;
double arrays[N][10]; // Can use array to call closestPair
or
const int N = 20;
double (*arrays)[10] = new double[N][10]; // Can use array to call closestPair
Your header files does not match, it should be:
#ifndef _DOUBLE_ARRAYS_H_
#define _DOUBLE_ARRAYS_H_
Then on your double_arrays.cpp file call:
#include "double_arrays.h"
To call your declared functions from header file on your .cpp file try:
double ** Double_Arrays::closestPair(double arrays[][10]) {
/... your code.../
return closest;
}
I wrote a multithreaded simulated annealing program but its not running. I am not sure if the code is correct or not. The code is able to compile but when i run the code it crashes. Its just a run time error.
#include <stdio.h>
#include <time.h>
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
#include <ctime>
#include <windows.h>
#include <process.h>
using namespace std;
typedef vector<double> Layer; //defines a vector type
typedef struct {
Layer Solution1;
double temp1;
double coolingrate1;
int MCL1;
int prob1;
}t;
//void SA(Layer Solution, double temp, double coolingrate, int MCL, int prob){
double Rand_NormalDistri(double mean, double stddev) {
//Random Number from Normal Distribution
static double n2 = 0.0;
static int n2_cached = 0;
if (!n2_cached) {
// choose a point x,y in the unit circle uniformly at random
double x, y, r;
do {
// scale two random integers to doubles between -1 and 1
x = 2.0*rand()/RAND_MAX - 1;
y = 2.0*rand()/RAND_MAX - 1;
r = x*x + y*y;
} while (r == 0.0 || r > 1.0);
{
// Apply Box-Muller transform on x, y
double d = sqrt(-2.0*log(r)/r);
double n1 = x*d;
n2 = y*d;
// scale and translate to get desired mean and standard deviation
double result = n1*stddev + mean;
n2_cached = 1;
return result;
}
} else {
n2_cached = 0;
return n2*stddev + mean;
}
}
double FitnessFunc(Layer x, int ProbNum)
{
int i,j,k;
double z;
double fit = 0;
double sumSCH;
if(ProbNum==1){
// Ellipsoidal function
for(j=0;j< x.size();j++)
fit+=((j+1)*(x[j]*x[j]));
}
else if(ProbNum==2){
// Schwefel's function
for(j=0; j< x.size(); j++)
{
sumSCH=0;
for(i=0; i<j; i++)
sumSCH += x[i];
fit += sumSCH * sumSCH;
}
}
else if(ProbNum==3){
// Rosenbrock's function
for(j=0; j< x.size()-1; j++)
fit += 100.0*(x[j]*x[j] - x[j+1])*(x[j]*x[j] - x[j+1]) + (x[j]-1.0)*(x[j]-1.0);
}
return fit;
}
double probl(double energychange, double temp){
double a;
a= (-energychange)/temp;
return double(min(1.0,exp(a)));
}
int random (int min, int max){
int n = max - min + 1;
int remainder = RAND_MAX % n;
int x;
do{
x = rand();
}while (x >= RAND_MAX - remainder);
return min + x % n;
}
//void SA(Layer Solution, double temp, double coolingrate, int MCL, int prob){
void SA(void *param){
t *args = (t*) param;
Layer Solution = args->Solution1;
double temp = args->temp1;
double coolingrate = args->coolingrate1;
int MCL = args->MCL1;
int prob = args->prob1;
double Energy;
double EnergyNew;
double EnergyChange;
Layer SolutionNew(50);
Energy = FitnessFunc(Solution, prob);
while (temp > 0.01){
for ( int i = 0; i < MCL; i++){
for (int j = 0 ; j < SolutionNew.size(); j++){
SolutionNew[j] = Rand_NormalDistri(5, 1);
}
EnergyNew = FitnessFunc(SolutionNew, prob);
EnergyChange = EnergyNew - Energy;
if(EnergyChange <= 0){
Solution = SolutionNew;
Energy = EnergyNew;
}
if(probl(EnergyChange ,temp ) > random(0,1)){
//cout<<SolutionNew[i]<<endl;
Solution = SolutionNew;
Energy = EnergyNew;
cout << temp << "=" << Energy << endl;
}
}
temp = temp * coolingrate;
}
}
int main ()
{
srand ( time(NULL) ); //seed for getting different numbers each time the prog is run
Layer SearchSpace(50); //declare a vector of 20 dimensions
//for(int a = 0;a < 10; a++){
for (int i = 0 ; i < SearchSpace.size(); i++){
SearchSpace[i] = Rand_NormalDistri(5, 1);
}
t *arg1;
arg1 = (t *)malloc(sizeof(t));
arg1->Solution1 = SearchSpace;
arg1->temp1 = 1000;
arg1->coolingrate1 = 0.01;
arg1->MCL1 = 100;
arg1->prob1 = 3;
//cout << "Test " << ""<<endl;
_beginthread( SA, 0, (void*) arg1);
Sleep( 100 );
//SA(SearchSpace, 1000, 0.01, 100, 3);
//}
return 0;
}
Please help.
Thanks
Avinesh
As leftaroundabout pointed out, you're using malloc in C++ code. This is the source of your crash.
Malloc will allocate a block of memory, but since it was really designed for C, it doesn't call any C++ constructors. In this case, the vector<double> is never properly constructed. When
arg1->Solution1 = SearchSpace;
Is called, the member variable "Solution1" has an undefined state and the assignment operator crashes.
Instead of malloc try
arg1 = new t;
This will accomplish roughly the same thing but the "new" keyword also calls any necessary constructors to ensure the vector<double> is properly initialized.
This also brings up another minor issue, that this memory you've newed also needs to be deleted somewhere. In this case, since arg1 is passed to another thread, it should probably be cleaned up like
delete args;
by your "SA" function after its done with the args variable.
While I don't know the actual cause for your crashes I'm not really surprised that you end up in trouble. For instance, those "cached" static variables in Rand_NormalDistri are obviously vulnerable to data races. Why don't you use std::normal_distribution? It's almost always a good idea to use standard library routines when they're available, and even more so when you need to consider multithreading trickiness.
Even worse, you're heavily mixing C and C++. malloc is something you should virtually never use in C++ code – it doesn't know about RAII, which is one of the few intrinsically safe things you can cling onto in C++.
My compiler keeps saying that 'small' and 'x' were not declared in this scope, how do I fix my array so that they are accurately displayed? overall the code is supposed to find the smallest positive nonzero value stored in the array.
#include <iostream>
#include <string>
using namespace std;
int findthesmall( int small[x], int y)
{
for(int i=0; i< y; i++){
for(int j=0; j< y; j++){
int temp = small[i];
if( small[i] > small[j] )
small[i] = small[j];
small[j] = temp;
}
}
return small[0];
}
int main(){
return 0;
}
I think you need:
int findthesmall( int* small, int y) {
Try this:
int findthesmall( int small[], int y) {
for(int i=0; i< y; i++){
for(int j=0; j< y; j++){
int temp = small[i];
if( small[i] > small[j] )
small[i] = small[j];
small[j] = temp;
}
}
return small[0];
}
int main(){
return 0;
}
int small[x]
This is illegal for 2 reasons.
Like your compiler says, X is undefined
Size of the array cannot be set to the value of a non compile time constant.
To fix this you can do what #ajon suggested( pass array as pointer + length), it is historically the way to pass arrays.
There are other better ways in C++ though.
You can consider using std::array or std::vector. Both of them can be passed as you would any other variable, know their own size, and can be accessed like a normal array
Or you could use template code to capture the size of the array automatically.
template<int len>
int findthesmall(int (&small)[len]){
The 2nd option maybe a little convoluted and more complex than other options, especially now that you have got your answer, I'm just including it here for completeness.
Apart from other answers, there is also a bug in the logic. If your function is just to find the smallest element as function name indicated, one for loop should be enough.
Sample code presented below:
int findthesmall( int small[], int y)
{
int temp = small[0];
for(int i=1; i< y; i++)
{
if( temp > small[i] )
temp = small[i];
}
return temp;
}
Or you could use std::min_element algorithm as well
std::cout << *std::min_element(small, small+y) << std::endl;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I work with dynamic multi-dimensional arrays in C?
Static Matrix Casting to a pointer
my this code is throwing exception at line
resMat[i][j] = matp[i][j];
// code begins here
#include <iostream>
#define MOD 1000000007
#define LL long long
using namespace std;
int mat[6][64][64],mat2[2][2], mat4[4][4], mat8[8][8], mat16[16][16], mat32[32][32], mat64[64][64];
int **point[6];
int resMat[64][64];
void fooMatrix(int **matp, int size)
{
int i,j;
// find canFollow of all matrixes
for(i=0;i<size;++i)
{
for(j=0;j<size;++j)
{
// throwing exception here
resMat[i][j] = matp[i][j];
}
}
}
int main()
{
point[0] = (int **)mat2;
point[1] = (int **)mat4;
point[2] = (int **)mat8;
point[3] = (int **)mat16;
point[4] = (int **)mat32;
point[5] = (int **)mat64;
LL a,b,res;
scanf("%lld %lld",&a,&b);
fooMatrix(point[a-1],1<<a);
return 0;
}
i want to process on different sized matrices of int in my function fooMatrix like say store it in resMat. Help me resolve this issue.
I am using DevC++ (g++ compiler) in windows.
Reading from the comments and links above i learnt this :
matrix represntation [][] and pointers representation ** is different. Compiler was giving me warning.
2d matrix is not array of pointers. so look at the code below
#include <stdio.h>
#define MOD 1000000007
#define LL long long
int mat[6][64][64],mat2[2][2], mat4[4][4], mat8[8][8], mat16[16][16], mat32[32][32], mat64[64][64];
// see this is array of single pointer
int *point[6];
int resMat[64][64];
void fooMatrix(int *matp, int size)
{
int i,j;
// find canFollow of all matrixes
for(i=0;i<size;++i)
{
for(j=0;j<size;++j)
{
// this is how we would access the matrix.
resMat[i][j] = matp[i*size+j];
}
}
}
int main()
{
point[0] = &mat2[0][0];
point[1] = &mat4[0][0];
point[2] = &mat8[0][0];
point[3] = &mat16[0][0];
point[4] = &mat32[0][0];
point[5] = &mat64[0][0];
LL a,b,res;
scanf("%lld %lld",&a,&b);
fooMatrix(point[a-1],1<<a);
return 0;
}
Instead of using matrices, you will have to use dynamically allocated arrays of pointers to arrays.
You can replace the declarations at the top of the file with the following:
int** newMat(int a, int b){
int** result = new int*[a];
for(int i=0; i<a; ++i)
result[i] = new int[b];
return result;
}
int** mat2 = newMat(2,2);
int** mat4 = newMat(4,4);
int** mat8 = newMat(8,8);
int** mat16 = newMat(16,16);
int** mat32 = newMat(32,32);
int** mat64 = newMat(64,64);
int*** point = new int**[6];
int** resMat= newMat(64,64);
And then change the assignments at the top of main with:
point[0] = mat2;
point[1] = mat4;
point[2] = mat8;
point[3] = mat16;
point[4] = mat32;
point[5] = mat64;