*任务描述
基于中医食疗知识图谱,选取邻接表(AdjList)中的前100个食材作为待推荐食材集合。分别将食材实体的所有功效(即在知识图谱中与食材实体的关系为“有功效”的实体)拼接成一个字符串。例如,“阿胶”的功效三元组如下所示:“阿胶 有功效 补血养阴”、“阿胶 有功效 润燥安胎”,共有两个功效,则将这两个功效拼接成“补血养阴#润燥安胎”。用编辑距离算法两两计算这100个食材实体之间的功效文本相似度,即两两计算食材的所有功效拼接后的字符串之间的编辑距离相似度s,再计算食材实体之间的功效相似距离,即 1-s 。构建一个100100的食材功效邻接矩阵,边权值为食材之间的功效相似距离,若功效相似距离为1,则表示为无穷。
编程要求
输出
食材功效邻接矩阵(无穷用INF表示)
测试说明
平台会对你编写的代码进行测试:
预期输出:
100100的食材功效邻接矩阵*
#include <bits/stdc++.h>
#define MVNum 10000
using namespace std;
const int INF = 9999;
string Relationship[] = {"有功效","有食谱","有推荐食材","有证机概要"};
typedef struct ArcNode {
int adjvex; // 该边所指向顶点的位置
int relationship; // 表示边的类型,即关系的类型,对应为数组下标
struct ArcNode* nextarc; // 下一条边
} ArcNode; // 边结点
string Entity[]= {"食材","疾病","功效","食谱","证机概要"};
typedef struct VNode {
int entity; // 表示顶点的类型,即实体的类型,对应为数组下标
string info; // 表示顶点的内容,即实体的内容
ArcNode* firstarc; // 指向第一条依附该顶点的边的指针
} VNode, AdjList[MVNum];
typedef struct {
AdjList vertices; // 邻接表
int vexnum, arcnum; // 图的当前顶点数和边数
} ALGraph;
typedef struct {
int vexs[100]; // 顶点表
double arcs[100][100]; // 邻接矩阵
int vexnum, arcnum; // 图的当前顶点数和边数
} AMGraph;
int LocateVex(ALGraph& G, string str) {
// 返回str在AdjList中的位置
for (int i = 0; i < G.vexnum; i++) {
if (G.vertices[i].info == str) {
return i;
}
}
return -1; // 如果找不到,返回 -1 表示错误
}
int LocateEntity(string str) {
// 返回str在Entity数组中的位置
for (int i = 0; i < sizeof(Entity) / sizeof(Entity[0]); i++) {
if (Entity[i] == str) {
return i;
}
}
return -1; // 如果找不到,返回 -1 表示错误
}
int LocateRelationship(string str) {
// 返回str在Relationship数组中的位置
for (int i = 0; i < sizeof(Relationship) / sizeof(Relationship[0]); i++) {
if (Relationship[i] == str) {
return i;
}
}
return -1; // 如果找不到,返回 -1 表示错误
}
void InitALGraph(ALGraph& G) {
// 初始化邻接表
G.vexnum = 0;
G.arcnum = 0;
for (int i = 0; i < MVNum; i++) {
G.vertices[i].entity = -1; // 初始化顶点的类型为 -1,表示错误
G.vertices[i].info = ""; // 初始化顶点的内容为空字符串
G.vertices[i].firstarc = nullptr; // 初始化顶点的边指针为空
}
}
void InitAMGraph(AMGraph& G) {
// 初始化邻接矩阵
}
void CreateAdjList(ALGraph& G, string filename) {
// 从filename中按顺序读取实体存入邻接表
ifstream infile(filename);
if (!infile) {
perror("Load");
exit(0);
}
string s1,s2;
while (infile >> s1>>s2) {
G.vertices[G.vexnum].info = s1;
G.vertices[G.vexnum].entity = LocateEntity(s2);
G.vertices[G.vexnum++].firstarc = NULL;
}
infile.close();
}
void CreateUDG(ALGraph& G, string filename) {
// 从filename中按顺序三元组存入邻接表
ifstream file(filename);
if (!file) {
perror("Load");
exit(0);
}
string s1, s2, s3;
while (file >> s1 >> s2 >> s3) {
int i = LocateVex(G, s1);
int j = LocateVex(G, s3);
ArcNode *p1 = new ArcNode;
p1->adjvex = j;
p1->relationship = LocateRelationship(s2);
p1->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p1;
ArcNode* p2 = new ArcNode;
p2->adjvex = i;
p2->relationship = LocateRelationship(s2);
p2->nextarc = G.vertices[j].firstarc;
G.vertices[j].firstarc = p2;
}
file.close();
}
int LevenshteinDistance(string s1, string s2) {
// 定义一个函数,计算两个字符串的莱文斯坦距离
int m = s1.length();
int n = s2.length();
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
for (int i = 0; i <= m; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= n; j++) {
dp[0][j] = j;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s1[i - 1] == s2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = min(dp[i - 1][j], min(dp[i][j - 1], dp[i - 1][j - 1])) + 1;
}
}
}
return dp[m][n];
}
double TextSimilarity(string s1, string s2) {
// 定义一个函数,计算两个字符串的文本相似度,文本相似度 = 1 - 莱文斯坦距离 / 最大字符串长度
int dist = LevenshteinDistance(s1, s2);
int max_len = max(s1.length(), s2.length());
double s = 1.0 - (double)dist / max_len;
return s;
}
void CreateAMG(AMGraph& GM, ALGraph& G) {
// 调用编辑距离算法计算相似度,构建食材之间的邻接矩阵
}
void PrintM(double M[100][100]) {
for (int i = 40; i < 60; i++) {
for (int j = 40; j < 60; j++) {
if (M[i][j] == INF) {
cout << "INF" << ' ';
}
else
cout << M[i][j] << setprecision(2) << ' ';
}
cout << endl;
}
}
int main() {
ALGraph G;
InitALGraph(G);
CreateAdjList(G, "/data/workspace/myshixun/3.2.1-基于编辑距离算法的食材功效邻接矩阵构建/entity.txt");
CreateUDG(G, "/data/workspace/myshixun/3.2.1-基于编辑距离算法的食材功效邻接矩阵构建/relationship.txt");
AMGraph GM;
InitAMGraph(GM);
CreateAMG(GM, G);
PrintM(GM.arcs);
return 0;
}