2016-06-20 23 views
0

我正在使用Oracle 10.Oracle - 計算圖中的路徑值

我有描述圖的節點和路徑的數據。 我想構建一個查詢,描述端點之間的所有路由及其值或遍歷開銷。

實施例的數據:

NodeId1 NodeId2 Endpoint1 Endpoint2 Value 
    1170  8406  34210  (null)  39 
    8411  8410  (null)  34260  1 
    8411  4275  (null)  32231  60 
    8406  8405  (null)  34287  1 
    8406  8411  (null)  (null)  26 

介紹看起來像這樣的曲線圖(成本括號,端點是方括號):

1170    8406    8405 
[]-----------------o----------------[] 
     (39)  |  (1) 
        | 
        |(27) 
        |    4275 
       8411 o----------------[] 
        |  (60) 
        | 
       (1)| 
        | 
        [] 
        8410 

輸出應看起來像:

Start  End Cost 
1170 4275  126 
1170 8405  40 
1170 8410  67 
8405 4275  88 
8405 8410  29 
4275 8410  61 

我不需要雙向輸出(1170到8406和8406到1170),但是它可以幫助進一步使用結果,所以如果可能包括,這將是很好的。

+0

相反,你似乎相信什麼,StackOverflow的是不是一個免費編碼服務(或考試應答服務)。您需要展示您的代碼,以及相關的示例輸入,預期輸出(您擁有的)和實際錯誤信息以及您對於卡住的位置的評論。請盡力解決這個問題,人們可能會幫助你。祝你好運。 – shellter

回答

0

甲骨文設置

CREATE FUNCTION sum_Number_List(
    i_str IN VARCHAR2, 
    i_delim IN VARCHAR2 DEFAULT ',' 
) RETURN NUMBER DETERMINISTIC 
AS 
    p_result  NUMBER := 0; 
    p_start  NUMBER(5) := 1; 
    p_end   NUMBER(5); 
    c_len CONSTANT NUMBER(5) := LENGTH(i_str); 
    c_ld CONSTANT NUMBER(5) := LENGTH(i_delim); 
BEGIN 
    IF c_len > 0 THEN 
    p_end := INSTR(i_str, i_delim, p_start); 
    WHILE p_end > 0 LOOP 
     p_result := p_result + TO_NUMBER(SUBSTR(i_str, p_start, p_end - p_start)); 
     p_start := p_end + c_ld; 
     p_end := INSTR(i_str, i_delim, p_start); 
    END LOOP; 
    IF p_start <= c_len + 1 THEN 
     p_result := p_result + TO_NUMBER(SUBSTR(i_str, p_start, c_len - p_start + 1)); 
    END IF; 
    END IF; 
    RETURN p_result; 
END; 
/

CREATE TABLE table_name (NodeId1, NodeId2, Endpoint1, Endpoint2, Value) AS 
SELECT 1170, 8406, 34210, null, 39 FROM DUAL UNION ALL 
SELECT 8411, 8410, null, 34260, 1 FROM DUAL UNION ALL 
SELECT 8411, 4275, null, 32231, 60 FROM DUAL UNION ALL 
SELECT 8406, 8405, null, 34287, 1 FROM DUAL UNION ALL 
SELECT 8406, 8411, null, null, 26 FROM DUAL; 

查詢

WITH directedgraph AS (
    SELECT NodeID1 AS f, 
     NodeID2 AS t, 
     EndPoint1 AS isStart, 
     EndPoint2 AS isEnd, 
     Value 
    FROM table_Name 
    UNION ALL 
    SELECT NodeID2 AS f, 
     NodeID1 AS t, 
     EndPoint2 AS isStart, 
     EndPoint1 AS isEnd, 
     Value 
    FROM table_Name 
) 
SELECT CONNECT_BY_ROOT(f) AS "START", 
     t AS "END", 
     SUM_NUMBER_LIST(SUBSTR(SYS_CONNECT_BY_PATH(value, ','), 2)) AS cost 
FROM directedgraph 
WHERE CONNECT_BY_ISLEAF = 1 
AND isEnd IS NOT NULL 
START WITH isStart IS NOT NULL 
CONNECT BY NOCYCLE 
      PRIOR t = f 
AND  PRIOR f <> t; 

輸出

 START  END  COST 
---------- ---------- ---------- 
     1170  8405   40 
     1170  4275  125 
     1170  8410   66 
     4275  1170  125 
     4275  8405   87 
     4275  8410   61 
     8405  1170   40 
     8405  4275   87 
     8405  8410   28 
     8410  4275   61 
     8410  1170   66 
     8410  8405   28