C语言使用动态规划法解决旅行商问题(tsp问题)

#include <stdio.h>
#include <stdlib.h>

#define INF 65535             // 代价矩阵中的无限这里用一个较大的数表示   
#define N 20

int cost[N][N] = { 0 };
int begin = 0;                // 全局变量存储起始点

// removeData函数返回在数组path中去除一个元素elem后形成的新数组newPath
int *removeData(int path[], int n, int elem)
{
    int *newPath = NULL;
    if (n > 1)
        newPath = (int *)malloc(sizeof(int) * (n - 1));

    int j = 0;
    for (int i = 0; i < n; i++)
    {
        if (path[i] != elem)
            newPath[j++] = path[i];
    }
    return newPath;
}

int travel(int start, int path[], int n)
{
    if (n == 0)                // 递归出口,如果n == 0说明path数组中已经无元素,直接返回从出发点start回到起始点begin的路径长度
        return cost[start][begin];

    int min = INF, elem = 0, len = 0;

    for (int i = 0; i < n; i++)
    {
        elem = path[i];
        len = cost[start][elem] + travel(elem, removeData(path, n, elem), n - 1) ;

        // len = 从出发点start到当前path[i]的路径长度 + 以path[i]为出发点经过去除了path[i]元素的path数组,最后返回出发点begin的路径长度
        if (len < min)
        {
            min = len;        // 选出其中最小的那个作为最后的结果
        }
    }
    return min;
}

int tsp_dynamic(int n)
{
    int *firstPath = (int *)malloc(sizeof(int) * n);
    for (int i = 0; i < n; i++)
        firstPath[i] = i;
    int *path = removeData(firstPath, n, begin);        // 使用的path数组应该是不包含一开始的出发点begin的
    free(firstPath);

    return travel(begin, path, n - 1);
}



/* 以下是贪心法解决tsp问题 */

int visited[N] = { 0 };

int tsp_greedy(int n)
{
    int min = INF, minPath = 0, sum = 0;
    visited[begin] = 1;

    int k = begin;
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (cost[k][j] < min && visited[j] == 0)
            {
                min = cost[k][j];
                minPath = j;
            }
        }
        sum = sum + min;

        k = minPath;
        min = INF;
        visited[k] = 1;
    }
    sum = sum + cost[k][begin];
    return sum;
}


/* 主函数 */
int main()
{
    int n;
    scanf("%d", &n);

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            scanf("%d", &cost[i][j]);          // 输入代价矩阵
    printf("result = %d", tsp_dynamic(n));     // 输出结果

    return 0;
}

本人水平一般,如有问题欢迎指正

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值