Quantcast
Viewing all articles
Browse latest Browse all 13

PHP bidirectional algorithm to find connection between linked users

This is the version (2.0) of our earlier post Find connection path between two users in a social network using PHP and http://blog.kunals.com/php-code-find-2-users-connected-friends-social-network/. In this version bidirectional search is performed from both ends/nodes/users and if found path is displayed.

This is based on graph traversal, breadth first search (bfs), bi-directional bfs. Nodes are the users and edges are considered as link between two users i.e. friendship with weight 1.

<?php
//bfs algorithm

$user_from=1; //start user (node)
$user_find=10; //end user (node)
$level_max=6;
$sts_found=0;

$list_parents=array();
$list_pals=array();
$list_depth=array();

function get_pals($usrid)
{
$qry_pals="SELECT * FROM pals WHERE pal_act='1' AND pal_sts='1' AND (pal_usrid='$usrid' OR pal_usrid_by='$usrid')";
$rsl_pals=mysql_query($qry_pals);
$n_pals = mysql_num_rows($rsl_pals);

$list_pals=array();
if($n_pals!=0)
{
for($i=0;$i<$n_pals;$i++)
{
$arr_pals =  mysql_fetch_row($rsl_pals);

$pal_usrid=$arr_pals[3];
$pal_usrid_by=$arr_pals[4];

if($pal_usrid_by==$usrid)
{
$pal_usrid_to=$pal_usrid;
}
else
{
$pal_usrid_to=$pal_usrid_by;
}
$list_pals[]=$pal_usrid_to;
}
}

return($list_pals);
}

$list_todo[0][]=$user_from;    //adding starting node/user
$list_todo[1][]=$user_find;
$loop_count_max=100;    //use this if you want to stop searching after certain number of nodes have been examined it should be around 10000
$loop_count_max=100;
$loop_count=0;
$node_level_now=0;
$loop_level_now=0;
$dir=0;
$diro=1;
$dir_level_now[0]=0;
$dir_level_now[1]=0;
$dir_level_total=$dir_level_now[0]+$dir_level_now[1];

$list_depth[$user_from]=$node_level_now;
$list_depth[$user_find]=$node_level_now;

//Finding desnitation node/user
while(count($list_todo[$dir])!=0)
{
$loop_count++; //if loop count is being used
$list_pals=array(); //intialising friends list for each loop

$node_now = reset($list_todo[$dir]);
//dir
$node_level_now=$list_depth[$node_now];
if($loop_level_now!=$node_level_now)
{
$diro=$dir;
$dir=($dir+1)%2;
if($dir==0)
{
$loop_level_now=$loop_level_now+1;
}
$dir_level_now[$dir]=$loop_level_now;
$dir_level_total=$dir_level_now[0]+$dir_level_now[1]+1;
}

$node_now=array_shift($list_todo[$dir]); //current node/child
$list_done[$dir][$node_now]=1;    //adding list of current node as done

$node_level_now=$list_depth[$node_now];
$node_level_next=$node_level_now+1;

$level_now=$list_depth[$node_now];
$level_next=$level_now+1;

//Validating if current loop is going within maximum degree
if($dir_level_total<$level_max)
{
$list_pals=get_pals($node_now);//Getting Friends
if(count($list_pals)>0)
{
foreach($list_pals AS $list_pals_val)
{
$pal_now=$list_pals_val;
//checking if exists in Done/processed list
if(!isset($list_done[$dir][$pal_now]))
{
if(in_array($pal_now,$list_todo[$diro]))
{
//If source is found.
$sts_found=1;  //setting success status to 1
$list_todo[$dir]=array();    //to end while loop
//$list_parents[$pal_now]=$node_now; //adding current node to backtrack path
$link_node=$pal_now;
$link_node_parent=$node_now;
}
else
{
if(!in_array($pal_now,$list_todo[$dir]))
{
//adding friend in ToDo list. Also assigning friend as child
$list_todo[$dir][]=$pal_now;
$list_parents[$pal_now]=$node_now;
$list_depth[$pal_now]=$node_level_next;
}
}
}
}
}
}
else
{
//for exiting from main while loop when maximum depth/degrees is reached
$list_todo[$dir]=array();
}
//for exiting from main while loop when maximum number of loop count reached. For system efficiency loop is used.
if($loop_count>$loop_count_max)
{
$list_todo[$dir]=array();
}

}

//
echo "<div>";
if($sts_found==0)
{
echo "<div style='font-weight:bold;color:#ff0000;'>No Connection found</div>";
}
else
{
//if found
echo "<div style='font-weight:bold;color:#00ff00;'>Connection found</div>";
if(count($list_parents)>0)
{
//dir 0
$grandparent=$user_from;//source node
$child=$link_node;
if($dir==0)
{
$child=$link_node_parent;
$parent_chain[0][]=$child;
}
else
{
$parent_chain[0][]=$child;
}
//backtracking the path
while($child!=$grandparent)
{
$key=$list_parents[$child];
$parent_chain[0][]=$key;
$child=$key;
}

//dir 1
$grandparent=$user_find;//source node
$child=$link_node;
if($dir==1)
{
$child=$link_node_parent;
$parent_chain[1][]=$child;
}
else
{
$parent_chain[1][]=$child;
}
//backtracking the path
while($child!=$grandparent)
{
$key=$list_parents[$child];
$parent_chain[1][]=$key;
$child=$key;
}

$count_parent_chain[0]=count($parent_chain[0]);
$count_parent_chain[1]=count($parent_chain[1]);

$count_parent_chain=$count_parent_chain[0]+$count_parent_chain[1]-1;
echo "<div style='color:#0000ff; margin:10px;'>Linked with $count_parent_chain ".$count_parent_chain[0]. $count_parent_chain[1]." degree(s) as:</div>";

if($count_parent_chain>0)
{
$parent_chain_0_rev = array_reverse($parent_chain[0]);
$parent_chains=array_merge($parent_chain_0_rev,$parent_chain[1]);
echo "<div>";
echo implode(" > ", $parent_chains);
echo "</div>";
}
}
}
echo "</div>";

?>

The post PHP bidirectional algorithm to find connection between linked users appeared first on KB Web Thoughts.


Viewing all articles
Browse latest Browse all 13

Trending Articles