Passing pointer as argument with std::thread function C++11 - c++

I wanted to pass a pointer to the thread function, but it gives back
error:
attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_In...
Code fragment in main
for (int i = 0; i < threadCount; ++i) {
ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
ptrTabThreads->join();
++ptrTabThreads;
}
And code for checkMin function
void checkMin(int* tab) {
int sizeOfTable = 0;
if (tab == ptrTab[threadCount-1])
sizeOfTable = partSize + additionalNumbers;
else
sizeOfTable = partSize;
mt.lock();
for (int i = 0; i < sizeOfTable; ++i) {
if (tab[i] < minValue) {
minValue = tab[i];
}
}
mt.unlock();
}
Where ptrTab is an array of pointers:
int* ptrTab[threadCount];
Full code is:
#include <iostream>
#include <thread>
#include <condition_variable>
#include <stdlib.h>
#include <climits>
#define threadCount 10
#define numbersCount 75
std::mutex mt;
int minValue = INT32_MAX;
int partSize, additionalNumbers;
int* ptrTab[threadCount];
void checkMin(int value);
void printTab(int *tab);
int main() {
int tab[numbersCount];
srand(time(NULL));
for (int i = 0; i < numbersCount; ++i) {
tab[i] = rand() % 1000;
std::cout << " " << tab[i];
}
partSize = numbersCount / threadCount;
additionalNumbers = numbersCount % threadCount;
for (int i = 0; i < threadCount-1; ++i) {
int *newTab = new int[partSize];
ptrTab[i] = newTab;
}
int *newTab = new int[partSize+additionalNumbers];
ptrTab[threadCount-1] = newTab;
int copiedElements = 0;
for (int i = 0; i < threadCount-1; ++i) {
int *tmpTab = ptrTab[i];
for (int j = 0; j < partSize; j++) {
tmpTab[j] = tab[copiedElements];
copiedElements++;
}
}
int *tmpTab = ptrTab[threadCount-1];
int elementsLeft = numbersCount-copiedElements;
for (int i = 0; i < elementsLeft; ++i) {
tmpTab[i] = tab[copiedElements];
copiedElements++;
}
/*for (int i = 0; i < threadCount; ++i) {
printTab(ptrTab[i]);
}*/
//----------------------
std::thread tabThreads[threadCount];
std::thread *ptrTabThreads = tabThreads;
for (int i = 0; i < threadCount; ++i) {
ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
ptrTabThreads->join();
++ptrTabThreads;
}
std::cout << "\n\n" << minValue << "\n\n";
//for check
std::cout << "for check: minimal value is ";
int min = INT32_MAX;
for (int i = 0; i < numbersCount; ++i) {
if (tab[i] < min) {
min = tab[i];
}
}
std::cout << min << "\n\n";
}
void checkMin(int* tab) {
int sizeOfTable = 0;
if (tab == ptrTab[threadCount-1])
sizeOfTable = partSize + additionalNumbers;
else
sizeOfTable = partSize;
mt.lock();
for (int i = 0; i < sizeOfTable; ++i) {
if (tab[i] < minValue) {
minValue = tab[i];
}
}
mt.unlock();
}
void printTab(int *tab) {
for (int i = 0; i < 10; ++i) {
std::cout << tab[i] << " ";
}
std::cout << "\n\n";
}
Thank you for all your advices.

The immediate problem which triggers compilation error is right here:
void checkMin(int value);
This is the prototype of your function, and it is incorrect - it should be
void checkMin(int* value); //<-- not the pointer.
But this is not the only one! Your code makes no sense. Look at this fragment:
std::thread tabThreads[threadCount];
std::thread *ptrTabThreads = tabThreads;
for (int i = 0; i < threadCount; ++i) {
ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
ptrTabThreads->join();
++ptrTabThreads;
}
What's the purpose of all this jumping with pointers? You also have a leak in your code, since you are modifying the pointer you obtained from new before deleteing it. Why not use following simple code?
std::array<std::thread, threadCount> tabThreads;
for (int i = 0; i < threadCount; ++i) {
tabThreads[i] = std::thread(checkMin, ptrTab[i]);
tabThreads[i].join();
}
This still serves no pratical purpose (application remains effectively single-threaded, since you join your thread right after creating it), but at least, the code is correct. To really do some fancy multithreading, you need your loop to look like following:
for (int i = 0; i < threadCount; ++i)
tabThreads[i] = std::thread(checkMin, ptrTab[i]);
for (std::thread& t : tabThreads) // so-called range-for loop. Nice thing!
t.join();
This will paralellize stuff!

