floyd算法

源码

#define _CRT_SECURE_NO_WARNINGS //处理scanf报错问题
#include <stdio.h>
#include <windows.h>

#define DEBUG_SWITCH 1
#if DEBUG_SWITCH
#define DEBUG_INFO(format, ...) printf("LINE: %d: "format"\n", __LINE__, ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...) 
#endif

#define TRUE  1
#define FALSE 0

#define UINT64_MAX (0XFFFFFFFFFFFFFFFF)
#define UINT32_MAX (0XFFFFFFFF)
#define UINT16_MAX (0XFFFF)
#define UINT8_MAX  (0XFF)

typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned long int uint32_t;
typedef unsigned long long int uint64_t;

#define GET_ARR_SIZE(arr,type) (sizeof(arr)/sizeof(type))
#define GET_ARR_2D_DATA(ARR, X, Y, X_MAX, Y_MAX) ARR[((((X) < (X_MAX) ? (X) : (X_MAX))) * (Y_MAX)) + ((Y) < (Y_MAX) ? (Y) : (Y_MAX))]
#define INF (UINT64_MAX >> 2)

typedef struct intrm_struct
{
	uint64_t consume;
	uint64_t pre_node;
}intrm_def;

typedef struct floyd_struct
{
	intrm_def *matrix_addr;
	uint64_t node_num;
	uint64_t (*node_index)(uint64_t node_index);
	uint64_t (*get_consume)(struct floyd_struct *data, uint64_t start_node, uint64_t end_node);
	void (*callback_path)(struct floyd_struct *data);
	void (*callback_path_output)(struct floyd_struct *data, uint64_t start_node, uint64_t end_node, uint64_t *path_node, uint64_t *path_node_num);
}floyd_def;

void floyd_path(floyd_def *data)
{
	for (uint64_t k = 1; k <= data->node_num; ++k)
	{
		for (uint64_t i = 1; i <= data->node_num; ++i)
		{
			for (uint64_t j = 1; j <= data->node_num; ++j)
			{
				if (GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(j), data->node_num, data->node_num).consume >
					(GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(k), data->node_num, data->node_num).consume 
						+ GET_ARR_2D_DATA(data->matrix_addr, data->node_index(k), data->node_index(j), data->node_num, data->node_num).consume))
				{
					GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(j), data->node_num, data->node_num).consume = 
						GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(k), data->node_num, data->node_num).consume 
						+ GET_ARR_2D_DATA(data->matrix_addr, data->node_index(k), data->node_index(j), data->node_num, data->node_num).consume;
					GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(j), data->node_num, data->node_num).pre_node = k;
				}
			}
		}
	}
}

void floyd_path_output(floyd_def *data, uint64_t start_node, uint64_t end_node, uint64_t *path_node, uint64_t *path_node_num)
{
	uint64_t k = GET_ARR_2D_DATA(data->matrix_addr, data->node_index(start_node), data->node_index(end_node), data->node_num, data->node_num).pre_node;
	path_node[(*path_node_num)++] = end_node;
	while (k != start_node)
	{
		path_node[(*path_node_num)++] = k;
		k = GET_ARR_2D_DATA(data->matrix_addr, data->node_index(start_node), data->node_index(k), data->node_num, data->node_num).pre_node;
	}
	path_node[(*path_node_num)++] = start_node;
}

uint64_t node_index(uint64_t node_index)
{
	return (node_index - 1);
}

uint64_t get_consume(floyd_def *data, uint64_t start_node, uint64_t end_node)
{
	return (GET_ARR_2D_DATA(data->matrix_addr, data->node_index(start_node), data->node_index(end_node), data->node_num, data->node_num).consume);
}

#define NODE_NUM 6
#define EDGE_NUM 9
#define MATRIX_SIZE (NODE_NUM * NODE_NUM)

