poj1094——Sorting It All Out

本文介绍了一种基于图论的拓扑排序算法实现方法,并通过C语言代码详细展示了该算法的具体步骤。该算法用于确定一系列任务之间的依赖关系,能够帮助解决实际问题中遇到的排序难题。

拓扑排序!具体方法见:http://www.cnblogs.com/xiaosuo/archive/2010/03/26/1690302.html

#include<stdio.h> #include<string.h> struct node { int u,v; }tt[1000]; int n,m,k,dgree[27],queue[1000],rear,front; bool flag,flag1,edge[27][27],vis[27]; void NPFTP() { int i; bool equal=true; rear=0;front=0; memset(edge,true,sizeof(edge)); memset(dgree,0,sizeof(dgree)); memset(vis,true,sizeof(vis)); for(i=1;i<=k;i++){ if(edge[tt[i].u][tt[i].v]){ edge[tt[i].u][tt[i].v]=false; dgree[tt[i].v]+=1; } } for(i=1;i<=n;i++) if(dgree[i]==0){ queue[++rear]=i; vis[i]=false; } if(rear>1) equal=false; memset(edge,true,sizeof(edge)); while(rear!=front) { front++;; for(i=1;i<=k;i++){ if(tt[i].u==queue[front]&&edge[tt[i].u][tt[i].v]){ edge[tt[i].u][tt[i].v]=false; dgree[tt[i].v]--; } } for(i=1;i<=n;i++) if(dgree[i]==0&&vis[i]){ vis[i]=false; queue[++rear]=i; } if(rear-front>1) equal=false; } if(rear==n&&equal){ flag1=false;flag=false; printf("Sorted sequence determined after %d relations: ",k); for(i=1;i<=rear;i++) printf("%c",queue[i]-1+'A'); printf(".\n"); } else if(rear<n){ flag1=false;flag=false; printf("Inconsistency found after %d relations.\n",k); } } int main() { int i,j; char p[5]; while(scanf("%d%d",&n,&m)!=EOF) { flag=true;flag1=true; if(n==0&&m==0) break; for(k=1;k<=m;k++) { scanf("%s",&p); tt[k].u=p[0]-'A'+1;tt[k].v=p[2]-'A'+1; } for(k=1;k<=m;k++) { if(flag1) NPFTP(); } if(flag) printf("Sorted sequence cannot be determined.\n"); } return 0; }