Related

how to solve a weighted completion time minimization problem to cplex/c++?

a scheduling problem that wants to minimize a weighted completion time
I would like to pass the image problem to the c++ language and solve it with cplex solver.
Problem:
Min ∑WiCi
xi ∈ 0,1
t= ∆ + ∑_{i} xi*pi1
Ci1 = ∑_{j=1}^{i} xj*pj1
Ci2 = t + ∑_{j=1}^{i} (1−xj)*pj2
Ci ≥ Ci1
Ci ≥ Ci2−Ωxi
Ω = ∆ + ∑_i max(pi1, pi2)
The goal is to minimize the weighted completion time of a problem with one machine with at most one machine reconfiguration. I have a boolean variable Xi that tells me if the job is done before or after the reconfiguration. The variable t is the instant after the reconfiguration(delta is the time to reconfigure the machine). pi1 is the processing time in configuration 1 and pi2 is the processing time in configuration 2. Besides, I have restrictions due to Ci (completion time of a job i).
The example of code I made is not working. I know I have a problem writing the C variable (but I don't know how to solve it).
#include <iostream>
#include <ilcplex/ilocplex.h>
#include <ilcp/cp.h>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int nbJob = 4;
int delta = 2;
int nbConf = 2;
vector<int> w_job;
w_job.push_back(1); w_job.push_back(1); w_job.push_back(1); w_job.push_back(1);
vector<vector<int>>p_job;
p_job.resize(nbJob);
p_job[0].push_back(6); p_job[0].push_back(3);
p_job[1].push_back(1); p_job[1].push_back(2);
p_job[2].push_back(10); p_job[2].push_back(2);
p_job[3].push_back(1); p_job[3].push_back(9);
int max_p = 0;
int aux;
for (size_t i = 0; i < nbJob - 1; i++) {
aux = max(p_job[i][0], p_job[i][1]);
max_p = max(max_p, aux);
}
cout << max_p << endl;
int max_w = 0;
aux = 0;
for (size_t i = 0; i < nbJob - 1; i++) {
aux = max(w_job[i], w_job[i + 1]);
max_w = max(aux, max_w);
}
cout << max_w << endl;
int omega = 0;
for (size_t i = 0; i < nbJob; i++) {
omega += max(p_job[i][0], p_job[i][1]);
}
omega += delta;
cout << omega << endl;
try {
IloEnv env;
IloModel model(env);
IloBoolVarArray x(env, nbJob);
for (size_t i = 0; i < nbJob; i++) {
IloBoolVar xi(env, 0, 1, "xi");
x[i] = xi;
}
IloArray<IloExprArray> C(env, nbJob);
for (size_t i = 0; i < nbJob; i++) {
IloExprArray Ci(env);
for (size_t j = 0; j < nbConf; j++) {
IloExpr Cij(env);
Ci.add(Cij);
}
C[i] = Ci;
}
IloNumVarArray C_final(env, nbJob);
for (size_t i = 0; i < nbJob; i++) {
IloNumVar C_finali(env, 0, IloInfinity, ILOINT); //
C_final[i] = C_finali;
}
IloExpr t(env);
for (int i = 0; i < nbJob; i++) {
t += x[i] * p_job[i][0];
}
t += delta;
for (size_t i = 0; i < nbJob; i++) {
for (size_t j = 0; j < nbJob; j++) {
if (j <= i) {
C[i][0] += x[j] * p_job[j][0];
}
}
}
for (size_t i = 0; i < nbJob; i++) {
for (size_t j = 0; j < nbJob; j++) {
if (j <= i) {
C[i][1] += ((1 - x[j]) * p_job[j][1]);
}
}
C[i][1] += t;
}
for (size_t i = 0; i < nbJob; i++) {
model.add(C_final[i] >= C[i][0]);
}
for (size_t i = 0; i < nbJob; i++) {
model.add(C_final[i] >= C[i][1] - (omega * x[i]));
}
IloExpr wiCi(env);
for (size_t i = 0; i < nbJob; i++) {
wiCi += w_job[i] * C_final[i];
}
model.add(IloMinimize(env, wiCi));
IloCplex solver(model);
solver.solve();
for (int i = 0; i < nbJob; i++) {
cout << "C " << i + 1 << " = " << solver.getValue(C_final[i]) << " x" << i+1 << " = " << solver.getValue(x[i]) << endl;
}
cout << endl;
cout << "t = " << solver.getValue(t) << endl;
cout << "wiCi = " << solver.getObjValue() << endl << endl;
}
catch (IloException e) {
cout << e.getMessage();
}
}