int main()
{
	static intrm_def matrix[MATRIX_SIZE];

	uint64_t path_node_num = 0;
	uint64_t path_node[NODE_NUM] = { 0 };
	floyd_def floyd_data;
	floyd_data.matrix_addr = matrix;
	floyd_data.node_num = NODE_NUM;
	floyd_data.callback_path = floyd_path;
	floyd_data.callback_path_output = floyd_path_output;
	floyd_data.node_index = node_index;
	floyd_data.get_consume = get_consume;

	for (uint64_t x = 0; x < NODE_NUM; x++)
	{
		for (uint64_t y = 0; y < NODE_NUM; y++)
		{
				GET_ARR_2D_DATA(matrix, x, y, NODE_NUM, NODE_NUM).consume = (x == y) ? 0 : INF;
				GET_ARR_2D_DATA(matrix, x, y, NODE_NUM, NODE_NUM).pre_node = 1 + x;
		}
	}
	
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(1), floyd_data.node_index(2), NODE_NUM, NODE_NUM).consume = 1;
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(1), floyd_data.node_index(3), NODE_NUM, NODE_NUM).consume = 12;
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(2), floyd_data.node_index(3), NODE_NUM, NODE_NUM).consume = 9;
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(2), floyd_data.node_index(4), NODE_NUM, NODE_NUM).consume = 3;
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(3), floyd_data.node_index(5), NODE_NUM, NODE_NUM).consume = 5;
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(4), floyd_data.node_index(3), NODE_NUM, NODE_NUM).consume = 4;
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(4), floyd_data.node_index(5), NODE_NUM, NODE_NUM).consume = 13;
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(4), floyd_data.node_index(6), NODE_NUM, NODE_NUM).consume = 15;
	GET_ARR_2D_DATA(matrix, floyd_data.node_index(5), floyd_data.node_index(6), NODE_NUM, NODE_NUM).consume = 4;

	for (uint64_t x = 0; x < NODE_NUM; x++)
	{
		for (uint64_t y = 0; y < NODE_NUM; y++)
		{
			printf("[%2lld] ", (GET_ARR_2D_DATA(matrix, x, y, NODE_NUM, NODE_NUM).consume >= INF) ? UINT64_MAX : GET_ARR_2D_DATA(matrix, x, y, NODE_NUM, NODE_NUM).consume);
		}
		printf("\r\n");
	}
	printf("---------------------------\r\n");

	floyd_data.callback_path(&floyd_data);

	for (uint64_t x = 0; x < NODE_NUM; x++)
	{
		for (uint64_t y = 0; y < NODE_NUM; y++)
		{
			printf("[%2lld] ", (GET_ARR_2D_DATA(matrix, x, y, NODE_NUM, NODE_NUM).consume >= INF) ? UINT64_MAX : GET_ARR_2D_DATA(matrix, x, y, NODE_NUM, NODE_NUM).consume);
		}
		printf("\r\n");
	}
	printf("---------------------------\r\n");

	for (uint64_t x = 0; x < NODE_NUM; x++)
	{
		for (uint64_t y = 0; y < NODE_NUM; y++)
		{
			printf("[%2lld] ", (GET_ARR_2D_DATA(matrix, x, y, NODE_NUM, NODE_NUM).pre_node >= INF) ? UINT64_MAX : GET_ARR_2D_DATA(matrix, x, y, NODE_NUM, NODE_NUM).pre_node);
		}
		printf("\r\n");
	}
	printf("---------------------------\r\n");

	for (uint64_t i = 1; i <= NODE_NUM; ++i)
	{
		path_node_num = 0;
		floyd_path_output(&floyd_data, 1, i, path_node, &path_node_num);
		printf("%lld -> %lld consume:%lld  path:",(uint64_t)1, i, floyd_data.get_consume(&floyd_data, 1, i));
		for (uint64_t j = path_node_num; j > 0; j--)
		{
			printf("[%d]", path_node[j - 1]);
		}
		printf("\r\n");
	}
}

使用

句柄说明

typedef struct intrm_struct
{
	uint64_t consume;  //经过该节点的消耗/距离
	uint64_t pre_node; //上一节点
}intrm_def; //中转点(邻接矩阵节点)

typedef struct floyd_struct
{
	intrm_def *matrix_addr; //邻接矩阵
	uint64_t node_num;		//节点数量
	uint64_t (*node_index)(uint64_t node_index);//节点和矩阵下标索引转换接口
	uint64_t (*get_consume)(struct floyd_struct *data, uint64_t start_node, uint64_t end_node);//获取从某节点到某节点的消耗/距离
	void (*callback_path)(struct floyd_struct *data);//floyd算法
	void (*callback_path_output)(struct floyd_struct *data, uint64_t start_node, uint64_t end_node, uint64_t *path_node, uint64_t *path_node_num);//获取从某节点到某节点的路径,倒序
}floyd_def; //floyd句柄

定义floyd句柄并初始化


