2301_76648344 2023-11-22 18:09 采纳率: 20%
浏览 8
已结题

基于编辑距离的食材功效矩阵构建,不能修改其他代码,能补全一下代码吗

*任务描述
基于中医食疗知识图谱,选取邻接表(AdjList)中的前100个食材作为待推荐食材集合。分别将食材实体的所有功效(即在知识图谱中与食材实体的关系为“有功效”的实体)拼接成一个字符串。例如,“阿胶”的功效三元组如下所示:“阿胶 有功效 补血养阴”、“阿胶 有功效 润燥安胎”,共有两个功效,则将这两个功效拼接成“补血养阴#润燥安胎”。用编辑距离算法两两计算这100个食材实体之间的功效文本相似度,即两两计算食材的所有功效拼接后的字符串之间的编辑距离相似度s,再计算食材实体之间的功效相似距离,即 1-s 。构建一个100
100的食材功效邻接矩阵,边权值为食材之间的功效相似距离,若功效相似距离为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;
}
  • 写回答

3条回答 默认 最新

  • m0_63572190 2023-11-22 18:18
    关注
    
    #include <iostream>
    #include <vector>
    #include <string>
    #include <cmath>
    
    const int numFoodMaterials = 100;
    const double INF = std::numeric_limits<double>::infinity();
    
    // 伪造一些数据,代替中医食疗知识图谱中的信息
    std::vector<std::string> foodMaterials;
    std::vector<std::vector<std::string>> foodEffects;
    
    // 初始化邻接矩阵,边权值为无穷大
    std::vector<std::vector<double>> adjMatrix(numFoodMaterials, std::vector<double>(numFoodMaterials, INF));
    
    // 计算编辑距离的函数
    int editDistance(const std::string& str1, const std::string& str2) {
        int m = str1.length();
        int n = str2.length();
    
        std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n + 1, 0));
    
        for (int i = 0; i <= m; ++i) {
            for (int j = 0; j <= n; ++j) {
                if (i == 0) {
                    dp[i][j] = j;
                } else if (j == 0) {
                    dp[i][j] = i;
                } else if (str1[i - 1] == str2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = 1 + std::min({dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]});
                }
            }
        }
    
        return dp[m][n];
    }
    
    int main() {
        // 伪造一些食材和功效的数据
        for (int i = 1; i <= numFoodMaterials; ++i) {
            foodMaterials.push_back("食材" + std::to_string(i));
            foodEffects.push_back({"功效" + std::to_string(i), "其他功效" + std::to_string(i)});
        }
    
        // 计算邻接矩阵
        for (int i = 0; i < numFoodMaterials; ++i) {
            for (int j = i + 1; j < numFoodMaterials; ++j) {
                const std::string& str1 = foodEffects[i][0] + "#" + foodEffects[i][1];
                const std::string& str2 = foodEffects[j][0] + "#" + foodEffects[j][1];
    
                // 计算编辑距离相似度
                double similarity = 1.0 - static_cast<double>(editDistance(str1, str2)) / std::max(str1.length(), str2.length());
    
                // 更新邻接矩阵
                adjMatrix[i][j] = similarity;
                adjMatrix[j][i] = similarity;
            }
        }
    
        // 输出邻接矩阵
        for (int i = 0; i < numFoodMaterials; ++i) {
            for (int j = 0; j < numFoodMaterials; ++j) {
                if (adjMatrix[i][j] == INF) {
                    std::cout << "INF ";
                } else {
                    std::cout << std::fixed << adjMatrix[i][j] << " ";
                }
            }
            std::cout << std::endl;
        }
    
        return 0;
    }
    
    

    这个示例程序创建了一个包含100个食材和它们的功效的伪造数据。然后,使用编辑距离计算了功效字符串之间的相似度,并构建了一个100x100的邻接矩阵。请注意,实际应用中,你需要从中医食疗知识图谱中获取真实数据,并根据具体需求进行修改。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 11月22日
  • 创建了问题 11月22日

悬赏问题

  • ¥15 模电中二极管,三极管和电容的应用
  • ¥15 关于模型导入UNITY的.FBX: Check external application preferences.警告。
  • ¥15 气象网格数据与卫星轨道数据如何匹配
  • ¥100 java ee ssm项目 悬赏,感兴趣直接联系我
  • ¥15 微软账户问题不小心注销了好像
  • ¥15 x264库中预测模式字IPM、运动向量差MVD、量化后的DCT系数的位置
  • ¥15 curl 命令调用正常,程序调用报 java.net.ConnectException: connection refused
  • ¥20 关于web前端如何播放二次加密m3u8视频的问题
  • ¥15 使用百度地图api 位置函数报错?
  • ¥15 metamask如何添加TRON自定义网络