Magic Number output

Alright so I have created this code. However, when i run it, it stops when it displays 104 for the counter??? I am so frustrated because I don't know how this could happen. The purpose of the code is to do the typical magic number output where the rows all add up to the same thing, the columns all add up to the same thing, and the diaganols all add up to the same thing. I believe the functions to do these calculations are correct, but the counter keeps stopping short of the 10000 attempts I am trying to do.
#include <iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
void getrandom();
void insertnumber(int n);
bool magic();
void create();
const int rows = 3;
const int cols = 3;
int arr[rows][cols] = { {0,0,0}, {0,0,0} , {0,0,0} };
int main() {
int counter = 0;
do
{
counter++;
cout << counter << endl;
getrandom();
if (counter == 100000)
break;
} while (!magic());
create();
cout << "It took " << counter << " tries." << endl;
return 0;
}
void getrandom() {
int n = 0;
const int size = 9;
int oldnum[size];
for (int i = 0; i < rows * cols; i++) {
oldnum[i] = 0;
}
srand(time(NULL)); // had to import the new libraries to use this
bool used = true;
for (int i = 0; i < size; i++) {
do
{
used = true;
n = rand() % 9 + 1;
if (oldnum[n - 1] == 0)
{
oldnum[n - 1] = n;
used = false;
}
} while (used);
insertnumber(n);
}
}
void insertnumber(int n) {
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
if (arr[i][j] == 0) {
arr[i][j] = n;
return;
}
}
}
}
bool magic() {
int rowsum = arr[0][0] + arr[0][1] + arr[0][2];
for (int i = 1; i < cols; i++)
{
if (arr[i][0] + arr[i][1] + arr[i][2] != rowsum)
return false;
}
for (int j = 0; j < rows; j++)
{
if (arr[0][j] + arr[1][j] + arr[2][j] != rowsum)
return false;
}
if (arr[0][0] + arr[1][1] + arr[2][2] != rowsum)
return false;
if (arr[0][2] + arr[1][1] + arr[2][0] != rowsum)
return false;
return true;
}
void create() {
{
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
}
You can try using a debugger for such problems.
I think you code crashes because of this:
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
It looks like you mean j < cols here :)
Check line 76. When I compile and run the code, line 76 is where the exception is thrown.
This line specifically
arr[i][j] = n;
It seems your insertnumber() function is the culprit.

Transpose matrix: swapping elements doesn't alter values

