diff --git a/.gitignore b/.gitignore index 112fbf0..3719e13 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ cmake-build-debug cmake-build-debug .idea .DS_Store +CMakeLists.txt diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 9ef8c1e..26ef6a8 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -8,7 +8,6 @@ set(SOURCE_FILES main.cpp header.h functions/solve/structure.cpp - functions/AbstractionLayers/AbstraktionLayer_Base.h functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp functions/AbstractionLayers/DestructionPower/DestructionPower.cpp diff --git a/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.cpp b/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.cpp index 9fb4998..6c76477 100644 --- a/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.cpp +++ b/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.cpp @@ -1,7 +1,3 @@ -// -// Created by mpapa on 05.12.2017. -// - #include "DestructionPower.h" //TODO! Add more layers here! @@ -9,10 +5,11 @@ //sets relations of speed for the different layers map DestructionPower_Properties::SpeedTable = { - {0,0.99} + {0,0.99}, + {1,0.7}, + {2,0.7} }; - bool DestructionPower::PreProcessing(coor mySize,const vector* partArray) { cout << "DestructionPower Preprocessing... "; @@ -38,7 +35,10 @@ bool DestructionPower::RemoveConstraintOnPosition(const coor constraintCoordinat //gets destruction power from left and from top if possible and normalizes void DestructionPower::DestructionOfSurrounding(const coor constraintCoordinate) { + for(int i = 0; i < m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray.size(); ++i) + m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray.pop_back(); for (int i = 0; i < DESTRUCTION_COUNT; ++i) { + m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray.push_back(0); int divisor=0; if(constraintCoordinate.row > 0) @@ -55,7 +55,10 @@ void DestructionPower::DestructionOfSurrounding(const coor constraintCoordinate) m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray[i] /=divisor; else //create default destructionPower //TODO find some better solution for default - m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray[i] =1-m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].SpeedTable[i]; + m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray[i] = m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].SpeedTable[i]; + //aging + if(m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray[i]<0.9) + m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray[i]=m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].DestructionArray[i]*(float)1.001+(float)0.01; } } @@ -102,6 +105,6 @@ DestructionPower_Properties::DestructionPower_Properties() { { DestructionArray.emplace_back((DestructionPower_Properties::SpeedTable[i]*DESTRUCTION_INIT)); - DestructionArray.back()<0.99 ? DestructionArray.back()*=aging:DestructionArray.back(); + DestructionArray.back()<0.8 ? DestructionArray.back()=aging*DestructionArray.back()+(float)0.01:DestructionArray.back(); } } diff --git a/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.h b/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.h index 56d3ecf..8d8eb9f 100644 --- a/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.h +++ b/Source/functions/AbstractionLayers/DestructionPower/DestructionPower.h @@ -1,9 +1,5 @@ -// -// Created by mpapa on 05.12.2017. -// - #pragma once - +//TODO!! increase Destructioncount #define DESTRUCTION_COUNT 1 #include "DestructionPower_Properties.h" diff --git a/Source/functions/AbstractionLayers/DestructionPower/DestructionPower_Properties.h b/Source/functions/AbstractionLayers/DestructionPower/DestructionPower_Properties.h index d2f294c..33b2d4c 100644 --- a/Source/functions/AbstractionLayers/DestructionPower/DestructionPower_Properties.h +++ b/Source/functions/AbstractionLayers/DestructionPower/DestructionPower_Properties.h @@ -1,6 +1,3 @@ -// -// Created by mpapa on 05.12.2017. -// #pragma once #define DESTRUCTION_INIT 0.5 diff --git a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp index e507bc7..064e777 100644 --- a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp +++ b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp @@ -1,10 +1,5 @@ -// -// Created by mpapa on 05.12.2017. -// - #include "AbstractionLayer_1.h" #include "../../../header.h" - #include #include @@ -14,6 +9,7 @@ bool AbstractionLayer_1::PreProcessing(coor mySize, const vector* partAr const vector& ref_partArray = *partArray; analyseParts analyse(mySize.row*mySize.col); Part buf; + int PSum=0; int iterator=0; if(!analyse.getImages()) { @@ -24,7 +20,8 @@ bool AbstractionLayer_1::PreProcessing(coor mySize, const vector* partAr //TODO rows and cols for(int i = 0; i < mySize.row*mySize.col; i++) { - unsigned char poempel = analyse.getTabs(i);; + unsigned char poempel = analyse.getTabs(i); + PSum+=PoempelSum(poempel); //preprocess correct check for (int j=0;j<4;j++) { ref_partArray[iterator]->m_a1.m_connections=poempel; @@ -33,10 +30,12 @@ bool AbstractionLayer_1::PreProcessing(coor mySize, const vector* partAr } } + if(PREPRO_CHECK && PSum) + return false; + + //Zugriff auf den vector mit den einzelnen teilen: part[0].getConnenctions() entspricht pömpel von bild 0.jpg und liefert ein unsigned char, poempl Belegung wie ausgemacht - - InitialiseConstraintMatrixSize(mySize.col+2, mySize.row+2); //col row switched in this function setEdgeZero(); @@ -44,9 +43,39 @@ bool AbstractionLayer_1::PreProcessing(coor mySize, const vector* partAr return true; } +int AbstractionLayer_1::PoempelSum(uint8_t constraint) +{ + int PoempelSum=0; + if((constraint & 0b11000000)==0b01000000) + PoempelSum--; + else if((constraint & 0b11000000)==0b10000000) + PoempelSum++; + + if((constraint & 0b00110000)==0b00010000) + PoempelSum--; + else if((constraint & 0b00110000)==0b00100000) + PoempelSum++; + + if((constraint & 0b00001100)==0b00000100) + PoempelSum--; + else if((constraint & 0b00001100)==0b00001000) + PoempelSum++; + + if((constraint & 0b00000011)==0b00000001) + PoempelSum--; + else if((constraint & 0b00000011)==0b00000010) + PoempelSum++; + + return PoempelSum; + +} + //it through qualityVector and removes all that do not trigger PlaceOfPartGood bool AbstractionLayer_1::EvaluateQuality (const coor constraintCoordinate, qualityVector& qVector) { + if(constraintCoordinate.row==23 && constraintCoordinate.col==35) + cout << "in" << endl; + //evaluateQuality = evaluateProbabilaty for(int i = 0;im_a1.m_connections)) @@ -69,6 +98,20 @@ bool AbstractionLayer_1::RemoveConstraintOnPosition(const coor constraintCoordin m_constraintMatrix[constraintCoordinate.col+1][constraintCoordinate.row+1].m_connections=0b11111111; } +int AbstractionLayer_1::RemoveSimilar(qualityVector& qVector,uint8_t& constraints) +{ + // + for(int i=0;im_a1.m_connections==constraints) + qVector.erase(qVector.begin()+i); + else + i++; + + } + +} + void AbstractionLayer_1::CreateRandomPuzzle() { std::minstd_rand simple_rand; @@ -120,8 +163,6 @@ void AbstractionLayer_1::CreateRandomPuzzle() } - - //puts all pieces of the current constraint matrix into a puzzlebox qualityVector AbstractionLayer_1::returnInBox(vector& PuzzleBox) { @@ -184,7 +225,11 @@ bool AbstractionLayer_1::PlaceOfPartGood(coor myCoor, uint8_t& myPart) || ((((negativePart & 0b00000011) == 0b00000011) || ((myPart & 0b00000011) == 0b00000011)) && (((myPart & 0b00000011) != 0b00000000) && (negativePart & 0b00000011) != 0b00000000)) || (((negativePart & 0b00000011) == 0b00000000) && ((myPart & 0b00000011) == 0b00000000)) ) ) + { + if(myCoor.row==18 && myCoor.col==35) + cout << "gud: " << std::bitset<8>(myPart) << endl; return true; + } return false; } diff --git a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.h b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.h index 81def82..ccb80f8 100644 --- a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.h +++ b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.h @@ -49,10 +49,13 @@ public: bool EvaluateQuality ( coor constraintCoordinate, qualityVector& qVector)override; bool SetConstraintOnPosition( coor constraintCoordinate, AbstractionLayer_1_Properties constraint)override; bool RemoveConstraintOnPosition( coor constraintCoordinate)override; + int RemoveSimilar(qualityVector&,uint8_t&); + bool PlaceOfPartGood(coor myCoor, uint8_t& myPart); void shift(uint8_t& Part, int shifts); void setEdgeZero(); + int PoempelSum(uint8_t constraint); void CreateRandomPuzzle(); qualityVector returnInBox(vector& PuzzleBox); diff --git a/Source/functions/solve/puzzleExtension.cpp b/Source/functions/solve/puzzleExtension.cpp index 9f45c27..775f078 100644 --- a/Source/functions/solve/puzzleExtension.cpp +++ b/Source/functions/solve/puzzleExtension.cpp @@ -1,6 +1,3 @@ -// -// Created by Raphael Maenle on 21/12/2017. -// #include "../../header/solve.h" #include "../../header/input.h" @@ -46,7 +43,8 @@ void Puzzle::putIntoBox() for(int rotations=0;rotations<4;rotations++) { tmpPart.m_a1.shift(1); - //TODO! add all other layers with their rotaionvariance here + //TODO! add all other layer with their rotaionvariance into "tmpPart" + //if it piece is roation invariant no need to do anything myBox.emplace_back(tmpPart); } @@ -65,6 +63,7 @@ void Puzzle::shuffle() void Puzzle::removeConstrains(coor removeCoordinates) { this->a1.RemoveConstraintOnPosition(removeCoordinates); + //TODO!! Add other layer remove here } void Puzzle::setConstraints(coor setConstraints, Part* constraintPiece) { @@ -75,6 +74,15 @@ void Puzzle::setConstraints(coor setConstraints, Part* constraintPiece) //a1 this->a1.SetConstraintOnPosition(setConstraints,constraintPiece->m_a1); + + //TODO!! Add other layer remove here +} + +int Puzzle::removeSimilar(qualityVector& qVector, Part& myPart) +{ + //a1 + uint8_t tmpConnections=myPart.m_a1.getConnections(); + a1.RemoveSimilar(qVector,tmpConnections); } void Puzzle::createRandomPuzzle() @@ -149,8 +157,6 @@ Mat Puzzle::resultImage( vector& log){ imageW = imageH; imageH = temp; - cout<<"imageW "<& log){ // imshow("result",result); // waitKey(0); } - cout << log.size() << endl; - cout << log[0].PieceCollector.size() << endl; cout << it.PieceCollector[0].second->GetPartID() << endl; diff --git a/Source/functions/solve/structure.cpp b/Source/functions/solve/structure.cpp index 05411a1..213e9c0 100755 --- a/Source/functions/solve/structure.cpp +++ b/Source/functions/solve/structure.cpp @@ -36,6 +36,7 @@ bool next(vector& log,Puzzle& puzzleMat) else setsolution(log,puzzleMat); return true; + } void createNextLogElement(vector& log, Puzzle& puzzleMat) @@ -43,11 +44,12 @@ 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 + cout << "-----------------------" << endl; + //get all not set pieces for(auto it:puzzleMat.p_myBox) if(!it->set) log.back().PieceCollector.emplace_back(pair(0,it)); - solve(log,puzzleMat); + solve(log,puzzleMat); } @@ -55,7 +57,6 @@ coor calculateNextCoor(vector& log, Puzzle& puzzleMat) { //level 1: //go left to right, then increase current row - if (log.size() == 1) return {0,0}; @@ -72,19 +73,22 @@ coor calculateNextCoor(vector& log, 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); + //status(log,p_Box,puzzleMat); + //TODO!! Add more layers here switch(log.back().abstractionLevel) { case 0://pömpel puzzleMat.a1.EvaluateQuality(log.back().myCoor, log.back().PieceCollector); break; + case 1://histogram + return; + break; case -1://random setsolution(log,puzzleMat); return; default: break; } - float worth = capLogElements(log); calculateTrueDestructionPower(log,puzzleMat, worth); CalculateNewCombinedQuality(log, log.back().PieceCollector, puzzleMat.combinedQualityVector); @@ -106,11 +110,27 @@ void setsolution(vector& log, Puzzle& puzzleMat) //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; + cout << "set:" << log.back().myCoor.col << "," << log.back().myCoor.row << endl; + //cout << "ID: " << log.back().PieceCollector[0].second->GetPartID() << endl; + int ist=0; + for(auto it:puzzleMat.myBox) + if(!it.set) + ist++; + + int soll = (puzzleMat.getSizeAsCoor().row*puzzleMat.getSizeAsCoor().col*4)-4*((log.back().myCoor.col)*puzzleMat.getSizeAsCoor().row+log.back().myCoor.row+1); + if(soll != ist) + cerr << "soll not ist!!!" << endl; + cout << "ist: " << ist << endl; + cout << "soll: " << soll << endl; + //cout << "log:" << endl; + //for(auto it:log.back().PieceCollector) + // cout << std::bitset<8>(it.second->m_a1.getConnections()) << "|" << it.second->GetPartID() << endl; + } bool backtrack(vector& log, Puzzle& puzzleMat) { + cout << "backtracking" ; if(log.empty()) { cout << "Puzzle not solveable!" << endl; @@ -120,10 +140,24 @@ bool backtrack(vector& log, Puzzle& puzzleMat) //if more pieces possible, tset piece as not logged if((log.back().PieceCollector.size())>1) { + cout << " next piece" << endl; + int count =0; for(int i=0;iGetPartID()==log.back().PieceCollector.begin()->second->GetPartID())//sets all with partid + { puzzleMat.p_myBox[i]->set=false; - log.back().PieceCollector.erase(log.back().PieceCollector.begin()); + count++; + } + } + + if (count !=4) + cerr << "incorrect set set" << endl; + Part myPart = *log.back().PieceCollector[0].second;//tmpsaves bad part + log.back().PieceCollector.erase(log.back().PieceCollector.begin());//removes bad part from log + puzzleMat.removeSimilar(log.back().PieceCollector,myPart); //removes all pieces from log that are similar to bad part + //TODO remove this when further layers are added!!! + if(log.back().PieceCollector.size()==1) log.back().decreaseRandomed(); @@ -135,11 +169,24 @@ bool backtrack(vector& log, Puzzle& puzzleMat) //else remove log element and backtrack once more else { + puzzleMat.removeConstrains(log.back().myCoor); //this should remove constraints from all layers + int count =0; if((log.back().PieceCollector.size())) + { for(int i=0;iGetPartID()==log.back().PieceCollector.begin()->second->GetPartID())//sets all with partid + { puzzleMat.p_myBox[i]->set=false; + count++; + } + } + if (count !=4) + cerr << "incorrect set set" << endl; + } + cout << " no more pieces" << endl; + log.pop_back(); if(!backtrack(log,puzzleMat)) return false; @@ -149,7 +196,6 @@ bool backtrack(vector& log, Puzzle& puzzleMat) //this is addon stuff that should later all be extracted into a sererate cpp as it is not core dispatcher functionality - void calculateTrueDestructionPower(vector& log, Puzzle& puzzleMat, float Layerworth) { float destructionPower = sqrt( Layerworth * puzzleMat.dp.m_constraintMatrix[0][0].SpeedTable[log.back().abstractionLevel]); @@ -166,6 +212,7 @@ void calculateTrueDestructionPower(vector& log, Puzzle& puzzleMat, flo // PART RAUER_WEIDINGER float capLogElements(vector& log) { + // Till Now only ground structure -> incorrect variable ans vector names double limit = 0.6; double diff = 0; @@ -187,6 +234,9 @@ float capLogElements(vector& log) break; } int newid=0; + //check if all over + if(id==log.back().PieceCollector.size()) + return 0; if(id>0) newid = --id; //set to the one just over limit @@ -241,6 +291,7 @@ bool SetBestOrMoreLayersArithmetical(vector& log, qualityVector& cqVec case 4: threshold = 0.60; break; default: threshold = 0.5; break; } + //TODO!! add more layers here! // check Quality of current Puzzle Piece in combinedQualityVector with Threshold value for (qualityVector::iterator it = cqVector.begin(); it != cqVector.end(); it++) @@ -269,6 +320,7 @@ void CalculateNewCombinedQuality(vector& log, qualityVector& qVector, { bool summarizedVectors = false; int countSummarizedVectors = 0; + bool removePart=true; // check if both qualityVectors are not empty if(qVector.empty()) @@ -287,19 +339,25 @@ void CalculateNewCombinedQuality(vector& log, qualityVector& qVector, 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) { + if (cqVector.at(i).second->GetPartID() == qVector.at(j).second->GetPartID() && cqVector.at(i).second->GetNumOfRotations() == qVector.at(j).second->GetNumOfRotations()) { // sum Quality of PieceCollector (qualityVector) to combinedQualityVector cqVector.at(j).first += qVector.at(i).first; countSummarizedVectors++; + removePart=false; 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(); + } + if(removePart) + { + swap(cqVector.at(i), cqVector.back()); + cqVector.pop_back(); + } + } // cqVector should have the same size now as newest qVector diff --git a/Source/header.h b/Source/header.h index 533aff6..bcf9329 100755 --- a/Source/header.h +++ b/Source/header.h @@ -7,6 +7,7 @@ #include #include +#define PREPRO_CHECK false using namespace std; #include "header/input.h" diff --git a/Source/header/solve.h b/Source/header/solve.h index 7bbc49a..08485f3 100755 --- a/Source/header/solve.h +++ b/Source/header/solve.h @@ -44,8 +44,9 @@ public: bool PreProcessing() { createBox(); createp_box(); - dp.PreProcessing({cols,rows}, nullptr); - a1.PreProcessing({cols,rows}, &p_myBox); + if(!dp.PreProcessing({cols,rows}, nullptr)) return false; + if(!a1.PreProcessing({cols,rows}, &p_myBox)) return false; + return true; } @@ -56,6 +57,8 @@ public: void removeConstrains(coor removeCoordinates); void setConstraints(coor setConstraints, Part *constraintPiece); + int removeSimilar(qualityVector&, Part&); + void printPuzzle(); void printBox(); Mat resultImage(vector&); diff --git a/Source/main.cpp b/Source/main.cpp index 56c683c..7b5ee70 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -15,14 +15,14 @@ int main() return 0; } - //puzzleMat.createRandomBox(); + puzzleMat.createRandomBox(); cout << "Solving Puzzle now..."; while(next(log, puzzleMat)); cout << "Done!" << endl; - puzzleMat.resultImage(log); + //puzzleMat.resultImage(log); puzzleMat.printPuzzle();