main optimizes a pair of patterns of which the filepath is given as cl arguments. The user can additionally define the number of function calls and the directory in which the program should export the results.

This commit is contained in:
Iason 2021-02-18 15:33:31 +02:00
parent ae645b27d2
commit 9a225439cf
2 changed files with 99 additions and 247 deletions

View File

@ -16,245 +16,61 @@
#include <string> #include <string>
#include <vcg/complex/algorithms/update/position.h> #include <vcg/complex/algorithms/update/position.h>
void exportOptimizationResults(
const ReducedModelOptimizer::Results &optimizationResults,
const std::filesystem::path &optimizationDirectory,
const ReducedModelOptimizer::Settings &settings_optimization,
csvFile &statistics,
const std::pair<FlatPattern *, FlatPattern *> patternPair) {
std::filesystem::path saveToPath(std::filesystem::path(optimizationDirectory)
.append(patternPair.first->getLabel() +
"@" +
patternPair.second->getLabel()));
std::filesystem::create_directories(std::filesystem::path(saveToPath));
optimizationResults.save(saveToPath.string());
statistics << patternPair.first->getLabel() + "@" +
patternPair.second->getLabel();
statistics << optimizationResults.objectiveValue;
for (const double &optimalX : optimizationResults.x) {
statistics << optimalX;
}
for (int unusedXVarCounter = 0;
unusedXVarCounter <
settings_optimization.xRanges.size() - optimizationResults.x.size();
unusedXVarCounter++) {
statistics << "-";
}
statistics << optimizationResults.time;
if (optimizationResults.numberOfSimulationCrashes == 0) {
statistics << "No crashes";
} else {
statistics << optimizationResults.numberOfSimulationCrashes;
}
statistics << endrow;
}
void optimizeTestSet(
const std::vector<std::pair<FlatPattern *, FlatPattern *>> patternPairs,
const ReducedModelOptimizer::Settings &settings_optimization,
const std::string &saveTo) {
const std::string optimizationSettingsString =
settings_optimization.toString();
std::filesystem::path thisOptimizationDirectory(
std::filesystem::path(saveTo).append(optimizationSettingsString));
//.append("Results"));
std::filesystem::create_directories(thisOptimizationDirectory);
std::cout << optimizationSettingsString << std::endl;
csvFile csv_settings(std::filesystem::path(thisOptimizationDirectory)
.append("settings.csv")
.string(),
true);
settings_optimization.writeTo(csv_settings);
csvFile statistics(std::filesystem::path(thisOptimizationDirectory)
.append("statistics.csv")
.string(),
false);
// Write header to csv
statistics << "FullPattern@ReducedPattern"
<< "Obj value";
for (const ReducedModelOptimizer::xRange &range :
settings_optimization.xRanges) {
statistics << range.label;
}
statistics << "Time(s)";
statistics << "#Crashes";
statistics << endrow;
double totalError = 0;
int totalNumberOfSimulationCrashes = 0;
std::vector<ReducedModelOptimizer::Results> optimizationResults_testSet(
patternPairs.size());
auto start = std::chrono::high_resolution_clock::now();
int pairsOptimized = 0;
#pragma omp parallel for
for (int patternPairIndex = 0; patternPairIndex < patternPairs.size();
patternPairIndex++) {
const std::pair<FlatPattern *, FlatPattern *> &patternPair =
patternPairs[patternPairIndex];
std::cout << "Optimizing " << patternPair.first->getLabel() << "@"
<< patternPair.second->getLabel() << std::endl;
const std::vector<size_t> numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1};
ReducedModelOptimizer optimizer(numberOfNodesPerSlot);
optimizer.initializePatterns(*patternPair.first, *patternPair.second, {});
ReducedModelOptimizer::Results optimizationResults =
optimizer.optimize(settings_optimization);
totalError += optimizationResults.objectiveValue;
optimizationResults_testSet[patternPairIndex] = optimizationResults;
totalNumberOfSimulationCrashes +=
optimizationResults.numberOfSimulationCrashes;
std::cout << "Optimized " << ++pairsOptimized << "/" << patternPairs.size()
<< std::endl;
#pragma omp critical
{
exportOptimizationResults(optimizationResults, thisOptimizationDirectory,
settings_optimization, statistics, patternPair);
optimizationResults.draw();
}
}
// for (int patternPairIndex = 0; patternPairIndex < patternPairs.size();
// patternPairIndex++) {
// const std::pair<FlatPattern *, FlatPattern *> &patternPair =
// patternPairs[patternPairIndex];
// const ReducedModelOptimizer::Results optimizationResults =
// optimizationResults_testSet[patternPairIndex];
// // Save results
// std::filesystem::path saveToPath(
// std::filesystem::path(thisOptimizationDirectory)
// .append(patternPair.first->getLabel() + "@" +
// patternPair.second->getLabel()));
// std::filesystem::create_directories(std::filesystem::path(saveToPath));
// optimizationResults.save(saveToPath.string());
// // Save statistics
// statistics << patternPair.first->getLabel() + "@" +
// patternPair.second->getLabel();
// statistics << optimizationResults.objectiveValue;
// for (const double &optimalX : optimizationResults.x) {
// statistics << optimalX;
// }
// for (int unusedXVarCounter = 0;
// unusedXVarCounter <
// settings_optimization.xRanges.size() -
// optimizationResults.x.size(); unusedXVarCounter++) {
// statistics << "-";
// }
// statistics << optimizationResults.time;
// if (optimizationResults.numberOfSimulationCrashes == 0) {
// statistics << "No crashes";
// } else {
// statistics << optimizationResults.numberOfSimulationCrashes;
// }
// statistics << endrow;
// }
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Create reduced models if (argc < 4) {
// FormFinder::runUnitTests(); std::cerr << "Specify the pattern pair to be optimized." << std::endl;
const std::vector<size_t> numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1}; std::terminate();
std::vector<vcg::Point2i> singleBarReducedModelEdges{vcg::Point2i(0, 3)}; }
FlatPattern singleBarReducedModel(numberOfNodesPerSlot, // Populate the pattern pair to be optimized
singleBarReducedModelEdges); ////Full pattern
singleBarReducedModel.setLabel("SingleBar_reduced"); const std::string filepath_fullPattern = argv[1];
singleBarReducedModel.savePly(singleBarReducedModel.getLabel()); FlatPattern fullPattern(filepath_fullPattern);
singleBarReducedModel.scale(0.03); fullPattern.setLabel(
std::filesystem::path(filepath_fullPattern).stem().string());
fullPattern.scale(0.03);
////Reduced pattern
const std::string filepath_reducedPattern = argv[2];
FlatPattern reducedPattern(filepath_reducedPattern);
reducedPattern.setLabel(
std::filesystem::path(filepath_reducedPattern).stem().string());
reducedPattern.scale(0.03);
std::vector<vcg::Point2i> CWreducedModelEdges{vcg::Point2i(1, 5), // Set the optization settings
vcg::Point2i(3, 5)};
FlatPattern CWReducedModel(numberOfNodesPerSlot, CWreducedModelEdges);
CWReducedModel.setLabel("CW_reduced");
CWReducedModel.scale(0.03);
std::vector<vcg::Point2i> CCWreducedModelEdges{vcg::Point2i(1, 5),
vcg::Point2i(3, 1)};
FlatPattern CCWReducedModel(numberOfNodesPerSlot, CCWreducedModelEdges);
CCWReducedModel.setLabel("CCW_reduced");
CCWReducedModel.savePly(CWReducedModel.getLabel());
CCWReducedModel.scale(0.03);
std::vector<FlatPattern *> reducedModels{&singleBarReducedModel,
&CWReducedModel, &CCWReducedModel};
// Define the ranges that the optimizer will use
ReducedModelOptimizer::xRange beamWidth{"B", 0.5, 1.5}; ReducedModelOptimizer::xRange beamWidth{"B", 0.5, 1.5};
ReducedModelOptimizer::xRange beamDimensionsRatio{"bOverh", 0.7, 1.3}; ReducedModelOptimizer::xRange beamDimensionsRatio{"bOverh", 0.7, 1.3};
ReducedModelOptimizer::xRange beamE{"E", 0.1, 1.9}; ReducedModelOptimizer::xRange beamE{"E", 0.1, 1.9};
ReducedModelOptimizer::xRange innerHexagonSize{"HS", 0.1, 0.9}; ReducedModelOptimizer::xRange innerHexagonSize{"HS", 0.1, 0.9};
// Test set of full patterns
std::string fullPatternsTestSetDirectory = "../TestSet";
if (!std::filesystem::exists(
std::filesystem::path(fullPatternsTestSetDirectory))) {
std::cerr << "Full pattern directory does not exist: "
<< fullPatternsTestSetDirectory << std::endl;
return 1;
}
// "/home/iason/Documents/PhD/Research/Approximating shapes with flat "
// "patterns/Pattern_enumerator/Results/1v_0v_2e_1e_1c_6fan/3/Valid";
std::vector<std::pair<FlatPattern *, FlatPattern *>> patternPairs;
for (const auto &entry :
filesystem::directory_iterator(fullPatternsTestSetDirectory)) {
const auto filepath =
// std::filesystem::path(fullPatternsTestSetDirectory).append("305.ply");
entry.path();
const std::string filepathString = filepath.string();
const std::string tiledSuffix = "_tiled.ply";
if (filepathString.compare(filepathString.size() - tiledSuffix.size(),
tiledSuffix.size(), tiledSuffix) == 0) {
continue;
}
FlatPattern fullPattern(filepathString);
fullPattern.setLabel(filepath.stem().string());
fullPattern.scale(0.03);
// for (int reducedPatternIndex = 0;
// reducedPatternIndex < reducedModels.size();
// reducedPatternIndex++) {
FlatPattern *pFullPattern = new FlatPattern();
pFullPattern->copy(fullPattern);
FlatPattern *pReducedPattern = new FlatPattern();
// pReducedPattern->copy(*reducedModels[reducedPatternIndex]);
pReducedPattern->copy(*reducedModels[0]);
patternPairs.push_back(std::make_pair(pFullPattern, pReducedPattern));
// }
}
// for (double rangeOffset = 0.15; rangeOffset <= 0.95; rangeOffset += 0.05)
// {
ReducedModelOptimizer::Settings settings_optimization; ReducedModelOptimizer::Settings settings_optimization;
settings_optimization.xRanges = {beamWidth, beamDimensionsRatio, beamE, settings_optimization.xRanges = {beamWidth, beamDimensionsRatio, beamE,
innerHexagonSize}; innerHexagonSize};
const bool input_numberOfFunctionCallsDefined = argc >= 4;
settings_optimization.numberOfFunctionCalls =
input_numberOfFunctionCallsDefined ? std::atoi(argv[3]) : 100;
// Optimize pair
const std::string pairName =
fullPattern.getLabel() + "@" + reducedPattern.getLabel();
std::cout << "Optimizing " << pairName << std::endl;
const std::vector<size_t> numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1};
ReducedModelOptimizer optimizer(numberOfNodesPerSlot);
optimizer.initializePatterns(fullPattern, reducedPattern, {});
ReducedModelOptimizer::Results optimizationResults =
optimizer.optimize(settings_optimization);
// Export results
const bool input_resultDirectoryDefined = argc >= 5;
std::string optimiziationResultsDirectory =
input_resultDirectoryDefined ? argv[4] : "OptimizationResults";
std::filesystem::path dirPath_thisOptimization(
std::filesystem::path(optimiziationResultsDirectory).append(pairName));
std::filesystem::create_directories(dirPath_thisOptimization);
csvFile csv_results(std::filesystem::path(dirPath_thisOptimization)
.append("results.csv")
.string(),
false);
settings_optimization.writeTo(csv_results);
optimizationResults.writeTo(settings_optimization, csv_results);
optimizationResults.save(dirPath_thisOptimization.string());
// for (settings_optimization.numberOfFunctionCalls = 100; // optimizationResults.draw();
// settings_optimization.numberOfFunctionCalls < 5000;
// settings_optimization.numberOfFunctionCalls += 100) {
std::string optimiziationResultsDirectory = "OptimizationResults";
if (argc < 2) {
settings_optimization.numberOfFunctionCalls = 100;
} else if (argc == 2) {
settings_optimization.numberOfFunctionCalls = std::atoi(argv[1]);
} else if (argc == 3) {
settings_optimization.numberOfFunctionCalls = std::atoi(argv[1]);
optimiziationResultsDirectory = argv[2];
}
// settings_optimization.normalizeObjectiveValue = false;
// optimizeTestSet(patternPairs, settings_optimization,
// optimiziationResultsDirectory);
settings_optimization.normalizeObjectiveValue = true;
optimizeTestSet(patternPairs, settings_optimization,
optimiziationResultsDirectory);
for (auto &patternPair : patternPairs) {
delete patternPair.first;
delete patternPair.second;
}
return 0; return 0;
} }

