public static function DijkstraAlgorithmByDB($first, $finish)
 {
     global $LINK_DB;
     if ($first == $finish) {
         return array(0, array($first));
     }
     $edge_table = PWRelatedWords::getTableName();
     // table of related words (words and distance between them)
     $path_table = PWShortPath::getTableName();
     // table of shortest paths (first, last, next-to-last vertexes, length of path)
     //print "$first, $finish";
     $query = "SELECT lemma_id1 FROM {$edge_table} WHERE lemma_id1='{$first}' or lemma_id2='{$first}' LIMIT 1";
     // check if any edge with $first exists
     $res_exist = $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
     if ($LINK_DB->query_count($res_exist) == 0) {
         return array(0, NULL);
     }
     $query = "SELECT lemma_id1 FROM {$edge_table} WHERE lemma_id1='{$finish}' or lemma_id2='{$finish}' LIMIT 1";
     // check if any edge with $finish exists
     $res_exist = $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
     if ($LINK_DB->query_count($res_exist) == 0) {
         return array(0, NULL);
     }
     $success = 0;
     // the condition of finding the shortest path in the given vertex ($finish)
     $count_row = 1;
     $query = "UPDATE {$path_table} SET mark=0 where lemma_id_1=" . $first;
     // mark all vertexes as unvisited (if already any paths in DB exists)
     //        $query = "DELETE FROM $path_table where lemma_id_1=".$first; // mark all vertexes as unvisited (if already any paths in DB exists)
     $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
     $prev = $first;
     $path_len = 0;
     //print "<PRE>";
     $count = 0;
     //print $first;
     //return;
     while (!$success && $count_row) {
         // until all vertixes will not be visited
         $count++;
         //  && $count<3
         print "<p>" . $count . ": " . $count_row . ".-----------------------------</p>";
         //print_r($finish_arr);
         //print_r($len_arr);
         $query = "SELECT * FROM {$edge_table} WHERE lemma_id1='{$prev}' or lemma_id2='{$prev}'";
         // search nearest vertexes to $prev (НЕТ необходимости сортировать, так как неважно в какой последовательности ставятся метки)
         $res_neib = $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
         while ($row_neib = $res_neib->fetch_object()) {
             if ($row_neib->lemma_id1 == $prev) {
                 $last = $row_neib->lemma_id2;
             } else {
                 $last = $row_neib->lemma_id1;
             }
             $new_path_len = $path_len + $row_neib->weight;
             // path length from $prev to $last (neighbour of $prev via semantic relations)
             $query = "SELECT path_len,mark FROM {$path_table} WHERE lemma_id_1='{$first}' and lemma_id_n='{$last}'";
             // recounted only unvisited vertexes
             //print "<P>$query";
             $res_path = $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
             if ($LINK_DB->query_count($res_path) == 0) {
                 // 1. this is new path from $start to $finish which is absent in table pw_short_path_LANG_CODE
                 $query = "INSERT INTO {$path_table} (`lemma_id_1`, `lemma_id_n`, `path_len`, `lemma_id_prev_n`, mark) VALUES ({$first}, {$last}, {$new_path_len}, {$prev}, 0)";
                 //print "<P>$query";
                 $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
             } else {
                 // 2. already (one) path from $start to $finish does exist, then update (length and previous word) only if length of new path is shorter
                 $row_path = $res_path->fetch_object();
                 if ($row_path->mark == 0 && $new_path_len < $row_path->path_len) {
                     $query = "UPDATE {$path_table} SET path_len={$new_path_len}, lemma_id_prev_n={$prev} WHERE lemma_id_1={$first} and lemma_id_n={$last}";
                     //print "<P>$query";
                     $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
                 }
             }
         }
         $query = "SELECT path_len, lemma_id_n FROM {$path_table} WHERE lemma_id_1='{$first}' and mark=0 order by path_len";
         // choose minimal distance of path from first to any unvisited vertex
         $res_min = $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
         $count_row = $LINK_DB->query_count($res_min);
         if (!$count_row) {
             // all paths from start are marked as visited
             $path_len = 0;
         } else {
             // choose vertex with minimal distance
             $row_min = $res_min->fetch_object();
             // get only one row - minimal path length
             $path_len = $row_min->path_len;
             // choose minimal distance of path from first to any unvisited vertex
             $prev = $row_min->lemma_id_n;
             // choose unvisited vertex with minimal distance
         }
         //print "<p>prev:$prev, path_len:".$path_len;
         $query = "UPDATE {$path_table} SET mark=1 where lemma_id_1={$first} and lemma_id_n={$prev}";
         // mark vertex $prev as unvisited
         //print "<P>$query";
         $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
         if ($prev == $finish) {
             // the shortest path in $finish are found!!
             $success = 1;
         }
     }
     print "<p>{$count} iterations";
     if ($success) {
         //
         $path = array($finish);
         $prev = $finish;
         while ($prev != start) {
             $query = "SELECT lemma_id_prev_n FROM {$path_table} WHERE lemma_id_1='{$first}' and lemma_id_n='{$prev}' order by path_len LIMIT 1";
             // choose minimal distance of path from first to any unvisited vertex
             $res = $LINK_DB->query_e($query, "Query failed in file <b>" . __FILE__ . "</b>, string <b>" . __LINE__ . "</b>");
             $row = $res->fetch_object();
             $prev = $row->lemma_id_prev_n;
             array_unshift($path, $prev);
         }
         return array($path_len, $path);
     } else {
         return array(NULL, NULL);
     }
     // any path from $first to $finish are not found
 }
Example #2
0
 public static function setLangCode($lang_code)
 {
     self::$lang_code = $lang_code;
     self::$table_name = 'pw_short_path_' . $lang_code;
 }
Example #3
0
// PhpMorphy
include "phpmorphy.inc.php";
//include_once(SITE_ROOT."phpmorphy/src/common.php");
foreach ($_REQUEST as $var => $value) {
    /*
    TODO!!! check vars
    */
    ${$var} = $value;
}
/*******************************
 * Init constants and variables
 *******************************/
define('NAME_DB', 'ruwik');
$config['hostname'] = 'localhost';
$config['dbname'] = NAME_DB;
$config['user_login'] = '******';
$config['user_password'] = '******';
$config['admin_login'] = '******';
$config['admin_password'] = '';
## DB connection
## mysql>GRANT SELECT ON %.* TO pw_user@'%' identified by '';
## mysql>GRANT SELECT, INSERT, UPDATE, CREATE, DROP, INDEX ON %.* TO pw_admin@'%' identified by '';
## mysql>FLUSH PRIVILEGES;
##
$LINK_DB = new DB($config['hostname'], $config['user_login'], $config['user_password'], $config['dbname']);
define('LangCode', 'ru');
PWLemma::setLangCode(LangCode);
PWRelatedWords::setLangCode(LangCode);
PWShortPath::setLangCode(LangCode);
// из-за этого слетают стили
//include_once(LIB_DIR."multi/".LangCode."/WMeaning.php");