Skip to content

Commit

Permalink
Update algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
platofff committed Jul 6, 2023
1 parent 6680476 commit 73b4cba
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 21 deletions.
4 changes: 3 additions & 1 deletion resistor-optimization/include/ElementContainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ class ElementContainer : public Element {

std::generator<std::shared_ptr<ElementContainer>> allNestedContainers();

std::uint_fast32_t getNumberOfResistors() const;

std::shared_ptr<ElementContainer> addCoW(
std::shared_ptr<ElementContainer> container) const;
std::shared_ptr<Element> el) const;

explicit ElementContainer() = default;
};
1 change: 1 addition & 0 deletions resistor-optimization/include/ResistanceOptimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class ResistanceOptimizer {
const std::vector<const std::shared_ptr<Resistor>>::iterator begin,
const std::vector<const std::shared_ptr<Resistor>>::iterator end,
const std::shared_ptr<ElementContainer> base) const;
static constexpr double ACCURACY = 0.0001; // TODO non-constant

public:
explicit ResistanceOptimizer(std::vector<double> &resistances);
Expand Down
17 changes: 15 additions & 2 deletions resistor-optimization/src/ElementContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void ElementContainer::add(std::shared_ptr<Element> el) {
}

std::shared_ptr<ElementContainer> ElementContainer::addCoW(
std::shared_ptr<ElementContainer> container) const {
std::shared_ptr<Element> el) const {
std::shared_ptr<ElementContainer> node = this->clone();
std::shared_ptr<ElementContainer> self_clone = node;

Expand All @@ -24,7 +24,7 @@ std::shared_ptr<ElementContainer> ElementContainer::addCoW(
node = parent_clone;
}

self_clone->add(container);
self_clone->add(el);

return node;
}
Expand All @@ -47,6 +47,19 @@ ElementContainer::allNestedContainers() {
co_return;
}

std::uint_fast32_t ElementContainer::getNumberOfResistors() const {
std::uint_fast32_t n = 0;
for (const auto& el : elements) {
auto sptr = std::dynamic_pointer_cast<ElementContainer>(el);
if (!sptr) {
n++;
continue;
}
n += sptr->getNumberOfResistors();
}
return n;
}

std::shared_ptr<ElementContainer> ElementContainer::clone() const {
const auto copy = createNewInstance();
std::ranges::copy(this->elements.begin(), this->elements.end(),
Expand Down
6 changes: 3 additions & 3 deletions resistor-optimization/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
int main() {
#if !__has_include(<emscripten/bind.h>)
// some tests
int r = 4;
std::vector<double> resistors{1.0, 1.7, 4.7, 5.6};
int r = 5;
std::vector<double> resistors{17.56};

const auto ro = ResistanceOptimizer(resistors);
const auto [svg, resistance] = ro.optimize(1.2, r);
const auto [svg, resistance] = ro.optimize(17.56, r);
std::cout << resistance << std::endl;
std::cout << svg << std::endl;
#endif
Expand Down
43 changes: 28 additions & 15 deletions resistor-optimization/src/ResistanceOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ ResistanceOptimizer::generateCombinations(
const std::shared_ptr<ElementContainer> base) const {
assert(std::distance(begin, end) != 0);

const auto c = std::ranges::subrange(begin, end);

if (base == nullptr) {
const auto base1 = std::make_shared<SeriesContainer>();
for (const auto& res : generateCombinations(
Expand All @@ -34,30 +36,38 @@ ResistanceOptimizer::generateCombinations(
co_return;
}

const auto c = std::ranges::subrange(begin, end);

if (c.size() == 1) {
for (const auto& container : base->allNestedContainers()) {
const auto new_container = std::make_shared<SeriesContainer>();
new_container->add(c[0]);
co_yield container->addCoW(new_container);
co_yield container->addCoW(c[0]);
}
co_return;
}

for (const auto& container : base->allNestedContainers()) {
const auto scontainer = std::make_shared<SeriesContainer>();
scontainer->add(c[0]);
for (const auto& res : generateCombinations(
std::next(begin), end, container->addCoW(scontainer))) {
co_yield res;
std::next(begin), end, container->addCoW(c[0]))) {
co_yield res;
}

const auto pcontainer = std::make_shared<ParallelContainer>();
pcontainer->add(c[0]);
for (const auto& res : generateCombinations(
std::next(begin), end, container->addCoW(pcontainer))) {
co_yield res;
auto scont = std::dynamic_pointer_cast<SeriesContainer>(container);

if (scont) {
const auto new_pcont = std::make_shared<ParallelContainer>();
new_pcont->add(c[0]);

for (const auto& res : generateCombinations(
std::next(begin), end, container->addCoW(new_pcont))) {
co_yield res;
}
} else {
auto pcont = std::dynamic_pointer_cast<ParallelContainer>(container);

const auto new_scont = std::make_shared<SeriesContainer>();
new_scont->add(c[0]);
for (const auto& res : generateCombinations(
std::next(begin), end, container->addCoW(new_scont))) {
co_yield res;
}
}
}
}
Expand All @@ -68,6 +78,7 @@ std::pair<std::string, double> ResistanceOptimizer::optimize(
std::ostringstream ss;

double min_r_offset = std::numeric_limits<double>::infinity();
std::uint_fast32_t res_n = 0;
double res_resistance = 0.0;
std::shared_ptr<ElementContainer> res;

Expand All @@ -78,9 +89,11 @@ std::pair<std::string, double> ResistanceOptimizer::optimize(
const double resistance = combination->getResistance();
const double r_offset =
std::abs(target_resistance - resistance);
const auto n = combination->getNumberOfResistors();

if (r_offset < min_r_offset) {
if (r_offset < min_r_offset || (n < res_n && r_offset <= ACCURACY)) {
min_r_offset = r_offset;
res_n = n;
res_resistance = resistance;
res = combination;
}
Expand Down

0 comments on commit 73b4cba

Please sign in to comment.