From 96dc1959a05239283b52c62b8f34c3ddcd76700d Mon Sep 17 00:00:00 2001 From: UnavailableDev <69792062+UnavailableDev@users.noreply.github.com> Date: Sat, 15 Jun 2024 11:42:44 +0200 Subject: Inserted loop detection --- Circuit.cpp | 1 + Circuit.h | 4 ++++ LoopDetection.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ LoopDetection.h | 20 ++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 LoopDetection.cpp create mode 100644 LoopDetection.h diff --git a/Circuit.cpp b/Circuit.cpp index e89fcb1..731e79f 100644 --- a/Circuit.cpp +++ b/Circuit.cpp @@ -14,6 +14,7 @@ void Circuit::create(string label, vector nodes) { return new_node(label, nodes[0]); new_net(label, nodes); + ld->add_connection(label, nodes); } void Circuit::new_node(string label, string type) { diff --git a/Circuit.h b/Circuit.h index f261cd8..e4b48e1 100644 --- a/Circuit.h +++ b/Circuit.h @@ -7,6 +7,8 @@ #include "Node.h" #include "Net.h" +#include "LoopDetection.h" + using std::string; using std::vector; @@ -26,6 +28,8 @@ private: std::map nodes = {}; vector nets = {}; + LoopDetection * ld = new LoopDetection(); + virtual Node * find_node(string label); }; diff --git a/LoopDetection.cpp b/LoopDetection.cpp new file mode 100644 index 0000000..ac4ab93 --- /dev/null +++ b/LoopDetection.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +#include "LoopDetection.h" +#include "Exception.h" + +LoopDetection::~LoopDetection(){} + +void LoopDetection::add_connection(const std::string &src, const std::vector &dests) +{ + for (const auto &dest : dests) + adj_list[src].push_back(dest); + + if (detect_cycle(src)) + throw CircuitException( "Cycle detected starting from node: %s", src.c_str()); +} + +bool LoopDetection::detect_cycle(const std::string &start) { + std::unordered_set visited; + std::unordered_set rec_stack; + + return is_cyclic(start, visited, rec_stack); +} + +bool LoopDetection::is_cyclic(const std::string &node, std::unordered_set &visited, std::unordered_set &rec_stack) { + if (rec_stack.find(node) != rec_stack.end()) + return true; // Cycle/Loop detected + + if (visited.find(node) != visited.end()) + return false; + + visited.insert(node); + rec_stack.insert(node); + + for (const auto &neighbor : adj_list[node]) + if (is_cyclic(neighbor, visited, rec_stack)) + return true; + + rec_stack.erase(node); + return false; +} + diff --git a/LoopDetection.h b/LoopDetection.h new file mode 100644 index 0000000..f12c83b --- /dev/null +++ b/LoopDetection.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include +#include + +class LoopDetection { +public: + LoopDetection() = default; + virtual ~LoopDetection(); + + virtual void add_connection(const std::string &src, const std::vector &dests); + +private: + std::unordered_map> adj_list; + + virtual bool detect_cycle(const std::string &start); + virtual bool is_cyclic(const std::string &node, std::unordered_set &visited, std::unordered_set &rec_stack); +}; -- cgit v1.2.3