From c78518b1e91d666ad1a426edc1c9655db87dd58e Mon Sep 17 00:00:00 2001 From: Raphael Maenle <17550607+g-spacewhale@users.noreply.github.com> Date: Sun, 7 Jan 2018 20:08:50 +0100 Subject: [PATCH] code now functional --- .../DestructionPower/DestructionPower.cpp | 24 +- .../Layer1/AbstractionLayer_1.cpp | 21 +- .../Layer1/AbstractionLayer_1_Properties.h | 1 + Source/functions/solve/puzzleExtension.cpp | 14 +- Source/functions/solve/structure.cpp | 216 +++++++----------- Source/header/input.h | 4 +- Source/header/solve.h | 9 +- Source/main.cpp | 5 +- 8 files changed, 127 insertions(+), 167 deletions(-) diff --git a/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.cpp b/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.cpp index 0b8dc84..184623d 100644 --- a/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.cpp +++ b/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.cpp @@ -13,8 +13,10 @@ map DestructionPower_Properties::SpeedTable = bool DestructionPower::PreProcessing(coor mySize,const vector* partArray) { - InitialiseConstraintMatrixSize(mySize.row,mySize.col); + cout << "DestructionPower Preprocessing... "; + InitialiseConstraintMatrixSize(mySize.row,mySize.col); + cout << "Done!" << endl; return true; } @@ -33,7 +35,6 @@ bool DestructionPower::RemoveConstraintOnPosition(const coor constraintCoordinat //gets destruction power from left and from top if possible and normalizes void DestructionPower::DestructionOfSurrounding(const coor constraintCoordinate) { - float newDestructionArray[DESTRUCTION_COUNT]; for (int i = 0; i < DESTRUCTION_COUNT; ++i) { m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray.push_back(0); @@ -68,24 +69,25 @@ int DestructionPower::getNextAbstractionLayer(coor newCoordinate, int currentAbs int nextLayer=-1; float nextLayerPower=0; if (currentAbstractionLayer>=0) - currentPower = m_constraintMatrix[newCoordinate.row][newCoordinate.col].DestructionArray[currentAbstractionLayer]; + currentPower = m_constraintMatrix[newCoordinate.col][newCoordinate.row].DestructionArray[currentAbstractionLayer]; int i=0; //giff next most valuable layer - for(auto it:m_constraintMatrix[newCoordinate.row][newCoordinate.col].DestructionArray) + for(auto it:m_constraintMatrix[newCoordinate.col][newCoordinate.row].DestructionArray) { if(it <= currentPower) {//if equal, then has to be the next one (activated from left to right) - if(it == currentPower) - if(i>currentAbstractionLayer) + if(it == currentPower) { + if (i > currentAbstractionLayer) return i; - //if this one is bigger than previous biggest one, save - if(it>nextLayerPower) - { - nextLayerPower=it; - nextLayer=i; } + //if this one is bigger than previous biggest one, save + else if(it>nextLayerPower) + { + nextLayerPower=it; + nextLayer=i; + } } i++; } diff --git a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp index 3697ff9..8c4b2df 100644 --- a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp +++ b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp @@ -10,8 +10,9 @@ bool AbstractionLayer_1::PreProcessing(coor mySize, const vector* partArray) { + cout << "Abstraction 1 Preprocessing... " << flush; const vector& ref_partArray = *partArray; - analyseParts analyse(1008); + analyseParts analyse(mySize.row*mySize.col); Part buf; int iterator=0; if(!analyse.getImages()) @@ -20,7 +21,8 @@ bool AbstractionLayer_1::PreProcessing(coor mySize, const vector* partAr return false; } else // hier werden alle vier verschiedenen Rotationsarten 'gleichzeitig' abgespeichert - for(int i = 0; i < 1008; i++) + //TODO rows and cols + for(int i = 0; i < mySize.row*mySize.col; i++) { unsigned char poempel = analyse.getTabs(i);; for (int j=0;j<4;j++) @@ -35,9 +37,10 @@ bool AbstractionLayer_1::PreProcessing(coor mySize, const vector* partAr - InitialiseConstraintMatrixSize(mySize.col+2, mySize.row+2); + InitialiseConstraintMatrixSize(mySize.col+2, mySize.row+2); //col row switched in this function setEdgeZero(); + cout << "Done!" << endl; return true; } @@ -58,12 +61,12 @@ bool AbstractionLayer_1::EvaluateQuality (const coor constraintCoordinate, quali bool AbstractionLayer_1::SetConstraintOnPosition(const coor constraintCoordinate, const AbstractionLayer_1_Properties constraint) { - m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].m_connections=constraint.m_connections; + m_constraintMatrix[constraintCoordinate.col+1][constraintCoordinate.row+1].m_connections=constraint.m_connections; } bool AbstractionLayer_1::RemoveConstraintOnPosition(const coor constraintCoordinate) { - m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].m_connections=0b11111111; + m_constraintMatrix[constraintCoordinate.col+1][constraintCoordinate.row+1].m_connections=0b11111111; } void AbstractionLayer_1::CreateRandomPuzzle() @@ -107,9 +110,9 @@ void AbstractionLayer_1::CreateRandomPuzzle() tempPiece and_eq (uint8_t)0b11001111; //set piece if piece good - if(PlaceOfPartGood(coor(col,row),tempPiece)) + if(PlaceOfPartGood(coor((unsigned int)col,(unsigned int)row),tempPiece)) { - m_constraintMatrix[row][col].m_connections = tempPiece; + m_constraintMatrix[col][row].m_connections = tempPiece; col++; } } @@ -163,8 +166,6 @@ bool AbstractionLayer_1::PlaceOfPartGood(coor myCoor, uint8_t& myPart) negativePart or_eq (m_constraintMatrix[myCoor.row-1][myCoor.col].m_connections & 0b00001100); negativePart or_eq (m_constraintMatrix[myCoor.row][myCoor.col+1].m_connections & 0b00000011); shift(negativePart,2); - if(negativePart & 0b11000000) - return 1; if ( ( ((((negativePart & 0b11000000) ^ (myPart & 0b11000000)) != 0b00000000) && (((myPart & 0b11000000) != 0b00000000) && (negativePart & 0b11000000) != 0b00000000)) || ((((negativePart & 0b11000000) == 0b11000000) || ((myPart & 0b11000000) == 0b11000000)) && (((myPart & 0b11000000) != 0b00000000) && (negativePart & 0b11000000) != 0b00000000)) @@ -220,8 +221,6 @@ Mat analyseParts::readImages(int count) Mat ref_gray; sprintf(name, PATH, count); - cout << "path" << name << endl; - Mat src = imread(name, 1); if (!src.data) { diff --git a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1_Properties.h b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1_Properties.h index cd5e639..f3401dd 100644 --- a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1_Properties.h +++ b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1_Properties.h @@ -12,6 +12,7 @@ class AbstractionLayer_1_Properties public: AbstractionLayer_1_Properties() : m_connections(0b11111111) {} void shift(int shifts); + uint8_t getConnections(){return m_connections;}; void print(); private: diff --git a/Source/functions/solve/puzzleExtension.cpp b/Source/functions/solve/puzzleExtension.cpp index e25a6c9..a3f6b12 100644 --- a/Source/functions/solve/puzzleExtension.cpp +++ b/Source/functions/solve/puzzleExtension.cpp @@ -59,6 +59,10 @@ void Puzzle::removeConstrains(coor removeCoordinates) { this->a1.RemoveConstraintOnPosition(removeCoordinates); } +void Puzzle::setConstraints(coor setConstraints, Part* constraintPiece) +{ + this->a1.SetConstraintOnPosition(setConstraints,constraintPiece->m_a1); +} void Puzzle::createRandomPuzzle() { @@ -67,13 +71,13 @@ void Puzzle::createRandomPuzzle() void Puzzle::createp_box() { - for(int i=0;i& log, vector& p_Box); bool SetBestOrMoreLayersArithmetical(vector& log, qualityVector& cqVector); void calculateTrueDestructionPower(vector& log, Puzzle& puzzleMat, float Layerworth); -void sort(vector& log); void cut(vector& log, int& cutID); float capLogElements(vector& log); void CalculateNewCombinedQuality(vector& log, qualityVector& qVector, qualityVector& cqVector); @@ -11,35 +9,31 @@ bool next(vector& log,Puzzle& puzzleMat) { //last log element is set, create new log element or log not yet started if(!(log.size()) || log.back().isSet()) - { if((puzzleMat.allSet())) return false; //puzzle solved else createNextLogElement(log,puzzleMat); - } + //last log element is empty, backtrack - else if(!(log.back().PieceCollector.size())) backtrack(log,puzzleMat); + else if(!(log.back().PieceCollector.size())) + { + if(!(backtrack(log,puzzleMat))) + return false; + } + //case last log element has multiple entries else if(log.back().PieceCollector.size() > 1) - { //moreLayers is 0, setbest is 1 if (SetBestOrMoreLayersArithmetical(log, puzzleMat.combinedQualityVector)) setsolution(log, puzzleMat); else solve(log, puzzleMat); - } + //case last log exactly one solution else if(log.back().PieceCollector.size() == 1) - { if(log.back().hasRandomed()) - { if(log.back().abstractionLevel < 2)//do 2 at least two best abstractions to check if part is okay - { - log.back().advance(); solve(log,puzzleMat); - } else setsolution(log,puzzleMat); - } else setsolution(log,puzzleMat); - } return true; } @@ -48,10 +42,10 @@ void createNextLogElement(vector& log, Puzzle& puzzleMat) log.emplace_back(LogEntry(coor(0, 0))); log.back().myCoor = calculateNextCoor(log, puzzleMat); puzzleMat.dp.DestructionOfSurrounding(log.back().myCoor);//calculate dp from surrounding + //get all not set pieces for(auto it:puzzleMat.p_myBox) - log.back().PieceCollector.emplace_back(pair(0,it)); - cout << puzzleMat.p_myBox.size() << endl; - cout << log.back().PieceCollector.size() << endl; + if(!it->set) + log.back().PieceCollector.emplace_back(pair(0,it)); solve(log,puzzleMat); } @@ -65,25 +59,27 @@ coor calculateNextCoor(vector& log, Puzzle& puzzleMat) return {0,0}; - unsigned int m= log.rbegin()[1].myCoor.col; - unsigned int n= log.rbegin()[1].myCoor.row; + unsigned int col= log.rbegin()[1].myCoor.col; + unsigned int row= log.rbegin()[1].myCoor.row; - if(m& log, vector& p_Box, Puzzle& puzzleMat) +void solve(vector& log,Puzzle& puzzleMat) { log.back().abstractionLevel = puzzleMat.dp.getNextAbstractionLayer(log.back().myCoor,log.back().abstractionLevel); //sets in abstractionLevel //status(log,p_Box,puzzleMat); switch(log.back().abstractionLevel) { - case 0: + case 0://pömpel puzzleMat.a1.EvaluateQuality(log.back().myCoor, log.back().PieceCollector); break; - + case -1://random + setsolution(log,puzzleMat); + return; default: break; } @@ -100,19 +96,26 @@ void setsolution(vector& log, Puzzle& puzzleMat) //advance number of randomed part count if(log.back().PieceCollector.size()>1) log.back().advanceRandomed(); - //remove first element in last logelement from box - for(int i=0;isecond)//mach ich das richtig so?! - puzzleMat.p_myBox.erase(puzzleMat.p_myBox.begin()+i); - else - i++; + //'set=true' all 4 rotations of pieces in puzzleBox + for(int i=0;iGetPartID()==log.back().PieceCollector.begin()->second->GetPartID()) + puzzleMat.p_myBox[i]->set=true; + puzzleMat.combinedQualityVector.clear(); //clear data from temp variable //tell log entry that it is set log.back().Set(); + puzzleMat.setConstraints(log.back().myCoor,log.back().PieceCollector.begin()->second); + cout << "set:" << log.back().myCoor.col << "," << log.back().myCoor.row << endl; } bool backtrack(vector& log, Puzzle& puzzleMat) { + if(log.empty()) + { + cout << "Puzzle not solveable!" << endl; + return false; + } + puzzleMat.combinedQualityVector.clear(); //remove all data from temp quality save //if more pieces possible, take next piece if((log.back().PieceCollector.size())>1) { @@ -131,42 +134,22 @@ bool backtrack(vector& log, Puzzle& puzzleMat) { puzzleMat.removeConstrains(log.back().myCoor); //this should remove constraints from all layers if((log.back().PieceCollector.size())) - puzzleMat.p_myBox.emplace_back(log.back().PieceCollector.begin()->second); + for(int i=0;iGetPartID()==log.back().PieceCollector.begin()->second->GetPartID())//sets all with partid + puzzleMat.p_myBox[i]->set=false; log.pop_back(); - backtrack(log,puzzleMat); + if(!backtrack(log,puzzleMat)) + return false; + return true; } } -void status(vector& log, Puzzle& puzzleMat) -{ - cout << "----------------------------" << endl; - cout << "status:" << endl; - cout << "hasrandomed: " << log[0].hasRandomed() << endl; - for(int i=0;i& log, Puzzle& puzzleMat, float Layerworth) { float destructionPower = sqrt( - Layerworth * puzzleMat.dp.m_constraintMatrix[0][0].SpeedTable[log.back().abstractionLevel]); + Layerworth * puzzleMat.dp.m_constraintMatrix[0][0].SpeedTable[log.back().abstractionLevel+1]); puzzleMat.dp.setDestructionPower(log.back().myCoor, log.back().abstractionLevel, destructionPower); } @@ -193,13 +176,14 @@ float capLogElements(vector& log) if(log.back().PieceCollector[id].first < limit) break; } + int newid=0; + if(id>0) + newid = --id; //set to the one just over limit - - int newid = --id; //set to the one just over limit - - - while(id maxdiff) @@ -217,21 +201,6 @@ float capLogElements(vector& log) } -qualityVector::iterator FindPartInLog(vector& log, Part* wishedPartPointer) -{ - qualityVector::iterator partOnPositionIterator = log.back().PieceCollector.begin(); - - while (partOnPositionIterator != log.back().PieceCollector.end()) - { - if(partOnPositionIterator->second == wishedPartPointer) - break; - else - partOnPositionIterator++; - } - - return partOnPositionIterator; -} - void cut(vector& log, int& cutID) { while(cutID& log, int& cutID) // geeignete Threshold values muessen noch getestet werden bool SetBestOrMoreLayersArithmetical(vector& log, qualityVector& cqVector) { - float threshold = 1.0, tempBest = 0.0; + float threshold, tempBest = 0.0; unsigned int countHigherThreshold = 0; if(cqVector.empty()) { - cerr << "combinedQualityVector is empty." << endl; // should not be empty => backtrack? + //cerr << "combinedQualityVector is empty." << endl; // should not be empty => backtrack? return false; // Warning: can only return true or false. What return for error? } else { - switch(log.back().abstractionLevel) + switch(log.back().abstractionLevel+1) { case 1: threshold = 0.90; break; case 2: threshold = 0.80; break; @@ -263,22 +232,14 @@ bool SetBestOrMoreLayersArithmetical(vector& log, qualityVector& cqVec default: threshold = 0.5; break; } - // check Quality of current Puzzle Piece in combinedQualityVector with Threshold value + // check Quality of current Puzzle Piece in combinedQualityVector with Threshold value for (qualityVector::iterator it = cqVector.begin(); it != cqVector.end(); it++) - { if ((cqVector.back().first / log.back().abstractionLevel) >= threshold) // const threshold values - { // count how many Pieces are greater than the threshold value countHigherThreshold++; - } else - { if ((cqVector.back().first / log.back().abstractionLevel) > tempBest) - { tempBest = cqVector.back().first; // could be used, for additional constraints - } - } - } // return true if only one piece is left if (1 == countHigherThreshold) @@ -302,52 +263,41 @@ void CalculateNewCombinedQuality(vector& log, qualityVector& qVector, // check if both qualityVectors are not empty if(qVector.empty()) { - cerr << "qualityVector is empty." << endl; // should not be empty => backtrack? + //cerr << "qualityVector is empty." << endl; // should not be empty => backtrack? return; } - else if(cqVector.empty()) + if(cqVector.empty()) { - cerr << "combinedQualityVector is empty." << endl; // should not be empty => backtrack? - return; + //cout << "combinedQualityVector was initialized." << endl; //first layer stuff eh + for(auto it:qVector) + cqVector.emplace_back(it); } - else - { - for (unsigned int i = 0; i < cqVector.size(); i++) - { - summarizedVectors = false; + else + { + for (unsigned int i = 0; i < cqVector.size(); i++) { + for (unsigned int j = 0; j < qVector.size(); j++) { + // search same PuzzlePart of qualityVector and combinedQualityVector + if (&cqVector.at(i).second == &qVector.at(j).second) { + // sum Quality of PieceCollector (qualityVector) to combinedQualityVector + cqVector.at(j).first += qVector.at(i).first; + countSummarizedVectors++; + break; // skip remaining for loop => save time! + } + // remove element at poisition X in combinedQualityVector, because it was not summarized + // inefficient way to delete element X + //cqVector->erase(cqVector->begin()+i); + // efficient way, but no sorted cqVector => wayne //echt? lol + swap(cqVector.at(i), cqVector.back()); + cqVector.pop_back(); + } + } - for (unsigned int j = 0; j < qVector.size(); j++) - { - // search same PuzzlePart of qualityVector and combinedQualityVector - if (&cqVector.at(i).second == &qVector.at(j).second) - { - // sum Quality of PieceCollector (qualityVector) to combinedQualityVector - cqVector.at(j).first += qVector.at(i).first; - countSummarizedVectors++; - summarizedVectors = true; - continue; // skip remaining for loop => save time! - } - } - - // remove element at poisition X in combinedQualityVector, because it was not summarized - if (!summarizedVectors) - { - // inefficient way to delete element X - //cqVector->erase(cqVector->begin()+i); - - // efficient way, but no sorted cqVector => wayne - swap(cqVector.at(i), cqVector.back()); - cqVector.pop_back(); - } - } - - // cqVector should have the same size now as newest qVector - if (cqVector.size() != qVector.size()) - { - cerr << "Size of combinedQualityVector doenst match with size of qualityVector!" << endl; - cout << "Size of combinedQualityVector: " << cqVector.size() << endl; - cout << "Size of qualityVector: " << qVector.size() << endl; - cout << "Size of countSummarizedVectors: " << countSummarizedVectors << endl; - } - } + // cqVector should have the same size now as newest qVector + if (cqVector.size() != qVector.size()) { + cerr << "Size of combinedQualityVector doenst match with size of qualityVector!" << endl; + cout << "Size of combinedQualityVector: " << cqVector.size() << endl; + cout << "Size of qualityVector: " << qVector.size() << endl; + cout << "Size of countSummarizedVectors: " << countSummarizedVectors << endl; + } + } } \ No newline at end of file diff --git a/Source/header/input.h b/Source/header/input.h index 32b8b0e..6cee3da 100755 --- a/Source/header/input.h +++ b/Source/header/input.h @@ -14,7 +14,7 @@ class LayerContainer; class Part { public: - Part() : m_partID(0), m_numOfRotations(0) + Part() : m_partID(0), m_numOfRotations(0), set(false) {} ~Part() = default; @@ -40,8 +40,8 @@ public: void print(){m_a1.print();} + bool set; AbstractionLayer_1_Properties m_a1; - DestructionPower_Properties m_destruction; private: int32_t m_partID; uint8_t m_numOfRotations; diff --git a/Source/header/solve.h b/Source/header/solve.h index 1f3ba4b..c87f00f 100755 --- a/Source/header/solve.h +++ b/Source/header/solve.h @@ -39,13 +39,13 @@ class Puzzle { public: - Puzzle(unsigned int newcols,unsigned int newrows):rows(newrows),cols(newcols) {} + Puzzle(unsigned int newcols,unsigned int newrows):cols(newcols),rows(newrows) {} bool PreProcessing() { createBox(); createp_box(); - dp.PreProcessing({rows,cols}, nullptr); - a1.PreProcessing({rows,cols}, &p_myBox); + dp.PreProcessing({cols,rows}, nullptr); + a1.PreProcessing({cols,rows}, &p_myBox); return true; } @@ -55,6 +55,7 @@ public: AbstractionLayer_1 a1; void removeConstrains(coor removeCoordinates); + void setConstraints(coor setConstraints, Part *constraintPiece); void printPuzzle(); void printBox(); @@ -74,8 +75,8 @@ public: private: - unsigned int rows; unsigned int cols; + unsigned int rows; }; bool next(vector& log,Puzzle& puzzleMat); diff --git a/Source/main.cpp b/Source/main.cpp index 9a14e61..7f71bf6 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -5,7 +5,7 @@ int LogEntry::randomed(0); int main() { - unsigned int cols=36, rows=28; + unsigned int cols=36,rows=28; vector log; Puzzle puzzleMat(cols, rows); @@ -16,10 +16,11 @@ int main() } //puzzleMat.createRandomBox(); - puzzleMat.a1.printConstraintMatrix(); + cout << "Solving Puzzle now..."; while(next(log, puzzleMat)); + cout << "Done!" << endl; puzzleMat.printPuzzle(); return 0; }