getValue() cplex C++ - c++

Actually, I'm a beginner on using cplex on C++.
I try to stock the values of a variable (IloIntVarArray) after solving the MIP on a vector that I've put as an argument of the function by getValue(), but it doesn't work. Any suggestions?

Here's an example
IloNumArray values(getEnv());
getValues(values, _x);
for (int i = 0; i < _graph->GetArcCount(); i++)
{
ClassOfArcs* arc = _graph->GetArc(i);
arc->value = (double)values[arc->index];
}
values.clear();
Where x is an IloNumVarArray holding the value of variable x_ij (going from customer i to j). In the example, I wish to store the values of x in an std::vector _x.
Don't forget to do a value.end() when you finish passing all other variables in your model to avoid memory leaks.

Related

Is there a way to 'reset' a functions variables?

I recently made a function to compare an array of numbers to a single value which returns the closest value to the single value out of the array. This works perfectly well when you only use it only once but if I use it again in another instance of the code, It returns an unexpected value (usually the previous single value used before). Here is the function that I am using:
double closestval (double num1, int amountofnums, double *comps){
double storagecomps[amountofnums];
for (int i = 0; i < amountofnums; i++){
storagecomps[i] = {comps[i]};
/* Storing the array of numbers for later as I will be changing them */
}
double smallval = 0.0001; /* tiny value used to increment/decrement
values in the array to the comparison variable.*/
int_fast64_t compi [amountofnums]; /* this variable keeps track of how many times it needs to decrement/increment the values in the array to approach the variable*/
for (int i = 0; i < amountofnums; i++){
compi[i] = 0;
}
for (int i = 0; i <= amountofnums; i++){
while (comps[i] > num1){
comps[i] -= smallval;
compi[i]++;
}
while (comps[i] < num1){
comps[i] += smallval;
compi[i]++;
}
double recholder[3] = {10000000, 0,};
// This area finds the
for (int i = 0; i < amountofnums; i++){
if (compi[i] < recholder[0]){
recholder[0] = compi[i];
recholder [1] = i;
recholder[2] = storagecomps[i]; /* if the amount of iterations to approach the single variable is less than the previous record holder, it becomes the new one.
*/
}
}
return recholder[2];
}
I am relatively sure this is because (in one way or another) the variables in the function are not being redefined properly or at all. Much thanks if you can show me where I've gone wrong!
The problem isn't resetting the variables. The problem is that you are modifying the arguments passed to the function.
To prevent modifications you should use the const keyword:
double closestval (double num1, int amountofnums, const double *comps){
and then fix the errors the compilers throws at you.
If you do want to modify the comps inside the functions but not have it affect the values outside the functions then you should usestd::vector so you can pass them by value and the compiler will copy them:
double closestval (double num1, int amountofnums, std::vector<double> comps){
You should really do that anyway as you should forget all about C-style arrays till you are an expert.

c++ program how can I return my array or write to a global variable

I am new with C++ and I have to write code, but somehow it is not working and I do not know what I can change. I would like to give back the array Grad, but it says segmentation fault (core dumped).
Could somebody help me with what I have to change?
Or is it possible to have a global variable and write from the function
directly to the global variable?
Thanks for your help.
Code:
double* Gradient(const double x[], int n1) {
double Grad [n1*4] = {0};
// We calculate the overlap. If the overlap is zero, the gradient
// is also zero. This should be probably improved in the future.
//int n = sizeof(x)/32;
for (int i = 0; i < n1*4; i++)
{
for (int j = 0; j < n1*4; i++)
{
if (i != j)
{
//cout << x[i]<< endl;
double xmin = max(x[i*4], x[j*4]);
double xmax = min(x[i*4+1], x[j*4+1]);
//if (xmin > xmax) return Grad;
double ymin = max(x[i*4+2], x[j*4+2]);
double ymax = min(x[i*4+3], x[j*4+3]);
//if (ymin > ymax) return Grad;
double x_overlap = xmax-xmin;
double y_overlap = ymax-ymin;
// Gradient for xmin
if (x[i*4] >= x[j*4] && x[i*4] != x[j*4+1] && x[i*4+1]
!= x[j*4] && x[i*4+2] != x[j*4+3] && x[i*4+3] != x[j*4+2]) Grad[i*4] =
Grad[i*4]-y_overlap;
// Gradient for xmax
if (x[i*4+1] < x[j*4+1]) Grad[i*4+1] = Grad[i*4+1] +
y_overlap;
// Gradient for ymin
if (x[i*4+2] >= x[j*4+2] && x[i*4] != x[j*4+1] &&
x[i*4+1] != x[j*4] && x[i*4+2] != x[j*4+3] && x[i*4+3] != x[j*4+2])
Grad[i*4+2] = Grad[i*4+2]-x_overlap;
// Gradient for ymax
if (x[i*4+3] <= x[j*4+3]) Grad[i*4+3] = Grad[i*4+3] +
x_overlap;
// Gradient for xmax if rectangles are touching by the
x-coordinate
if (x[i*4+1] == x[j*4] && x[i*4+3] > x[j*4+2] &&
x[i*4+2] < x[j*4+3])
{
Grad[i*4+1] = Grad[i*4+1] + y_overlap;
}
// Gradient for ymax if rectangles are touching by the
y-coordinate
if (x[i*4+3] == x[j*4+2] && x[i*4+1] > x[j*4] && x[i*4]
< x[j*4+1])
{
Grad[i*4+3] = Grad[i*4+3] + x_overlap;
}
}
}
}
return Grad;
}
int main() {
// Coordinates of the rectangles
double x[] = {0,6,0,9,3,9,4,11};
int n1 = sizeof(x)/32;
double gradient;
gradient = Gradient(x,n1);
cout << "Gradient R1 xmin = " << Gradient[0] << endl;
}
Arrays are not first class elements in C++ language (they were not in C either). Specifically, when you pass an array to a function, or when you return it, it decays to a pointer to its first element. As the Grad array has automatic storage (neither static nor allocated) its lifetime ends at the end of a function and you only return a dangling pointer, meaning a pointer to a variable whose lifetime has ended. Using it is explicitely Undefined Behaviour.
In common implementation, automatic variables are allocated in the stack. So after the function returns, the memory pointed to by the dangling pointer is likely to be reused and what you will get will not be what you would expect. The segmentation fault is just one of the possible consequences of the UB.
The common way to return an array if you do not intend to use multi-threading would be to declare it static. That way its lifetime extends up to the end of the program and it solves the dangling pointer problem. That would be fine for a static size array (size defined at compile time) but not for a dynamic size (defined at run time). So you are left with 2 C-ish ways:
use a dynamically allocated array (with new[] or malloc); the caller will then have to free it (with resp. delete[] or free)
let the caller manage the array and pass it to the function (void Gradient(const double x[], double *Grad, int n1)). This is the prefered way because the caller has full control over the allocation mode.
But in C++ the idiomatic way is to use a vector: std::vector Grad(n1*4, 0.);. A vector is a true C++ object and can be assigned or returned. Unless you have strong reasons to do so, avoid C-ish ways because C++ containers are much more programmer friendly.
how can I return my array or write to a global variable
Read a good book on C++ programming, and look into this C++ reference.
double* Gradient(const double x[], int n1) {
double Grad [n1*4] = {0};
If n1 is a large positive integer such as 1234567, your code is likely to have a stack overflow. If n1 is negative, you are in trouble. AFAIK, VLAs are not in C++.
Read also how to debug small programs
You probably want to use some standard C++ container. std::array or std::vector comes to mind.
You can return some std::array<int,10>. Of course the computer would copy ten integers, and that is slower than returning just a pointer.
In some cases, you might want to use smart pointers. Read about the standard <memory> header.
Beware of buffer overflow and segmentation fault and other kinds of undefined behavior.
If you compile your C++ code with a recent GCC compiler, enable all warnings and debug info, so use g++ -Wall -Wextra -g. If you use GCC 10, consider using the recently added static analysis options. If you prefer Clang, consider using its static analyzer. Consider also using the Frama-C analyzer and reading this draft report. Be however aware of Rice's theorem.
In all cases read the documentation of your particular C++ compiler. Don't confuse your C++ compiler with your IDE or source-code editor. I suggest to compile on the command line, and use some build automation tool (perhaps GNU make or ninja) with some version control tool such as git, and some debugger such as GDB. Tools like valgrind are also helpful.
Always avoid returning the address of some automatic variable on the call stack. Once your function returned, that address is invalid. Be scared of uninitialized pointer variables.
I will try to help you
variable-sized array double Grad [n1*4] = {0}; In C++, variable length arrays are not legal. G++ allows this as an "extension".
return Grad; return pointer to local data, after exiting function Gradient Grad id not available
You can use std::vector, thus your code may look like this:
std::vector<double> Gradient(const double x[], int n1) {
std::vector<double> Grad (n1*4, 0);
...
Grad[i*4+3] = ...
...
return Grad;
}
There are multiple problems with your code.
You can't allocate the size of a static array at run time , that is you can't do this operation double Grad [n1*4] = {0};
where n1 is a variable. To allocate memory you have to use malloc function.
ptr = (int*)malloc(n * sizeof(int));
where n is the size of desired array.A continuous block of memory will be allocated
Array can't be returned as such, to solve that problem pointers are introduced.
If you follow the above method, ptr is a pointer which can access a memory location,while to access a particular element you can simple use ptr[i], where i is the desired index
Gradient is a function, it's illegal to perform this operation Gradient[0].
I hope this have cleared your doubt. A simple tip try writing small block of code to check if certain thing works.

Dynamic 2D array of strings where the second dimension can change

So I have to make a 2-d array of strings named history[][], where history[i] stores all of the subjects currently involved in experiment i, and history[i][j] contains a string listing all of the experiments that this particular subject has been a part of. The thing is, I have to use int* numsubjects, an array of integers that tells me how many subjects are in experiment i. However, the contents of numsubjects should be able to move around as subjects can be moved into other experiments. I have no idea how to go about doing this. I cannot use vector, dequeue, or list.
experiments = 0;
numsubjects = new int[experiments+1];
numsubjects[experiments] = n;
history = new string*[0];
for(int j = 0; j < n; j++) {
history[0] = new string[j];
history[0][j] = "0";
}
The above code initializes everything when there is only one experiment, experiment 0. I need a way to make history somehow with numsubjects in it.
If you must use C-style arrays, then realloc() will allow you to resize your array.
However, since this is C++, I strongly encourage you to use std::vector or std::map.

What is the correct syntax for accessing a class member function for a pointer-to-class object contained within an array?

I have the following function, stdDev, which accepts an array of pointers to objects of the Student class. Student class has a member function getScores(), which returns a student's score as a double.
Here is the code below:
double stdDev(Student array[], int SIZE) {
double sum, std_sum, mean, std_mean = 0;
double *std_scores = NULL;
std_scores = new double[SIZE];
for (int i = 0; i < SIZE; i++) {
sum += array[i]->getScore;
}
mean = sum / SIZE;
for (int i = 0; i < SIZE; i++) {
std_scores[i] = pow((array[i]->getScore - mean), 2);
std_sum += std_scores[i];
}
std_mean = std_sum / SIZE;
return sqrt(std_mean);
}
On lines 8 and 13 in the above code, I get the following errors:
expression must have pointer type
and
'*': illegal operation on bound member function expression
I'm new to pointer syntax with C++. Any assistance is appreciated.
The short answer to your question is:
sum += answer[i].getScore;
Except that you need to call the function (not just refer to it), so it should be:
sum += answer[i].getScore();
Other problems:
You don't initialize sum to zero.
You leak std_scores. In reverse order of preference:
Delete it with delete [] std_scores at the end of your function.
Declare it as `std::vector std_scores(SIZE);
Don't use an array at all. Just use double score2 = pow((array[i].getScore() - mean), 2);
Finally points:
C++ is not C89 - you should delay declaring your variables until you can give them a value. std_scores is a particularly glaring example of that - you initialize to NULL and then immediately assign a new value. Apart from sum and std_sum (and i) you don't need any non-const variables.
The code would be nicer with std::accumulate
There are better algorithms for calculating mean and standard deviation that are more numerically stable.

Trying to fill a 2d array of structures in C++

As above, I'm trying to create and then fill an array of structures with some starting data to then write to/read from.
I'm still writing the cache simulator as per my previous question:
Any way to get rid of the null character at the end of an istream get?
Here's how I'm making the array:
struct cacheline
{
string data;
string tag;
bool valid;
bool dirty;
};
cacheline **AllocateDynamicArray( int nRows, int nCols)
{
cacheline **dynamicArray;
dynamicArray = new cacheline*[nRows];
for( int i = 0 ; i < nRows ; i++ )
dynamicArray[i] = new cacheline [nCols];
return dynamicArray;
}
I'm calling this from main:
cacheline **cache = AllocateDynamicArray(nooflines,noofways);
It seems to create the array ok, but when I try to fill it I get memory errors, here's how I'm trying to do it:
int fillcache(cacheline **cache, int cachesize, int cachelinelength, int ways)
{
for (int j = 0; j < ways; j++)
{
for (int i = 0; i < cachesize/(cachelinelength*4); i++)
{
cache[i][ways].data = "EMPTY";
cache[i][ways].tag = "";
cache[i][ways].valid = 0;
cache[i][ways].dirty = 0;
}
}
return(1);
}
Calling it with:
fillcache(cache, cachesize, cachelinelength, noofways);
Now, this is the first time I've really tried to use dynamic arrays, so it's entirely possible I'm doing that completely wrong, let alone when trying to make it 2d, any ideas would be greatly appreciated :)
Also, is there an easier way to do write to/read from the array? At the moment (I think) I'm having to pass lots of variables to and from functions, including the array (or a pointer to the array?) each time which doesn't seem efficient?
Something else I'm unsure of, when I pass the array (pointer?) and edit the array, when I go back out of the function, will the array still be edited?
Thanks
Edit:
Just noticed a monumentally stupid error, it should ofcourse be:
cache[i][j].data = "EMPTY";
You should find your happiness. You just need the time to check it out (:
The way to happiness