मेरे पास निम्न प्रक्रिया है जो एक अप्रत्यक्ष ग्राफ में किनारे (सिंगलजेज) और किनारे सेट (एजसेट) लेने वाले चक्रों का पता लगाने के लिए है। दो और तर्क हैं, बाएं_सेट (जो आवश्यक किनारों को रिकर्सन में पारित करने के लिए है) और चक्रीय (जो एक बूलियन मान है जो अंततः यह निर्धारित करता है कि ग्राफ चक्रीय था या नहीं।MySQL रिकर्सिव चक्र पहचान प्रक्रिया
किसी कारण से, पहचान अतीत पहले प्रत्यावर्तन काम नहीं करता है यहाँ टिप्पणियां विवरण समझा साथ कोड है:।
निम्नलिखित कार्य MySQL में ME द्वारा लागू किया गया (भ्रम से बचने के):
-concat_set(): रिटर्न एक खाली सेट
के मामले में गलत सेट 'के लिए लेखांकन के दो सेटों का समापन-remove_first(): किनारों के नोड्स देता है, किनारों के बीच सीमांकक है ':' तो एक बढ़त इस '12 की तरह दिखता है: 15 'सेट
-get_left_node()/get_right_node से पहले सदस्य को हटा
CREATE PROCEDURE `is_cyclic`(
IN `singleedge` VARCHAR(15),
IN `edgeset` VARCHAR(1024),
IN 'left_set' VARCHAR(512),
OUT `cyclic` BOOLEAN)
BEGIN
DECLARE se_left VARCHAR(5);
DECLARE es_left VARCHAR(5);
DECLARE se_right VARCHAR(5);
DECLARE es_right VARCHAR(5);
Call get_left_node(singleedge, se_left);
Call get_left_node(SUBSTRING_INDEX(edgeset, ',', 1), es_left);
Call get_right_node(singleedge, se_right);
Call get_right_node(SUBSTRING_INDEX(edgeset, ',', 1), es_right);
--is edgeset emptY?
IF LENGTH(edgeset)= 0 AND LENGTH(left_set) = 0 THEN
BEGIN
SET cyclic= false;
END;
--are singeeledge and first edge in edgeset the same?
ELSEIF ((se_left = es_left
OR se_left= es_right)
AND(se_right = es_left
OR se_right = es_right)) THEN
BEGIN
set cyclic= true;
END;
--do singleedge and first edge in edgeset share any vertices?
ELSEIF se_left = es_left
OR se_left= es_right
OR se_right = es_left
OR se_right = es_right
THEN
--check for all possiblities
BEGIN
--if left vertex of singleedge and left vertex of current edge in front of edgeset are the same
IF se_left=es_left THEN
BEGIN
--test if the edge of combined uncommon vertices (forming concat(se_right,':',es_right)) exists in the remaining edgeset concatanated with the left_set
CALL is_cyclic(concat(se_right,':',es_right),concat_set(left_set,remove_first(edgeset)), '', cyclic);
--if the recursion returns cyclic=false, then remove the considered edge from edgeset and continue trying to match the original singleedge with the rest of edgeset
IF cyclic=false THEN
CALL is_cyclic(singleedge, remove_first(edgeset), left_set, cyclic);
END IF;
END;
ELSEIF se_left= es_right THEN
BEGIN
CALL is_cyclic(concat(se_right,':',es_left), concat_set(left_set, remove_first(edgeset)), '', cyclic);
IF cyclic=false THEN
CALL is_cyclic(singleedge, remove_first(edgeset), left_set, cyclic);
END IF;
END;
ELSEIF se_right=es_left THEN
BEGIN
CALL is_cyclic(concat(se_left,':',es_right), concat_set(left_set, remove_first(edgeset)), '', cyclic);
IF cyclic=false THEN
CALL is_cyclic(singleedge, remove_first(edgeset), left_set, cyclic);
END IF;
END;
ELSE
BEGIN
CALL is_cyclic(concat(se_left,':',es_left), concat_set(left_set, remove_first(edgeset)), '', cyclic);
IF cyclic=false THEN
CALL is_cyclic(singleedge, remove_first(edgeset), left_set, cyclic);
END IF;
END;
END IF;
END;
ELSE
BEGIN
--if the current edge being considered from the edgeset does not contain any vertex in common with singleedge, set it aside into left_set and call is_cyclic recurisvely with the edge removed
SET left_set = concat_set(left_set, SUBSTRING_INDEX(edgeset, ',', 1));
CALL is_cyclic(singleedge, remove_first(edgeset), left_set, cyclic);
END;
END IF;
END
मैं बस एक लूप में रिकर्सन को खोलना चाहता हूं। यह कोड को थोड़ा उलझन में डाल सकता है, लेकिन यह पहले से ही बहुत बदसूरत है। – siride