2013-06-02 49 views
1

我的目標是建立術語知識圖;每學期;我可以(以某種方式輕鬆地)從該術語中提取所有其他術語的直接聯繫;下表(可以存儲在MySQL)是什麼我可以提取一個例子:提取知識圖數據結構之間的連接

enter image description here

在從上面的表中的每一行;我們會看到一個直接(不受指控)的連接,以及它的重量(或強度)。 請注意,所有連接都是無向的。

所以問題是;我們能否找出間接的術語之間的關係?例如; Leonardo Da VinciMichelangelo之間的一個鏈接是通過術語Italy;這可以表示爲:

Leonardo Da Vinci -- 4 (weight) -- Italy -- 6 (weight) -- Michelangelo

使用PHP和MySQL,我們可以簡單地做了以下內容:

<? include('db_settings.php'); ?> 

<?php 

    $con = mysqli_connect($myDB_server, $myDB_userName, $myDB_password, $myDB_name); 

    if (mysqli_connect_errno($con)) 
     echo "Error :(<BR/>"; 

    $connectionFrom = 'Leonardo Da Vinci'; 

    $result = mysqli_query($con, "SELECT * FROM termLinks WHERE termLinks_t1 = '$connectionFrom'"); 

    while($row = mysqli_fetch_array($result)) 
    { 
     $currConnection = $row[2]; 
     $newResult = mysqli_query($con, "SELECT * FROM termLinks WHERE termLinks_t2 = '$currConnection'"); 

     while ($newRow = mysqli_fetch_array($newResult)) 
     { 
      if (strcmp($newRow[1], $connectionFrom) != 0) 
       echo "There is a connection between " . $connectionFrom . " and " . $newRow[1] . " through " . $currConnection; 
     } 

     echo "<BR/>"; 
    } 

    mysqli_close($con); 
?> 

這將導致以下:

There is a connection between Leonardo Da Vinci and Michelangelo through Italy There is a connection between Leonardo Da Vinci and Lorenzo de’ Medici through Renaissance

但在其他情況;我們可能需要通過多個鏈接才能找到連接;例如存在通過以下Lorenzo de’ MediciMichelangelo之間的連接:

Lorenzo de’ Medici -- Renaissance -- Leonardo Da Vinci -- Italy -- Michelangelo

什麼是提取所有條款之間的所有連接的最佳方法?我明白這可能是一個非常複雜的問題,但我開放中,我也許可以建立一個我可以使用,而高效地提取所有連接的數據結構中的任何建議...

+1

查看[transitive closure](http://en.wikipedia.org/wiki/Transitive_closure)和[這些答案](http://stackoverflow.com/questions/3517524/best-known-transitive-closure -algorithm換圖表) –

回答

1

使用MySQL的GROUP_CONCAT,這將組合在一起的所有termLinks_t1有termLinks_t2共同點

SELECT 
    a.*, 
    (SELECT 
     GROUP_CONCAT(b.termLinks_t1) 
     FROM 
      termLinks b 
     WHERE 
      a.termLinks_t2 = b.termLinks_t2 AND 
      a.termLinks_t1 != b.termLinks_t1 
     GROUP BY 
      b.termLinks_t1 
     ) as connections 
FROM 
    termLinks 

所以它會返回類似(假定洛倫佐·德·美第奇也有意大利爲紐帶,否則connections也只是米開朗基羅)

termLinks_t1   termLinks_t2 connections 
Leonardo Da Vinci Italy   Michelangelo, Lorenzo de’ Medici 

至於第二種情況(深層鏈接)不知道我是否找到一些病態的reedit。