如何在C++路径寻优算法文件中嵌入样本数据直接运行
如何将图数据嵌入C++路径寻优算法代码(无需外部文件)
问题描述
现有一段用于寻找最短且盈利最高配对路径的C++算法代码,原本通过命令行参数读取外部图数据文件。需要将提供的样本图数据直接嵌入到.cpp文件中,无需依赖外部文件即可运行并得到结果,不清楚如何构建对应数据结构。
解决方案
核心思路是用内存字符串流(istringstream)模拟文件输入,替代原来的ifstream读取外部文件,同时将命令行参数硬编码为固定值。这样无需修改readGraph和bellmanFord等核心函数的逻辑,只需调整数据输入和参数传递部分。
修改步骤
- 添加必要头文件:引入
<sstream>以使用字符串流 - 嵌入样本数据:将样本数据格式化为多行字符串,保持与原文件一致的结构
- 替换文件输入流:用
istringstream替代ifstream,读取内存中的数据 - 硬编码命令行参数:将原本通过
argv获取的输入输出路径、源节点、目标节点、交易成本等参数改为固定值
修改后的完整代码
#include "readGraph.hpp" #include "ShortestPath.hpp" #include <limits> #include <fstream> #include <string> #include <iostream> #include <cmath> #include <chrono> #include <sstream> // 新增头文件 using namespace std; int main() { // 去掉命令行参数,改为无参main // -------------------------- 嵌入样本数据(样本2) -------------------------- const string graphData = R"(6 30 GBP EUR JPY CHF USD GLD 0 1 1.4599 GBP->EUR 0 2 189.05 GBP->JPY 0 3 2.1904 GBP->CHF 0 4 1.5714 GBP->USD 0 5 0.004816 GBP->GLD 1 0 0.684978 EUR->GBP 1 2 129.52 EUR->JPY 1 3 1.4978 EUR->CHF 1 4 1.0752 EUR->USD 1 5 0.003295 EUR->GLD 2 0 0.00528961 JPY->GBP 2 1 0.00772082 JPY->EUR 2 3 0.011574 JPY->CHF 2 4 0.008309 JPY->USD 2 5 0.0000255 JPY->GLD 3 0 0.456538 CHF->GBP 3 1 0.667646 CHF->EUR 3 2 86.4006 CHF->JPY 3 4 0.7182 CHF->USD 3 5 0.002201 CHF->GLD 4 0 0.636375 USD->GBP 4 1 0.93006 USD->EUR 4 2 120.351 USD->JPY 4 3 1.39237 USD->CHF 4 5 0.003065 USD->GLD 5 0 207.641 GLD->GBP 5 1 303.49 GLD->EUR 5 2 39215.7 GLD->JPY 5 3 454.339 GLD->CHF 5 4 326.264 GLD->USD )"; // ------------------------------------------------------------------------- // 用字符串流模拟文件输入 istringstream fin(graphData); // 硬编码输出文件路径(或改为cout直接输出到控制台) ofstream fout("output.txt"); // 硬编码交易成本、源节点、目标节点 double cost = 0.0; // 可根据需求修改 string sourceV = "GBP"; string destV = "EUR"; int** edgeL; double* weights; int numEdges; double totalDist = 0.0; // 初始化totalDist,避免未定义行为 string* e; //eLabels string* v; //vLabels /* edgeList version of readGraph */ int numVertices = readGraph(fin, edgeL, weights, numEdges, v, e); /* Checking input source and destination vertices and assigning their corresponding integer values */ int source = -1, dest = -1; for(int i = 0; i < numVertices; i ++){ if(sourceV == v[i]){ source = i; } if(destV == v[i]){ dest = i; } } // 检查源/目标节点是否存在 if (source == -1 || dest == -1) { cerr << "Source or destination vertex not found!" << endl; return 1; } int* prev; double* dist; int* path; int* cycle; /*Prepping the weights for bellmanFord by taking setting w[i] = -log(temp*(1-cost)) */ for(int i = 0; i < numEdges; i ++){ double temp = weights[i]; weights[i] = -1*log(temp*(1-cost)); // cout << weights[i] << endl; // 可选:注释掉减少输出 } /* Setting timers and invoking bellmanFord to catch arbitrage opportunity */ auto t1 = std::chrono::system_clock::now(); int x = bellmanFord(edgeL, weights, numVertices, numEdges, source, dist, prev); auto t2 = std::chrono::system_clock::now(); auto dur = t2-t1; auto durns = std::chrono::duration_cast<std::chrono::microseconds>(dur); double elapsed = durns.count(); /** If there is a negative loop, there is an arbitrage opportunity. * A path is derived using the appropriate getCycle method. * The path is printed to fout and meta data printed to the terminal. */ if(x != -1){ int cycleSize = getCycle(x, prev, numVertices, cycle); fout << numVertices << " " << cycleSize << endl; for(int i = 0; i < numVertices; i ++){ fout << v[i] << endl; } int idx = 0; for(int i = 0; i < cycleSize; i ++){ for(int j = 0; j < numEdges; j ++){ if(edgeL[j][0] == cycle[i] && edgeL[j][1] == cycle[i+1]){ totalDist += weights[j]; fout << cycle[i] << " " << cycle[i+1] << " " << exp(-1*weights[j]) << " " << e[j] << endl; idx = j; } } } cout << "Arbitrage Opportunity Detected!" << endl; cout << "Effective Exchange Rate: " << exp(-1*totalDist) << endl; cout << "Runtime: " << elapsed << " Microseconds" << endl; delete[] cycle; for (int i=0; i<numEdges; i++){ delete[] edgeL[i]; } } /** If there is no negative cycle. * The path is simply printed to fout and meta data printed to terminal. */ else{ // 简化判断,直接else即可 int pathSize = getPath(source, dest, prev, path); fout << numVertices << " " << pathSize - 1 << endl; for(int i = 0; i < numVertices; i++){ fout << v[i] << endl; } int temp; for(int i = 0; i < pathSize-1; i++){ temp = path[i]; for(int j = 0; j < numEdges; j ++){ if(edgeL[j][0] == path[i] && edgeL[j][1] == path[i+1]){ totalDist += weights[j]; fout << temp << " " << path[i+1] << " " << exp(-1*weights[j]) << " " << e[j] << endl; } } } cout << "Effective Exchange Rate: " << exp(-1*totalDist) << endl; cout << "Runtime: " << elapsed << " Microseconds" << endl; delete[] path; for (int i=0; i<numEdges; i++){ delete[] edgeL[i]; } } delete[] dist; delete[] prev; delete[] e; delete[] v; delete[] weights; delete[] edgeL; return 0; }
关键说明
- 样本数据嵌入:使用C++11及以上支持的原始字符串字面量(
R"(...)"),可以直接保留样本数据的换行和空格,避免转义字符的麻烦。如果使用旧标准,可以用"\n"替换换行。 - 字符串流替代文件流:
istringstream会将字符串内容模拟成文件输入流,完全兼容原有的readGraph函数,无需修改该函数的实现。 - 参数硬编码:将
cost、sourceV、destV等参数改为固定值,同时去掉main函数的命令行参数,简化运行流程。 - 修复潜在问题:初始化
totalDist为0,避免未定义行为;增加源/目标节点存在性检查,提升代码健壮性。
切换样本数据
如果需要使用样本1,只需替换graphData的内容为:
const string graphData = R"( 6 1 GBP EUR JPY CHF USD GLD 0 1 1.45543 GBP->EUR )";
内容的提问来源于stack exchange,提问作者Udbdjfj
相关产品推荐
相关产品推荐