View File

@ -47,7 +47,7 @@ public:
std::vector<xRange> xRanges; std::vector<xRange> xRanges;
int numberOfFunctionCalls{100}; int numberOfFunctionCalls{100};
double solutionAccuracy{1e-2}; double solutionAccuracy{1e-2};
bool normalizeObjectiveValue{ true }; bool normalizeObjectiveValue{true};
std::string toString() const { std::string toString() const {
std::string settingsString; std::string settingsString;
@ -59,23 +59,25 @@ public:
settingsString += xRangesString; settingsString += xRangesString;
} }
settingsString += "FuncCalls=" + std::to_string(numberOfFunctionCalls) + settingsString += "FuncCalls=" + std::to_string(numberOfFunctionCalls) +
" Accuracy=" + std::to_string(solutionAccuracy)+" Norm="+(normalizeObjectiveValue ? "yes" : "no"); " Accuracy=" + std::to_string(solutionAccuracy) +
" Norm=" + (normalizeObjectiveValue ? "yes" : "no");
return settingsString; return settingsString;
} }
void writeTo(csvFile &csv) const { void writeTo(csvFile &csv, const bool writeHeader = true) const {
// Create settings csv header // Create settings csv header
if (!xRanges.empty()) { if (writeHeader) {
for (const xRange &range : xRanges) { if (!xRanges.empty()) {
csv << range.label + " max"; for (const xRange &range : xRanges) {
csv << range.label + " min"; csv << range.label + " max";
csv << range.label + " min";
}
} }
csv << "Function Calls";
csv << "Solution Accuracy";
csv << endrow;
} }
csv << "Function Calls";
csv << "Solution Accuracy";
csv << "Normalize obj value";
csv << endrow;
if (!xRanges.empty()) { if (!xRanges.empty()) {
for (const xRange &range : xRanges) { for (const xRange &range : xRanges) {
@ -85,7 +87,6 @@ public:
} }
csv << numberOfFunctionCalls; csv << numberOfFunctionCalls;
csv << solutionAccuracy; csv << solutionAccuracy;
csv <<(normalizeObjectiveValue ? "yes" : "no");
csv << endrow; csv << endrow;
} }
}; };
@ -149,7 +150,8 @@ public:
&reducedToFullInterfaceViMap); &reducedToFullInterfaceViMap);
static double computeError(const std::vector<Vector6d> &reducedPatternResults, static double computeError(const std::vector<Vector6d> &reducedPatternResults,
const std::vector<Vector6d> &fullPatternResults,const double& interfaceDisplacementNormSum, const std::vector<Vector6d> &fullPatternResults,
const double &interfaceDisplacementNormSum,
const std::unordered_map<ReducedPatternVertexIndex, const std::unordered_map<ReducedPatternVertexIndex,
FullPatternVertexIndex> FullPatternVertexIndex>
&reducedToFullInterfaceViMap); &reducedToFullInterfaceViMap);
@ -250,10 +252,9 @@ struct ReducedModelOptimizer::Results {
const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob = const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob =
reducedPatternSimulationJobs[simulationJobIndex]; reducedPatternSimulationJobs[simulationJobIndex];
const auto reducedPatternDirectoryPath = const auto reducedPatternDirectoryPath =
std::filesystem::path(simulationJobFolderPath) std::filesystem::path(simulationJobFolderPath).append("Reduced");
.append("Reduced");
if (!std::filesystem::exists(reducedPatternDirectoryPath)) { if (!std::filesystem::exists(reducedPatternDirectoryPath)) {
std::filesystem::create_directory(reducedPatternDirectoryPath); std::filesystem::create_directory(reducedPatternDirectoryPath);
} }
pReducedPatternSimulationJob->save(reducedPatternDirectoryPath.string()); pReducedPatternSimulationJob->save(reducedPatternDirectoryPath.string());
} }
@ -264,10 +265,12 @@ struct ReducedModelOptimizer::Results {
for (const auto &directoryEntry : for (const auto &directoryEntry :
filesystem::directory_iterator(loadFromPath)) { filesystem::directory_iterator(loadFromPath)) {
const auto simulationScenarioPath = directoryEntry.path(); const auto simulationScenarioPath = directoryEntry.path();
if (!std::filesystem::is_directory(simulationScenarioPath)) {
continue;
}
// Load reduced pattern files // Load reduced pattern files
for (const auto &fileEntry : filesystem::directory_iterator( for (const auto &fileEntry : filesystem::directory_iterator(
std::filesystem::path(simulationScenarioPath) std::filesystem::path(simulationScenarioPath).append("Full"))) {
.append("Full"))) {
const auto filepath = fileEntry.path(); const auto filepath = fileEntry.path();
if (filepath.extension() == ".json") { if (filepath.extension() == ".json") {
SimulationJob job; SimulationJob job;
@ -291,6 +294,39 @@ struct ReducedModelOptimizer::Results {
} }
} }
} }
void writeTo(const ReducedModelOptimizer::Settings &settings_optimization,
csvFile &csv, const bool writeHeader = true) const {
if (writeHeader) {
//// Write header to csv
csv << "Obj value";
for (const ReducedModelOptimizer::xRange &range :
settings_optimization.xRanges) {
csv << range.label;
}
csv << "Time(s)";
csv << "#Crashes";
csv << endrow;
}
csv << objectiveValue;
for (const double &optimalX : x) {
csv << optimalX;
}
for (int unusedXVarCounter = 0;
unusedXVarCounter < settings_optimization.xRanges.size() - x.size();
unusedXVarCounter++) {
csv << "-";
}
csv << time;
if (numberOfSimulationCrashes == 0) {
csv << "No crashes";
} else {
csv << numberOfSimulationCrashes;
}
csv << endrow;
}
}; };
#endif // REDUCEDMODELOPTIMIZER_HPP #endif // REDUCEDMODELOPTIMIZER_HPP