29 #include "SolverConfig.h" 
   42         EXIT_WITH_SUCCESS = 0,
 
   43         INVALID_PARAMETER = 1,
 
   44         INPUT_OUTPUT_ERROR = 2,
 
   58         cout<<
"Energy optimizator of robotic cells."<<endl;
 
   59         cout<<
"Authors: Libor Bukata and Premysl Sucha"<<endl;
 
   60         cout<<
"Licence: GNU General Public License"<<endl;
 
   61         cout<<
"Program version: "<<PROGRAM_VERSION<<endl;
 
   63         cout<<
"Build type: "<<BUILD_TYPE<<endl;
 
   73         cout<<endl<<
"Usage:"<<endl;
 
   74         cout<<
"\t"<<progName<<
" [options] --dataset FILE"<<endl<<endl;
 
   75         cout<<
"General options:"<<endl;
 
   76         cout<<
"\t--dataset ARG, -d ARG, ARG: FILE"<<endl;
 
   77         cout<<
"\t\tThe input dataset to solve (an xml file)."<<endl;
 
   78         cout<<
"\t--verbose, -v"<<endl;
 
   79         cout<<
"\t\tAn additional information is printed (solver progress, runtime, etc.)."<<endl;
 
   80         cout<<
"\t--number-of-segments ARG, -nos ARG, ARG: INTEGER"<<endl;
 
   81         cout<<
"\t\tThe number of segments of each discretized energy function."<<endl;
 
   82         cout<<
"\t--number-of-threads ARG, -not ARG, ARG: INTEGER"<<endl;
 
   83         cout<<
"\t\tThe number of concurrent threads (default is autodetect)."<<endl;
 
   84         cout<<
"\t--help, -h"<<endl;
 
   85         cout<<
"\t\tIt prints this help."<<endl;
 
   86         cout<<
"\t--max-runtime ARG, -mr ARG, ARG: FLOAT"<<endl;
 
   87         cout<<
"\t\t"<<
"It sets the time limit per instance for a selected algorithm (in seconds)."<<endl;
 
   88         cout<<
"\t--use-heuristic-algorithm, -uha"<<endl;
 
   89         cout<<
"\t\t"<<
"A heuristic algorithm is employed to solve instances."<<endl;
 
   90         cout<<
"\t--use-exact-algorithm, -uea"<<endl;
 
   91         cout<<
"\t\t"<<
"An exact algorithm is preferred as a problem solver."<<endl;
 
   92         cout<<
"\t--write-results ARG, -wr ARG, ARG: DIRECTORY"<<endl;
 
   93         cout<<
"\t\tIt specifies where the solutions, error logs, and performance logs will be written."<<endl<<endl;
 
   94         cout<<
"ILP solver options:"<<endl;
 
   95         cout<<
"\t--ilp-solver-relative-gap ARG, -isrg ARG, ARG: DECIMAL"<<endl;
 
   96         cout<<
"\t\tIt stops the solver after achieving the relative gap between the best integer solution and lower bound."<<endl;
 
   97         cout<<
"\t\tSetting the gap to 0.05 means that solver stops after proving 5 % maximal gap from the optimal solution."<<endl;
 
   98         cout<<
"\t--lower-bound-calculation, -lbc"<<endl;
 
   99         cout<<
"\t\tIt turns on the calculation of a tighter lower bound by using a problem decomposition and an ILP solver."<<endl;
 
  100         cout<<
"\t--lower-bound-runtime ARG, -lbr ARG, ARG: FLOAT"<<endl;
 
  101         cout<<
"\t\tIt sets a time limit for the tight lower bound calculation."<<endl<<endl;
 
  102         cout<<
"Heuristic options:"<<endl;
 
  103         cout<<
"\t--number-of-elite-solutions ARG, -noes ARG, ARG: INTEGER"<<endl;
 
  104         cout<<
"\t\tThe maximal number of elite solutions in the pool."<<endl;
 
  105         cout<<
"\t--max-number-of-alternatives ARG, -mnoa ARG, ARG: INTEGER"<<endl;
 
  106         cout<<
"\t\tThe maximal number of alternatives to consider for each robot."<<endl;
 
  107         cout<<
"\t--minimal-number-of-iters-per-tuple ARG, -mnoipt ARG, ARG: INTEGER"<<endl;
 
  108         cout<<
"\t\tThe minimal number of runs of sub-heuristics for each feasible solution. Sub-heuristics, i.e."<<endl;
 
  109         cout<<
"\t\t(de)select power mode, change locations, and change path, are executed in the round robin order."<<endl<<endl;
 
  110         cout<<