import json import copy import sys import csv import os import os sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) # sys.path.append('....') from lib import get_allpath as method_get_all_path from lib import cal_metrics as method_cal_metrics # import MABAC as method_MABAC from lib.Rank.mabac import method_MABAC def get_path(topo_path): with open(topo_path, 'r') as f: Topo = json.load(f) f.close() start = Topo['start'] end = Topo['goal'][0]['host'] nodes = Topo['hosts'] edges = Topo['edges'] pathsnum = Topo['nums'] newnodes = [] newedges = [] tempedges={} for node in nodes: newnodes.append(node['host_name']) for edge in edges: path = [edge['source'], edge['target']] newedges.append(path) return start, end, newnodes, newedges,pathsnum def get_path1(start, end, nodes, edges): edgesDict = {} Numedges = {} edgesNum = {} for edge in edges: if edgesDict.get(edge[0]) == None: edgesDict[edge[0]] = [edge[1]] else: edgesDict[edge[0]].append(edge[1]) edgesDict[end] = [] myPath = method_get_all_path.GetPath(nodes, edgesDict, start, end) Path = myPath.getPath() # 存放全部攻击路径 edgePath = myPath.tran(Path) return edgePath def all_paths_conversion(all_paths, topo_path, start): path_id = [] # 每条边用编号代替 path_node = [] # 记录攻击路径上的点 with open(topo_path, 'r') as f: Topo = json.load(f) f.close() edge_ID_dict = {} for edge in Topo['edges']: dict = {edge['source'] + ',' + edge['target']: edge['edge_name']} edge_ID_dict.update(dict) # print(edge_ID_dict) for path in all_paths: temp_id = [] temp_path = [start] for source, target in path: temp_id.append(edge_ID_dict[source + ',' + target]) temp_path.append(target) path_id.append(temp_id) path_node.append(temp_path) return path_id, path_node def get_rank(m1, m2, m3, m4, weight, visit, edgesnum, topo_path, data_path, out,flag): # # 从右往左pop # for i in range(edgesnum - 1, -1, -1): # if visit[i] == 1: # m1.pop(i) # m2.pop(i) # m3.pop(i) # m4.pop(i) # # m10.pop(i) B_or_C = ['B', 'C', 'C', 'C', 'B', 'B', 'B', 'B', 'C', 'B'] # B表示Benefit,C表示Cost型 with open(topo_path, 'r') as f: edges = json.load(f)['edges'] f.close() m5_TFN = [] m6_TFN = [] m7_TFN = [] m8 = [] m9_TFN = [] for edge in edges: if edge['edge_name'] == 'E1': m5_TFN.append((0,0,0)) m6_TFN.append((0,0,0)) m7_TFN.append((0,0,0)) m8.append(0) m9_TFN.append((0,0,0)) continue # print(edge['val']) # 机密性C(b) 模糊值 m5_TFN.append(edge['val']['C']) # 完整性I(b) 模糊值 m6_TFN.append(edge['val']['I']) # 可用性A(b) 模糊值 m7_TFN.append(edge['val']['A']) # exploit(b) m8.append(edge['val']['ES']) # 设备影响值(b)模糊值 m9_TFN.append(edge['val']['TFN']) # print(edge['edge_name'], edge['val']['C'], len(m5_TFN)) cias=[copy.deepcopy(m5_TFN[1:]),copy.deepcopy(m6_TFN[1:]),copy.deepcopy(m7_TFN[1:]),copy.deepcopy(m9_TFN[1:])] m5 = method_MABAC.TFN_exact_value(m5_TFN) m6 = method_MABAC.TFN_exact_value(m6_TFN) m7 = method_MABAC.TFN_exact_value(m7_TFN) m9 = method_MABAC.TFN_exact_value(m9_TFN) for i in range(edgesnum - 1, -1, -1): if visit[i] == 1: m1.pop(i) m2.pop(i) m3.pop(i) m4.pop(i) m5.pop(i) m6.pop(i) m7.pop(i) m8.pop(i) m9.pop(i) metrics_10 = [m1] + [m2] + [m3] + [m4] + [m5] + [m6] + [m7] + [m8] + [m9] all_metrics_final = [] g = [] A_cias=[];n_cias=[] for i in range(len(metrics_10)): temp = metrics_10[i] if B_or_C[i] == 'B': # benefit n_m = method_MABAC.benefit_normalize(copy.deepcopy(temp)) else: # cost n_m = method_MABAC.cost_normalize(copy.deepcopy(temp)) A_m = method_MABAC.B_to_A_weight(copy.deepcopy(n_m), weight[i]) if i in [4,5,6,8]: n_cias.append(n_m) A_cias.append(A_m) g_i = method_MABAC.get_g(copy.deepcopy(A_m), visit) final_m = method_MABAC.refresh_A_with_g(copy.deepcopy(A_m), g_i) all_metrics_final.append(final_m) if(flag): out={} out.update({'CIA_Service': [cias,n_cias,A_cias]}) with open("result/tmp/CIA_Service.json", 'w') as f: json.dump(out, f) f.close() # print(all_metrics_final) data = list(zip(*all_metrics_final)) # 保存数据 with open(data_path, 'w', newline='') as csvfile: writer = csv.writer(csvfile) writer.writerows(data) temp_sum = [] temp_sum_exp = [] temp_c3 = [] for i in range(len(data)): temp_sum.append(sum(data[i])) temp_sum_exp.append(sum(data[i]) - data[i][2]) temp_c3.append(data[i][2]) edge_scores = [-100] * edgesnum visit_num = 0 # print(len(data), len(visit)) for i in range(len(visit)): # print(i-visit_num) if visit[i] == 1: visit_num += 1 continue else: edge_scores[i] = sum(data[i - visit_num]) edgeID_score = [] for i in range(len(edge_scores)): #edgeID_score.append(['E' + str(i + 1), edge_scores[i]]) edgeID_score.append(['E' + str(i + 1), edge_scores[i], help[i]]) ranking=Single_round_sorting_results(edgeID_score,len(edgeID_score)) best_score = max(edge_scores) rank_1_edge = edge_scores.index(best_score) # rank1_edge这个是索引,加入索引为3,说明最重要的边是E4 return rank_1_edge,ranking def refresh_path(best_edge, all_paths, topo_path): # 删除all_paths中包含best_edge的边 with open(topo_path, 'r') as f: Topo = json.load(f) f.close() edge_ID_dict = {} for edge in Topo['edges']: dict = {edge['source'] + ',' + edge['target']: edge['edge_name']} edge_ID_dict.update(dict) for key in edge_ID_dict.keys(): if edge_ID_dict[key] == best_edge: # print(key) delete_edge = (key.split(',')[0], key.split(',')[1]) # print(delete_edge) for i in range(len(all_paths) - 1, -1, -1): if delete_edge in all_paths[i]: all_paths.pop(i) #print(edge_ID_dict) return all_paths def get_pathnum(topo): with open(topo_path, 'r') as f: topo = json.load(f) edges = {} for edge in topo["edges"]: key = (edge["source"], edge["target"]) edges[key] = edge pathsnum = caculatepathsnum(edges) return pathsnum def Single_round_sorting_results(edgeID_score, edgesnum): edgeID_score.sort(key=lambda x: -x[1]) # edgeID_score.sort(key=lambda x: (-x[1], x[2])) ranking = [0] * edgesnum result=[] for i, res in enumerate(edgeID_score): result.append(res) ranking[int(res[0][1:]) - 1] = i + 1 # print('ranking=', ranking) out.update({'ranking': result}) return ranking if __name__ == '__main__': topo_path = sys.argv[1]; weight_path = sys.argv[2]; data_path = sys.argv[3]; output_path = sys.argv[4]; metrics_path = sys.argv[5] with open(weight_path, 'r') as f: weight = json.load(f) f.close() weight = weight['weight'] with open('input/MainInput.json', 'r') as f: input = json.loads(f.read()) f.close() method=input['rrisk_cal']['method'] start, end, nodes, edges,nums= get_path(topo_path) all_paths = get_path1(start, end, nodes, edges) # all_paths 记录了攻击路径 cutset = []; visit = [0] * nums[2]; visit[0] = 1; best_edge = 0;help = [0] * nums[2];help[0] = 1 out = {};tmp={} rankings=[] with open(metrics_path, 'r') as f: metrics = list(csv.reader(f)) m1 = [float(row[1]) for row in metrics[1:]] m2 = [float(row[2]) for row in metrics[1:]] m3 = [float(row[3]) for row in metrics[1:]] m4 = [float(row[4]) for row in metrics[1:]] # m10 = [float(row[5]) for row in metrics[1:]] f.close() best_edge_index,ranking = get_rank(m1, m2, m3, m4, weight, visit, nums[2], topo_path, data_path, out,True) best_edge = 'E' + str(best_edge_index + 1) cutset.append(best_edge) rankings.append(ranking[1:]) visit[best_edge_index] = 1 help[best_edge_index] = max(help) + 1 # 更新攻击路径 all_paths = refresh_path(best_edge, copy.deepcopy(all_paths), topo_path) # print('best_edge', best_edge) # print('===========================') with open(output_path, 'w') as f: json.dump(out, f) f.close() if(method=='d'): while (len(all_paths) > 0): path_id, path_node = all_paths_conversion(all_paths, topo_path, start) m1 = method_cal_metrics.cal_AttackPath_Count(path_id,nums[2]) m2 = method_cal_metrics.cal_Shortest_AP_Length(path_id,nums[2]) m3 = method_cal_metrics.cal_AttackPath_Length_Average(path_id,nums[2]) m4 = method_cal_metrics.cal_shortest_distance_to_S0(path_id,nums[2]) best_edge_index,ranking = get_rank(m1, m2, m3, m4, weight, visit, nums[2], topo_path, data_path, out,False) best_edge = 'E' + str(best_edge_index + 1) cutset.append(best_edge) rankings.append(ranking[1:]) visit[best_edge_index] = 1 help[best_edge_index] = max(help) + 1 # 更新攻击路径 all_paths = refresh_path(best_edge, copy.deepcopy(all_paths), topo_path) # print('best_edge', best_edge) # print('===========================') tmp.update({'ranking':rankings}) tmp.update({'delete_edges':cutset}) with open("result/tmp/ranking.json", 'w') as f: json.dump(tmp, f) f.close() 如何在别的程序中调用这个排序算法程序,需要传入的参数以及程序输出的排序结果在哪里
最新发布
08-28
这段代码实现了一个基于 **MABAC(Multi-Attributive Border Approximation area Comparison)** 的多准则决策排序算法,用于对网络攻击路径中的边(`edges`)进行优先级排序。它会根据输入的拓扑结构、权重配置、指标数据等,计算出每条边的重要性排序,并将结果输出为 JSON 文件。 --- ## 🧪 如何在别的程序中调用这个排序算法程序? ### ✅ 调用方式 该程序是一个可执行脚本,支持从命令行调用。因此,你可以在其他 Python 程序中使用 `subprocess` 模块来调用它。 #### 示例调用代码: ```python import subprocess # 定义参数路径 topo_path = "input/topology.json" weight_path = "input/weights.json" data_path = "output/metrics.csv" output_path = "output/ranking.json" metrics_path = "input/metrics.csv" # 调用脚本 subprocess.run([ "python", "path/to/your_script.py", topo_path, weight_path, data_path, output_path, metrics_path ]) ``` --- ## 📥 需要传入的参数(命令行参数) | 参数编号 | 参数名 | 含义说明 | |----------|----------------|----------| | 1 | `topo_path` | 拓扑结构文件路径(JSON 格式),包含网络节点和边信息 | | 2 | `weight_path` | 权重文件路径(JSON 格式),包含各指标的权重值 | | 3 | `data_path` | 输出路径,用于保存中间计算的指标数据(CSV 格式) | | 4 | `output_path` | 输出路径,用于保存最终排序结果(JSON 格式) | | 5 | `metrics_path` | 输入指标数据路径(CSV 格式),包含各项评估指标值 | --- ## 📤 程序输出的排序结果在哪里? ### ✅ 输出文件路径: - 排序结果写入由第 4 个参数指定的路径(`output_path`): - 例如:`"output/ranking.json"` ### 📄 输出格式(JSON): ```json { "ranking": [ [1, 2, 3, 4, 5, 6, 7, 8, 9], // 第一次排序结果 [2, 1, 3, 4, 5, 6, 7, 8, 9], // 第二次删除某边后重新排序 ... ], "delete_edges": ["E1", "E3", "E5"] // 每轮删除的最重要边 } ``` ### 📁 输出内容说明: - `"ranking"`: 每次删除边后的边排序结果,是一个二维数组,每一行对应一次排序。 - `"delete_edges"`: 每次删除的最重要边(优先级最高的边) --- ## 📁 中间文件说明 - `data_path`:用于保存中间处理的指标数据(CSV 格式) - `metrics_path`:输入的指标数据(CSV 格式) - `result/tmp/CIA_Service.json`:调试用的 CIA 指标中间输出文件(可选) --- ## ✅ 示例输入文件格式 ### `topology.json` 示例: ```json { "start": "S0", "goal": [{"host": "H3"}], "hosts": [ {"host_name": "S0"}, {"host_name": "H1"}, {"host_name": "H2"}, {"host_name": "H3"} ], "edges": [ {"source": "S0", "target": "H1", "edge_name": "E1", "val": {"C": [1,1,1], "I": [2,3,4], "A": [0.5,1,1.5], "ES": 3, "TFN": [1,2,3]}}, ... ], "nums": [4, 5, 9] } ``` ### `weights.json` 示例: ```json { "weight": [0.3, 0.2, 0.1, 0.4, 0.2, 0.1, 0.1, 0.3, 0.2] } ``` ### `metrics.csv` 示例: ```csv ID,M1,M2,M3,M4,M5,M6,M7,M8,M9 E1,0.5,0.7,0.2,0.8,0.6,0.4,0.3,3,0.5 E2,0.6,0.6,0.3,0.7,0.5,0.5,0.4,2,0.6 ... ``` --- ##
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值