I have been trying to write a small test program and I was trying to think of any potential optimization I could do, especially if there is any chance to avoid some of the for loops.
The program has Dad class, a Child class and a DadChild class that holds the IDs of the Dad and Child objects that are associated based on their DNA.
The requirements are:
- A Dad object can be associated with multiple Child objects
- A Child object can NOT be associated with more than 1 Dad objects
- Out of all Child objects that are associated with the a Dad object, only one has to be marked as bestMatch.
Here is the sample code that I drafted, it works as expected, but I wondering if there is any space for optimizations.
#include<iostream>
#include<vector>
#include<map>
#include <algorithm>
#include <memory>
class Dad
{
public:
Dad(int a_id, int a_dna): id(a_id), DNA(a_dna) {}
int id;
int DNA;
};
class Child
{
public:
Child(int a_id, int a_dna): id(a_id), DNA(a_dna) {}
int id;
int DNA;
};
class DadChild
{
public:
DadChild(): dnaResult(-1) {}
DadChild(bool a_bestMatch, int a_childID, int a_dadID, double a_dnaResult):
bestMatch(a_bestMatch),
childID(a_childID),
dadID(a_dadID),
dnaResult(a_dnaResult) {}
int dadID;
int childID;
double dnaResult;
bool bestMatch;
};
double compareDNA (int a, int b) {
return abs(a - b); // 0 indicates a perfect match
}
DadChild createDadChild(Dad d) {
//Do something for single parents. Not really that important here.
return DadChild();
}
DadChild createDadChild(Dad d, Child c, double dnaTest) {
//Construct and return DadChild Object
DadChild dc;
dc.bestMatch = false;
dc.childID = c.id;
dc.dadID = d.id;
dc.dnaResult = dnaTest;
return dc;
}
int main() {
Dad d1 (1, 1);
Dad d2 (2, 4);
Child c0 (0, 4);
Child c1 (1, 2);
Child c2 (2, 3);
Child c3 (3, 1);
std::vector<Dad> dads;
std::vector<Child> children;
dads.push_back(d1);
dads.push_back(d2);
children.push_back(c0);
children.push_back(c1);
children.push_back(c2);
children.push_back(c3);
std::map <int, DadChild> assocMap; // Where the the key is the childID
std::vector <DadChild> singleDadVector;
for (auto &dad : dads) {
bool singleParent = true;
for (auto &child : children) {
double dnaTest = compareDNA(dad.DNA, child.DNA);
if (dnaTest < 2) { // 2 here is an arbitrary threshold for the dna result
singleParent = false;
auto search = assocMap.find(child.id);
if (search != assocMap.end()) {
if (assocMap[child.id].dnaResult > dnaTest) {
assocMap[child.id] = createDadChild(dad, child, dnaTest);
}
}
else {
assocMap[child.id] = createDadChild(dad, child, dnaTest);
}
}
}
if (singleParent)
singleDadVector.push_back(createDadChild(dad));
}
// Try to find the bestMatch.
// I am wondering if there is a better way to do this.
for (auto const &dad : dads) {
DadChild dc;
DadChild *bestDadChild = &dc;
for (auto &assoc: assocMap) {
if ((dad.id == assoc.second.dadID) && (bestDadChild->dnaResult == -1)) {
bestDadChild = &assoc.second;
} else if ((dad.id == assoc.second.dadID) && assoc.second.dnaResult < bestDadChild->dnaResult) {
bestDadChild = &assoc.second;
}
}
bestDadChild->bestMatch = true;
}
/*
// I tried to do something like this, but it didn't really work.
for (auto &dad : dads) {
auto pr = std::min_element(
std::begin(assocMap), std::end(assocMap),
[dad] (const auto &p1, const auto &p2) {
return ((dad.id == p1.second.dadID) && (dad.id == p2.second.dadID) && (p1.second.dnaResult < p2.second.dnaResult));
});
pr->second.bestMatch = true;
std::cout << dad.id << std::endl;
std::cout << "Setting: " << pr->second.dadID << std::endl;
}*/
for (auto &a : assocMap) {
std::cout << "DadID: " << a.second.dadID << std::endl;
std::cout << "ChildID: " << a.second.childID << std::endl;
std::cout << "bestMatch: " << a.second.bestMatch << std::endl;
std::cout << "dnaResult: " << a.second.dnaResult << std::endl;
std::cout << "--------------" << std::endl;
}
}
Output:
DadID: 2
ChildID: 0
bestMatch: 1
dnaResult: 0
--------------
DadID: 1
ChildID: 1
bestMatch: 0
dnaResult: 1
--------------
DadID: 2
ChildID: 2
bestMatch: 0
dnaResult: 1
--------------
DadID: 1
ChildID: 3
bestMatch: 1
dnaResult: 0
--------------
Aucun commentaire:
Enregistrer un commentaire