"Default settings can be modified at \"DefaultSettings.h\" file."<<endl;
 
  132         if (number.empty() || number[0] == 
'-')
 
  133                 throw InvalidArgument(caller(), 
"Argument must be a positive number!");
 
  136         istringstream istr(number, istringstream::in);
 
  154 bool getArgument(
int& i, 
int argc, 
char* argv[], 
const string& fullName, 
const string& shortName, 
string& writeArgument)        {
 
  155         string arg = argv[i];
 
  156         if (arg == fullName || arg == shortName)        {
 
  158                         writeArgument = argv[++i];
 
  161                         throw InvalidArgument(caller(), 
"'"+fullName+
"' requires the argument!");
 
  178 bool processArg(
int& i, 
int argc, 
char* argv[], 
const string& fullName, 
const string& shortName, 
bool* toWrite = 
nullptr)       {
 
  179         string arg = argv[i];
 
  180         if (arg == fullName || arg == shortName)        {
 
  181                 if (toWrite != 
nullptr)
 
  199 bool processArg(
int& i, 
int argc, 
char* argv[], 
const string& fullName, 
const string& shortName, 
string& toWrite)       {
 
  200         return getArgument(i, argc, argv, fullName, shortName, toWrite);
 
  216 bool processArg(
int& i, 
int argc, 
char* argv[], 
const string& fullName, 
const string& shortName, T& toWrite, T minValue = 1)    {
 
  218         if (
getArgument(i, argc, argv, fullName, shortName, strNumber)) {
 
  221                         number = parsePositiveNumber<T>(strNumber);
 
  223                          throw_with_nested(
InvalidArgument(caller(), 
"Cannot read the parameter of '"+fullName+
"' option!"));
 
  226                 if (number >= minValue) {
 
  230                         throw InvalidArgument(caller(), 
"The '"+fullName+
"' parameter needs to be a positive number!");
 
  245         for (
int i = 1; i < argc; ++i)  {
 
  251                 if (
processArg(i, argc, argv, 
"--help", 
"-h") == 
true)  {
 
  270                 throw InvalidArgument(caller(), 
"Unknown argument \""+
string(argv[i])+
"\"!");
 
  274                 throw InvalidArgument(caller(), 
"Insufficient number of parameters! At least a dataset must be specified!");
 
  298 int main(
int argc, 
char* argv[])        {
 
  305                                 return EXIT_WITH_SUCCESS;
 
  308                         return EXIT_WITH_SUCCESS;
 
  317                 const vector<RoboticLine>& lines = reader.dataset();
 
  318                 const vector<PrecalculatedMapping>& mappings = reader.precalculatedMappings();
 
  321                 for (uint32_t lineId = 0; lineId < min(lines.size(), mappings.size()); ++lineId)        {
 
  330                                 solution = solver.
solve();
 
  333                                 solution = solver.
solve();
 
  346                                         cout<<solution<<endl;
 
  361                                 cerr<<
"Solution of instance "<<lineId<<
" is invalid:"<<endl;
 
  368                                         ofstream errorLog(instanceErrorFile.c_str());
 
  369                                         if (errorLog.good())    {
 
  371                                                         errorLog<<errMsg<<endl;
 
  373                                                 cerr<<
"Cannot open an error log for instance "<<lineId<<
"!"<<endl;
 
  384                 cerr<<
"\nProjectSolver: Cannot read the input dataset!"<<endl;
 
  385                 return INPUT_OUTPUT_ERROR;
 
  388                 return INVALID_PARAMETER;
 
  391                 cerr<<
"\nProjectSolver: A runtime error occurred, terminating..."<<endl;
 
  392                 return RUNTIME_ERROR;
 
  393         } 
catch (
const exception& e)    {
 
  395                 return UNKNOWN_ERROR;
 
  399         return EXIT_WITH_SUCCESS;
 
bool USE_EXACT_ALGORITHM
The variable indicates whether the exact algorithm should be used. 
 
double ILP_RELATIVE_GAP
If a given relative gap from the best known lower bound is achieved, then the solver stops...
 
bool processCommandLineArguments(int argc, char *argv[])
It parses the program arguments and sets the desired parameters for optimization. ...
 
The structure representing a solution found by an algorithm. 
 
uint32_t MAX_ALTERNATIVES
The maximal number of alternative orders generated for each robot. 
 
std::string exceptionToString(const std::exception &e, uint32_t level=0)
The recursive method creates the formatted error message for the given exception and their nested sub...
 
uint32_t NUMBER_OF_SEGMENTS
By how many segments (linear pieces) the energy function of the movement is approximated. 
 
string DATASET_FILE
Dataset with problems to be solved. 
 
ProgramReturnedCodes
Return codes of the program with obvious meanings. 
 
void printProgramHelp(const string &progName)
It prints the program header and brief help. 
 
The class is intended to be used by users for the dataset parsing and checking. 
 
Solution solve()
It optimizes the robotic cell and returns the best found solution. 
 
An instance of this class is devoted to the solution checking. 
 
int main(int argc, char *argv[])
An entry point of the program, arguments are processed, dataset is parsed and solved, and results printed and optionally written to files. 
 
Checking and post-processing of parsed datasets. 
 
A general exception of the program. 
 
bool CALCULATE_LOWER_BOUND
Indicates whether a tight lower bound should be calculated. 
 
double RUNTIME_OF_LOWER_BOUND
Time limit for the tight lower bound. 
 
Solution solve(double relGap=Settings::ILP_RELATIVE_GAP, double timLim=Settings::MAX_RUNTIME) const 
ILP solver optimizes the energy consumption of the robotic cell until a stop criterion is reached...
 
std::vector< std::string > errorMessages() const 
It returns error message(s) describing why the solution is invalid. 
 
uint32_t MAX_ELITE_SOLUTIONS
The number of top solutions maintained by the heuristic. 
 
bool VERBOSE
Boolean flag determining verbosity of the program. 
 
uint32_t NUMBER_OF_THREADS
Maximal number of threads to be used. 
 
bool checkAll()
It calls the private member methods to verify the solution. 
 
Thrown if the dataset file contains ill-specified robotic cells. 
 
The file defines extended exceptions for the better error handling in the program. 
 
An exact solver for the energy optimization problem. 
 
Solver-independent interface for solving Integer Linear Programming problems. 
 
Exception is thrown if a method is given invalid parameters or a user provides invalid program argume...
 
State status
Enum specifying whether the solution is optimal, feasible, or infeasible... 
 
#define DEFAULT_USE_HEURISTICS
It specifies whether the heuristic algorithm should be preferred by default. 
 
void writeBriefResultToCsvFile(const std::string &instanceName, const std::string &pathToFile, const Solution &s)
It writes the solution to the file in the same format as writeBriefResultToStream function...
 
static double lowerBoundOnEnergy(const std::vector< Robot * > &robots, const PrecalculatedMapping &m)
A tight lower bound on the energy consumption. 
 
std::string solverIdentification()
Returns an identification of the used solver, e.g. 'Gurobi 6.0.4'. 
 
bool processArg(int &i, int argc, char *argv[], const string &fullName, const string &shortName, bool *toWrite=nullptr)
It processes the arguments without parameters. 
 
A parallel hybrid heuristic solving the energy optimization problem of robotic cells. 
 
It declares the namespace for program settings. 
 
A parallel heuristic for the energy optimization of robotic cells. 
 
void printProgramHeader()
It prints a brief description of the program including the authors, license, ILP solver, and version. 
 
string RESULTS_DIRECTORY
If not empty, then the optimization results will be written to this directory. 
 
void writeSolutionToCsvFile(const string &file, const Solution &s, const PrecalculatedMapping &mapper)
It writes the solution to a csv file, the header is 'activity id, start time, duration, type, point, power saving mode, movement, energy'. 
 
uint32_t MIN_ITERS_PER_TUPLE
The minimal number of optimization iterations per each tuple. 
 
A representation of the solution that is algorithm independent. 
 
double lowerBound
Lower bound on energy, i.e. there is not a solution consuming less energy than this number...
 
#define DEFAULT_USE_EXACT_ALGORITHM
It specifies whether the exact algorithm should be preferred by default. 
 
The file declares a class responsible for checking of solutions. 
 
void writeBriefResultToStream(std::ostream &OUT, const string &instanceName, const Solution &s)
It prints the solution as follows: 'instance name (state, runtime s): energy'. 
 
The robotic cell corresponds to an instance of this class. 
 
The structure contains the maps for fast searching in the robotic cell. 
 
void readInstances()
It processes the dataset specified in Settings::DATASET_FILE. 
 
bool getArgument(int &i, int argc, char *argv[], const string &fullName, const string &shortName, string &writeArgument)
It processes the arguments with one parameter. 
 
RoboticLineSolverILP class, declared in this file, addresses the energy optimization problem of robot...
 
T parsePositiveNumber(const string &number)
 
double MAX_RUNTIME
Maximal run time of the solver. 
 
bool USE_HEURISTICS
The variable indicates whether the heuristic should be used.