コード例 #1
0
void scn::RunSPFA(UGraph::pGraph graph,size_t indexOfSource, std::unordered_map<size_t,size_t> &distance)
{
   assert(graph->HasNode(indexOfSource));
//   Map<size_t>& distance = distance_sssp;
   //distance, stored the distance information of each node
   //init
   for(auto node = graph->begin(); node != graph->end(); node++)
   {
      distance[*node] = Graph::NaF;
   }
   distance[indexOfSource] = 0;
   queue<size_t> queue_buffer;
   unordered_set<size_t> in_queue;
   queue_buffer.push(indexOfSource);//push source node
   size_t front;
   while(!queue_buffer.empty())
   {
      front = queue_buffer.front();
      queue_buffer.pop();
      in_queue.erase(front);
      auto node = graph->find(front);
      for(auto other = node->begin(); other != node->end(); other++)
      {
	 if(in_queue.find(*other) == in_queue.end() &&
	    distance[front] + 1 < distance[*other])
	 {
	    distance[*other] = distance[front] + 1;
	    queue_buffer.push(*other);
	    in_queue.insert(*other);
	 }
      }
   }
}
コード例 #2
0
double scn::GetSearchInfo(UGraph::pGraph graph,size_t indexOfSource, size_t indexOfTarget)
{
   assert(graph->HasNode(indexOfSource));
   assert(graph->HasNode(indexOfTarget));
   assert(indexOfSource != indexOfTarget);
   std::unordered_map<size_t,size_t> distance;
   //get shortest distance
   //auto& distance = distance_sssp;
   RunSPFA(graph,indexOfSource,distance);
   double sum = 0;
   //search in breadth-first way
   queue<pair<size_t, double>> path_queue;//pair : indexOfNode,
					  //probability of path
   path_queue.push(make_pair(indexOfTarget, 1.0));
   while(!path_queue.empty())
   {
      auto current = path_queue.front();
      auto node = (*graph)[current.first];
      path_queue.pop();
      
      for(auto other = node->begin(); other != node->end(); other++)
      {//put all of previous-node in path into queue
	 if(distance[*other] == distance[*node] - 1)
	 {
	    if(distance[*other] == 0)
	       sum += current.second / static_cast<double>(node->GetDegree());
	    else
	       path_queue.push(make_pair(*other, current.second / 
					 static_cast<double>((*graph)[*other]->GetDegree() - 1))); 
	 }
      }
   }
   return - log(sum)/log(2.0);
}
コード例 #3
0
size_t scn::GetShortestDistance(UGraph::pGraph graph,size_t indexOfSource, size_t indexOfTarget)
{
   assert(graph->HasNode(indexOfSource) && graph->HasNode(indexOfTarget));
   //breadth-first search
   queue<size_t> search_queue;
   std::unordered_map<size_t,size_t> distance;
   unordered_set<size_t> in_queue;
   size_t front;
   //initial
   distance[indexOfSource] = 0;
   search_queue.push(indexOfSource);
   in_queue.insert(indexOfSource);
   
   while(!search_queue.empty())
   {
      front = search_queue.front();
      search_queue.pop();
      in_queue.erase(front);

      auto node = graph->find(front);
      for(auto other = node->begin(); other != node->end(); other++)
      {
	 if(*other == indexOfTarget)
	    return distance[*node] + 1;

	 if(in_queue.find(*other) == in_queue.end() &&
	    (distance.find(*other) == distance.end() || distance[front] + 1 < distance[*other]))
	 {
	    distance[*other] = distance[front] + 1;
	    search_queue.push(*other);
	    in_queue.insert(*other);
	 }
      }
   }
   //if this point is reached, the indexOfTarget is an isolated node 
   return Graph::NaF;
}
コード例 #4
0
void scn::RunDjikstra(UGraph::pGraph graph,size_t indexOfSource,std::unordered_map<size_t,size_t> &distance)
{
   //auto& distance = distance_sssp;//using distance_sssp eariler
   assert(graph->HasNode(indexOfSource));
   //init
   //distance.reserve(graph->GetNumberOfNodes());
   for(auto node = graph->begin(); node != graph->end(); node++)
   {
      distance[*node] = Graph::NaF;
   }
   distance[indexOfSource] = 0;

   list<size_t> queue;
   //fill index of nodes into queue
   for(size_t i = 0; i < graph->GetNumberOfNodes(); i++)
   {
      queue.push_back(i);
   }
   //begin
   size_t next_distance;
   while(!queue.empty())
   {
      //get min one
      auto min = min_element(queue.begin(), queue.end(), 
			     [&](const size_t &one, const size_t &two)->bool
			     {
				if(distance[one] < distance[two])
				   return true;
				else
				   return false;
			     });
      auto node = graph->find(*min);  

      if(distance[*node] < Graph::NaF)
	 next_distance = distance[*node] + 1;
      else
	 next_distance = Graph::NaF;
      //relax neighbors
      for(auto other = node->begin(); other != node->end(); other++)
      {
	 if(distance[*other] > next_distance)
	 {
	    distance[*other] = next_distance;
	 } 
      }
      queue.erase(min);
   }
}
コード例 #5
0
pair<size_t, size_t> scn::GetNumberOfShortestPath(UGraph::pGraph graph,size_t indexOfSource, size_t indexOfTarget,
							 size_t indexOfThrough)
{
   assert(graph->HasNode(indexOfSource));
   assert(graph->HasNode(indexOfTarget));
   //find shortest path
    std::unordered_map<size_t,size_t> distance;
	//auto& distance = distance_sssp;
   RunSPFA(graph,indexOfSource,distance);
   
   if(indexOfThrough == UGraph::NaF)
   {//no passing through any specified node
      size_t sum = 0;
      queue<size_t> path;
      path.push(indexOfTarget);
      //breadth-first search
      while(!path.empty())
      {
	 if(indexOfSource == path.front())
	    sum++;
	 else
	 {
	    auto current = graph->find(path.front());
	    size_t current_distance = distance[*current];
	    for(auto other = current->begin(); other != current->end(); other++)
	    {
	       if(distance[*other] == current_distance - 1)
		  path.push(*other);
	    }
	 }
	 path.pop();
      }
      return make_pair(sum, sum);
   }
   else
   {
      assert(graph->HasNode(indexOfThrough));
      assert(indexOfSource != indexOfThrough);
      assert(indexOfTarget != indexOfThrough);

      size_t sum_all = 0;
      size_t sum_through = 0;
      queue<pair<size_t, bool>> path;//pair(indexOfNode, Does it Pass
				     //through the give node?
      path.push(make_pair(indexOfTarget, false));
      //breadth-first search
      while(!path.empty())
      {
	 auto current = path.front();
	 if(current.first == indexOfThrough) 
	    current.second = true;
	 
	 if(indexOfSource == current.first)
	 {
	    sum_all++;
	    if(current.second)
	       sum_through++;
	 }
	 else
	 {
	    size_t current_distance = distance[current.first];
	    auto current_node = graph->find(current.first);
	    for(auto other = current_node->begin(); other != current_node->end(); other++)
	    {
	       if(distance[*other] == current_distance - 1)
		  path.push(make_pair(*other, current.second));
	    }
	 }
	 path.pop();
      }
      return make_pair(sum_all, sum_through);
   }
}