社交图中 2 个节点之间的连接程度
degree of connection between 2 nodes in a social graph
我试图找出社交图中 2 个实体之间的联系程度,其中
- 1
- 跳:1度 2
- 跳:2度 3
- 跳:3度等等。
顶点是实体,边是两个实体之间的友谊。给定这样的图形,我想分析图形并回答有关实体之间连接类型的查询。它可以是断开连接的图形。如果没有连接,它将返回 0。
它将输入作为-
Number_of_vertices Number_of_Edges
Edge 1
Edge 2
(So on.)
查询
输出
连接程度
例
Input
5 4
Abhs Krax // Edge 1
Harry Idrina // Edge 2
Harry Jigma // Edge 3
Harry Krax // Edge 4
Abhs Jigma // Query
输出
Degree : 3
我已经使用 BFS 找出 2 个节点之间的深度,但我的程序仅适用于 1 度。它无法测试队列的下一个后续成员,因此只能测试队列的第一个成员。我在代码中遗漏了什么?问题出在我无法追踪Connection()
功能上。
#include <iostream>
#include <list>
#include <string>
using namespace std;
class Vertex // Each vertex of the graph is represented by the object of the Vertex class
{
public:
// Fields in every vertex node
string name;
std::list<Vertex*> adjacencyList;
bool status;
int depth;
// Constructor which initializes the node
Vertex(string id)
{
name = id;
adjacencyList = list<Vertex*>();
status = false;
depth =0;
}
// Function to add edges by pushing the vertices to its adjacency list
void addEdge(Vertex *v)
{
adjacencyList.push_back(v);
}
};
class Graph{
public:
// Fields of the Graph node
int N;
std::list<Vertex> vertexList;
// Functions to be implemented
int Connection(Vertex,Vertex);
Graph(int n){ // Constructor
N = n;
vertexList = list<Vertex>();
}
/* This function first checks whether the vertex has been already added
to Vertex List of the Graph. If not found it would create the vertex
node and push the node into Vertex List. Then the edges are added by
updating the adjacency list of respective vertices. */
void addEdge(string to, string from ){
if(find(to))
{
Vertex entity_1 = Vertex(to); // New vertex node creation
vertexList.push_back(entity_1); // Pushing to the Vertex List
}
if(find(from))
{
Vertex entity_2 = Vertex(from);
vertexList.push_back(entity_2);
}
Vertex *v1 = &(*(find_it(to)));
Vertex *v2 = &(*(find_it(from)));
v1->addEdge(v2); // Updating respective adjacency list
v2->addEdge(v1);
}
// Function to check whether the vertex is already added in the Vertex List
int find(string check)
{
list<Vertex>::iterator it;
it = find_it(check);
if(it==vertexList.end())
return 1;
else
return 0;
}
// Function which returns pointer to a Vertex in the Vertex List
list<Vertex>::iterator find_it(string check)
{
list<Vertex>::iterator it;
for (it = vertexList.begin(); it != vertexList.end(); it++)
if((check.compare(it->name))==0)
break;
return it;
}
};
int main()
{
int numVertices,numEdges,i,result;
string to,from,queryTo,queryFrom;
cin>>numVertices>>numEdges;
Graph G = Graph(numVertices); // Creating the Graph object
for( i=0;i<numEdges;i++)
{
cin>>to>>from;
G.addEdge(to,from); // Adding Edges to Graph
}
cin>>queryTo>>queryFrom;
// The function you have to write is called here where the address of vertex
// node is passed.
result = G.Connection((*(G.find_it(queryTo))),(*(G.find_it(queryFrom))));
if(!result)
cout<<"No Connection";
else
cout<<"Degree : "<<result;
return 0;
}
int Graph::Connection(Vertex v1,Vertex v2)
{
// Mark all the vertices as not visited
Vertex s=Vertex("xx");
int i=0;
//list<Vertex>::iterator it;
Vertex *temp=&(*(vertexList.begin()));
while(!temp)
temp->status = false,++temp;
// Create a queue for BFS
list<Vertex> queue;
// Mark the current node as visited and enqueue it
v1.status=true;
queue.push_back(v1);
// it will be used to get all adjacent vertices of a vertex
int depth;
while (!queue.empty())
{
depth=0;
// Dequeue a vertex from queue and print it
s = queue.front();
queue.pop_front();
// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it visited
// and enqueue it
temp=s.adjacencyList.front();
while(temp!=NULL)
{
++depth;
// If this adjacent node is the destination node, then return true
if ((v2.name.compare(temp->name))==0)
{
v2.depth=depth;
return v2.depth;
}
// Else, continue to do BFS
if(temp->status==false)
{
temp->status = true;
queue.push_back(*temp);
}
++temp;
}
}
return 0;
}
我将假设您尝试计算的连接程度是节点之间的最短路径距离(具有均匀的边缘成本)。您可以使用 Floyd-Warshall 在 O(1) 时间内预处理图形并回答查询。实现起来非常简单。
int a[N][N]; /* adjacency matrix where N is max node count */
/* build graph here and init distances between distinct nodes to +INFINITY */
/* n is number of nodes */
for(int k = 0; k < n; k++)
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]);
要回答查询 (x,y),请打印 dist[x][y]。
您的 BFS 解决方案看起来过于复杂。使用vector<in> g[N]
来表示图形。添加带有g[x].push_back(y)
的边x->y
。BFS 看起来像:
queue<int> Q;
Q.push(s); /* start node */
for(int i = 0; i < n; i++)
{ dist[i] = INFINITY;
}
dist[s] = 0; /* distance to s is set to 0 */
while(Q.empty() == false)
{ int x = Q.front(); Q.pop();
for(int i = 0; i < g[x].size(); i++)
{ int y = g[x][i];
/* process edge x->y */
if(dist[y] == INFINITY)
{ dist[y] = dist[x] + 1;
Q.push(y);
}
}
}
S 和任何其他节点 t 之间的距离是 dist[s][t]。
如果您尝试查找等级为 1 的连接,您的代码也会在分段错误中崩溃。鉴于您的图表,请尝试找到"Harry Krax"。
我认为错误是使用指针Vertex * temp = temp=s.adjacencyList.front();
,然后尝试通过++temp;
访问下一个顶点。
这不是 std::list 与指针结合使用的工作方式。如果要使用 ++temp
访问下一个顶点,则可能需要使用迭代器 std::list<x>::iterator temp
。
您尝试执行的操作适用于像 int a[N]
这样的数组,因为数组的元素在内存中是相邻的。随着int * aptr = a
. ++aptr
说 temp 是移动到内存中的另一个位置,该位置的大小与更远的一个 int 大小相同。 std::list<x>
不会这样做。在这里,元素可以分散在内存中的不同位置。(简化)它的值和指向上一个和下一个元素的指针被存储。
- PC中的程序和PHONE中的本机描述应用程序之间的数据连接
- 在 QNX 中,如何管理服务器和客户端之间的 IPC 连接?
- 如何在 2 台主机之间保持 UDP 套接字连接打开
- 在QT中的两个窗口之间共享websocket连接
- 在两个类之间连接QPushButton
- 查找树(不属于任何特定类型的简单连接树)中两个节点之间的路径
- Visual Studio 中的套接字 c++ 应用程序无法通过两台计算机之间的以太网连接工作
- QT在两个类之间连接
- 如何在两个设备之间与TCP通信时修复错误"连接被拒绝"
- 我无法在用C++编写的服务器和用 C# 编写的客户端之间建立 UDP 连接
- 连接类实例和另一个类实例中的对话框之间的槽和信号
- 为什么使用 C++ 接口作为类之间的连接?
- 使用Isringstream和struct/vector在给定的数据之间建立连接
- 如何在C 中连接两个对象以在它们之间传输数据
- 通过直接连接或排队连接调用插槽的QTimer超时插槽之间的区别
- 类之间的 QT 连接
- 如何在两个类之间连接函数
- QObject 和级联控件之间的连接是什么?
- 尝试在Qt中连接隐藏信号的两种方式之间做出决定
- 无法在多个 Qthread的 QThread 和 finish() 信号之间连接