I am trying to transpose a matrix built with vectors.
Here is the transpose function I wrote:
void transpose(std::vector<std::vector<int>>& fill_mat) {
for (int i = 0; i < fill_mat.size(); ++i) {
for (int j = 0; j < fill_mat.size(); ++j) {
std::swap(fill_mat[i][j], fill_mat[j][i]);
}
}
}
It doesn't seem to be doing anything: my final results are the same as the starting ones.
Here is my full program:
#include<iostream>
#include<vector>
#include<utility>
void print_matrix(std::vector<std::vector<int>>& to_print) {
for (int i = 0; i < to_print.size(); ++i) {
for (int j = 0; j < to_print.size(); ++j) {
std::cout << " " << to_print[i][j];
}
std::cout << std::endl;
}
}
void make_matrix(std::vector<std::vector<int>>& fill_mat) {
for (int i = 0; i < fill_mat.size(); ++i) {
for (int j = 0; j < fill_mat.size(); ++j) {
fill_mat[i][j] = rand() % 15;
}
}
}
void transpose(std::vector<std::vector<int>>& fill_mat) {
for (int i = 0; i < fill_mat.size(); ++i) {
for (int j = 0; j < fill_mat.size(); ++j) {
std::swap(fill_mat[i][j], fill_mat[j][i]);
}
}
}
int main() {
int size = 3;
std::vector<std::vector<int>> matrix_sample(size, std::vector<int>(size));
make_matrix(matrix_sample);
print_matrix(matrix_sample);
transpose(matrix_sample);
std::cout << "----## transpose ##-----" << std::endl;
print_matrix(matrix_sample);
}
I expected to print out the transposed matrix but the input ends up being the same as the output. What am I doing wrong?
You swap (i,j) with (j,i) twice! That's why it has no effect.
You should only work on one half of your matrix. Plus minors improvements, we get:
void transpose(std::vector<std::vector<int>>& fill_mat)
{
using size_type = decltype(fill_mat)::size_type; // better use your matrix' size type
for (size_type i = 0; i < fill_mat.size(); ++i) {
for (size_type j = 0; j < i; ++j) {
using std::swap; // see swap idiom
swap(fill_mat[i][j], fill_mat[j][i]);
}
}
}

Adding two 2D arrays together in C++ - Why do this program crash?

Hey I am beginner at C++ programming. I have made a program that is meant to add two 2D arrays together. However, The program outputs the values until the program crashes. Can someone help me to identify the problem?
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int a[10][10], c[10][10], i, j;
for (i = 1; i <= 10; ++i)
{
for(j=0; j < 10; ++j)
{
a[i][j] = i * j;
}
}
// We are able to treat the individual columns as arrays
for (int i = 0; i < 10; ++i)
{
int *b = a[i];
for (int j = 0; j < 10; ++j)
{
cout << b[j] << " ";
}
cout << endl;
}
cout << "****" << endl;
// Declare a multidimensional array on the heap
int **b = new int*[10];
// need to allocate all members individually
for (int i = 0; i < 10; ++i)
{
b[i] = new int[10];
}
// Set the values of b
for (int i = 0; i < 10; ++i)
{
for (j = 0; j < 10; ++j)
{
b[i][j] = (i * 10) + j;
}
}
for (i = 0; i < 10; ++i)
{
for (j = 1; j <= 10; ++j)
{
c[i][j] = a[i][j] + b[i][j];
}
}
for (i = 0; i < 10; ++i)
{
for (j = 1; j <= 10; ++j)
{
cout << c[i][j] << endl;
}
}
// Delete the multidimensional array - have to delete each part
for (int i = 0; i < 10; ++i)
{
delete[] b[i];
}
delete[] b;
return 0;
}
I corrected your code.Now, It's working and program didn't crash. You can try it out.
#include<conio.h>
#include<iostream.h>
int main(int argc, char** argv)
{
int a[10][10], c[10][10], i, j;
for (i = 0; i <10; ++i)
{
for(j=0; j < 10; ++j)
{
a[i][j] = i * j;
}
}
//We are able to treat the individual columns as arrays;
for (i = 0; i < 10; ++i)
{
int *b = a[i];
for (int j = 0; j < 10; ++j)
{
cout << b[j] << " ";
}
cout << endl;
}
cout << "****" << endl;
//Declare a multidimensional array on the heap;
int **b = new int*[10];
//need to allocate all members individually
for (i = 0; i < 10; ++i)
{
b[i] = new int[10];
}
//Set the values of b
for ( i = 0; i < 10; ++i)
{
for (j = 0; j < 10; ++j)
{
b[i][j] = (i * 10) + j;
}
}
for (i = 0; i < 10; ++i)
{
for (j = 0; j <10; ++j)
{
c[i][j] = a[i][j] + b[i][j];
}
}
for (i = 0; i < 10; ++i)
{
for (j = 0;j < 10; ++j)
{
cout << c[i][j] << " ";
}
cout<<endl;
}
// Delete the multidimensional array - have to delete each part
for (i = 0; i < 10; ++i)
{
delete[] b[i];
}
delete[] b;
return 0;
}

