This loops through a vector of vector of A and adds a smaller array to a bigger one at a specified position+random shift. Then it is checked if it is a better solution, and if yes, it is stored, else it is discarded. I have already parallelized it.
Can this be improved to run faster?
I am not sure if a vector<vector<struct>>
is a good idea, or maybe there is a better memory management to use better cache effects. The struct
is currently global and since it is only readable by the threads all threads use the same instance.
I am using C++11 threads.
Description of what the program does:
We have a big array, rand_val
, and we have many small arrays, Leistungskurve
. We can add these array to rand_val
at a fixed position + random shift. We want to find a valid position for each array so the max element in rand_val
is minimized. In the array, rand
is stated which position we have chosen.
#include <iostream>
#include <string>
#include <vector>
#include <time.h>
#include <cmath>
#include <iterator>
#include <algorithm>
#include <fstream>
#include <stdlib.h>
#include <sstream>
#include <stdlib.h>
#include <thread>
#include <random>
using namespace std;
struct Teilstrecke {
int StreckenNr;
int Fahrzeit;
int Haltezeit;
int FruehesteAbfahrt;
int SpaetesteAbfahrt;
int Abfahrtsintervall;
double *Leistungskurve;
};
struct Zug {
int ZugNr;
int AnzahlStrecken;
vector<Teilstrecke> Teilstrecken;
};
vector<Zug> Zuege;
int Planungsintervall;
int AnzahlZuege;
int AnzahlSchattenzuege;
inline double maxArray(double *arr, int size)
{
double max = 0;
int pos = 0;
for (int i = 0; i < size; i++)
{
if (arr[i] > max)
{
max = arr[i];
pos = i;
}
}
return pos;
}
inline void addArray(double *arr1, double *arr2, int size2, int pos)
{
for (int i = 0; i < size2; i++)
{
arr1[pos+i] += arr2[i];
}
}
inline void addArray(double *arr1, Teilstrecke ts, int shift)
{
addArray(arr1, ts.Leistungskurve, ts.Fahrzeit*600+1, (ts.FruehesteAbfahrt+shift)*600);
}
inline void randomSolution(int *rand, double *rand_val);
inline int randomNumber(int low, int high) // has to be replaced to c++11 random
{
return rand() % (high - low + 1) + low;
}
void wrapper()
{
int size = Planungsintervall*600+1;
int *rand = new int[AnzahlSchattenzuege];
fill_n(rand, AnzahlSchattenzuege, 0);
double *rand_val = new double[size];
fill_n(rand_val, size, 0);
int max_iter = 1000000;
double best_max = 1e20;
int *rand_best = new int[AnzahlSchattenzuege];
for (int i = 0; i < max_iter; i++)
{
randomSolution(rand, rand_val);
double max = maxArray(rand_val, size);
//cout << max << '\n';
if (max < best_max)
{
best_max = max;
memcpy(rand_best, rand, sizeof(int)*AnzahlSchattenzuege);
}
fill_n(rand, AnzahlSchattenzuege, 0);
fill_n(rand_val, size, 0);
}
cout << best_max << ' ' << '\n';
}
inline void randomSolution(int *rand, double *rand_val)
{
int pos2 = 0;
for (int i = 0; i < AnzahlZuege; i++)
{
for (int j = 0; j < Zuege.at(i).AnzahlStrecken; j++)
{
Teilstrecke ts = Zuege.at(i).Teilstrecken.at(j);
int k = randomNumber(0, ts.Abfahrtsintervall);
rand[pos2+k] = 1;
addArray(rand_val, ts, k);
pos2 += ts.Abfahrtsintervall + 1;
}
}
}
void read_input(char *read_file);
int main(int argc, char** argv)
{
read_input((char*)argv[1]);
vector<thread> threads;
for (int i = 0; i < 7; i++)
{
threads.push_back(thread(wrapper));
}
wrapper();
for (int i = 0; i < 7; i++)
{
threads.at(i).join();
}
}
Profiling
It seems that all work is done in addArray
.