void floyd_path(floyd_def *data)
{
	for (uint64_t k = 1; k <= data->node_num; ++k)
	{
		for (uint64_t i = 1; i <= data->node_num; ++i)
		{
			for (uint64_t j = 1; j <= data->node_num; ++j)
			{
				if (GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(j), data->node_num, data->node_num).consume >
					(GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(k), data->node_num, data->node_num).consume 
						+ GET_ARR_2D_DATA(data->matrix_addr, data->node_index(k), data->node_index(j), data->node_num, data->node_num).consume))
				{
					GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(j), data->node_num, data->node_num).consume = 
						GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(k), data->node_num, data->node_num).consume 
						+ GET_ARR_2D_DATA(data->matrix_addr, data->node_index(k), data->node_index(j), data->node_num, data->node_num).consume;
					GET_ARR_2D_DATA(data->matrix_addr, data->node_index(i), data->node_index(j), data->node_num, data->node_num).pre_node = k;
				}
			}
		}
	}
}

void floyd_path_output(floyd_def *data, uint64_t start_node, uint64_t end_node, uint64_t *path_node, uint64_t *path_node_num)
{
	uint64_t k = GET_ARR_2D_DATA(data->matrix_addr, data->node_index(start_node), data->node_index(end_node), data->node_num, data->node_num).pre_node;
	path_node[(*path_node_num)++] = end_node;
	while (k != start_node)
	{
		path_node[(*path_node_num)++] = k;
		k = GET_ARR_2D_DATA(data->matrix_addr, data->node_index(start_node), data->node_index(k), data->node_num, data->node_num).pre_node;
	}
	path_node[(*path_node_num)++] = start_node;
}

uint64_t node_index(uint64_t node_index)
{
	return (node_index - 1);
}

uint64_t get_consume(floyd_def *data, uint64_t start_node, uint64_t end_node)
{
	return (GET_ARR_2D_DATA(data->matrix_addr, data->node_index(start_node), data->node_index(end_node), data->node_num, data->node_num).consume);
}

int main()
{
#define NODE_NUM 6
#define EDGE_NUM 9
#define MATRIX_SIZE (NODE_NUM * NODE_NUM)
	floyd_def floyd_data;
	floyd_data.matrix_addr = matrix;
	floyd_data.node_num = NODE_NUM;
	floyd_data.callback_path = floyd_path;
	floyd_data.callback_path_output = floyd_path_output;
	floyd_data.node_index = node_index;
	floyd_data.get_consume = get_consume;
}

初始化邻接矩阵数据

在这里插入图片描述

GET_ARR_2D_DATA(matrix, floyd_data.node_index(1), floyd_data.node_index(2), NODE_NUM, NODE_NUM).consume = 1;
GET_ARR_2D_DATA(matrix, floyd_data.node_index(1), floyd_data.node_index(3), NODE_NUM, NODE_NUM).consume = 12;
GET_ARR_2D_DATA(matrix, floyd_data.node_index(2), floyd_data.node_index(3), NODE_NUM, NODE_NUM).consume = 9;
GET_ARR_2D_DATA(matrix, floyd_data.node_index(2), floyd_data.node_index(4), NODE_NUM, NODE_NUM).consume = 3;
GET_ARR_2D_DATA(matrix, floyd_data.node_index(3), floyd_data.node_index(5), NODE_NUM, NODE_NUM).consume = 5;
GET_ARR_2D_DATA(matrix, floyd_data.node_index(4), floyd_data.node_index(3), NODE_NUM, NODE_NUM).consume = 4;
GET_ARR_2D_DATA(matrix, floyd_data.node_index(4), floyd_data.node_index(5), NODE_NUM, NODE_NUM).consume = 13;
GET_ARR_2D_DATA(matrix, floyd_data.node_index(4), floyd_data.node_index(6), NODE_NUM, NODE_NUM).consume = 15;
GET_ARR_2D_DATA(matrix, floyd_data.node_index(5), floyd_data.node_index(6), NODE_NUM, NODE_NUM).consume = 4;

调用floyd

floyd_data.callback_path(&floyd_data);

输出

for (uint64_t i = 1; i <= NODE_NUM; ++i)
{
	path_node_num = 0;
	floyd_path_output(&floyd_data, 1, i, path_node, &path_node_num);
	printf("%lld -> %lld consume:%lld  path:",(uint64_t)1, i, floyd_data.get_consume(&floyd_data, 1, i));
	for (uint64_t j = path_node_num; j > 0; j--)
	{
		printf("[%d]", path_node[j - 1]);
	}
	printf("\r\n");
}

在这里插入图片描述

参考

参考

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值