Shouldn't this recursive method end as soon as you get to the return?

I would like to know why my output is:
a-b-b-b-b-0
When I think it should just be a-1.
Shouldn't a recursive method end as soon as you get to a return? and why doesn't it here?
I only put the letters with '-' to clarify that the returns are being met but not stopping there.
#include <stdio.h>
#include <iomanip>
#include <iostream>
using namespace std;
void printv(int mask[], int elements[], int n)
{
int i;
printf("{ ");
for (i = 0; i < n; i++)
if (mask[i])
printf("%d ", elements[i]);
printf("}");
}
int next(int mask[], int size)
{
int i;
for (i = 0; (i < size) && mask[i]; i++)
mask[i] = 0;
if (i < size) {
mask[i] = 1;
return 1;
}
return 0;
}
void nSubsets(int mask[], int elements[], int size, int n)
{
int sum = 0;
int temp[10], count = 0;
for (int i = 0; i < 10; i++) //this MUST be here
temp[i] = 0;
for (int i = 0; i < size; i++)
{
if (mask[i])
{
count++;
for (int k = 0; k < 44; k++)
if (temp[k] == 0)
{
temp[k] = elements[i];
sum += elements[i];
break;
}
}
}
if (sum == n)
{
cout << "{ ";
for (int l = 0; l < count; l++)
cout << temp[l] << " ";
cout << "}";
}
}
int isEmptySet(int mask[], int elements[], int size, int n, int sizeRecursion)
{
int sum = 0;
int temp[10], count = 0;
for (int i = 0; i < 10; i++) //this MUST be here
temp[i] = 0;
for (int i = 0; i < size; i++)
{
if (mask[i])
{
count++;
for (int k = 0; k < 44; k++)
if (temp[k] == 0)
{
temp[k] = elements[i];
sum += elements[i];
break;
}
}
}
if (sum == n)
{
cout << "a-";
return 1;
}
sizeRecursion--;
if (sizeRecursion > 0)
{
next(mask, size);
isEmptySet(mask, elements, size, n, sizeRecursion);
}
cout << "b-";
return 0;
}
int main()
{
int n, size = 10;
int elements[size];
size = 6; n = 5;
elements[0] = 5;
elements[1] = 2;
elements[2] = 3;
elements[3] = 2;
elements[4] = 1;
elements[5] = 1;
int mask[10];
int i;
for (i = 0; i < size; ++i)
mask[i] = 0;
cout << "Subsets of elements: ";
printv(mask, elements, size); //this prints first subset
while (next(mask, size))
printv(mask, elements, size);
n = 3;
cout << "\nSubsets equal to " << n << "\n";
while (next(mask, size))
nSubsets(mask, elements, size, n);
cout << "\n" << isEmptySet(mask, elements, size, n, size);
return 0;
}
Shouldn't a recursive method end as soon as you get to a return? and why doesn't it here?
No, the way it works in general is that when a function call returns, it only returns for that function call, and then the immediate caller may continue execution. It doesn't matter whether the function is recursive or not, each function call is separate and each call needs to hit a return statement at some point (unless the return type is void).
When you have this code
...
if(sizeRecursion > 0)
{
next(mask,size);
isEmptySet(mask, elements, size, n,sizeRecursion);
}
cout<<"b-";
return 0;
}
What's going to happen is, as soon as the recursive call to isEmptySet returns, its going to go right to the cout << "b-"; line and then to return 0;. If you don't want that then you should put those in an else block, and maybe also modify the line that calls isEmptySet so that it returns the value returned from that call.