实现从武汉出发,进行34个省会的遍历,最后回到武汉,要求输出遍历路径和最后总里程

以下为贪心算法程序,回溯算法在最后,可是这两个算法都有缺点,特别是回溯算法,谁能帮我找出一个更好的算法啊。

/*********************************************************/

main.cpp

#include "setting.h"

 

int main (void){

      

       int** dist;

       char ch[10];

       dist= get ();                         //得到文件数据

      

       printf("请输入起点城市:");

       scanf("%s",ch);

       getdist(ch,dist);                    //得到遍历数据    

       return 0;

      

}

 

 

/*****************************************************************************/

operation.cpp  // 贪心算法

#include  "setting.h"

 

char city[40][10];

int cityNum = 0;

FILE* file = fopen ("distance.txt","r");

StringReader sr ;

char buf[20];

 

 

int getLine (FILE* file,char* str){

       static int c;

       int count = 0;

       int ifeof = 0;

       if (c == EOF){

              return -1;

       }

       while ((c=fgetc(file)) != EOF){

              if (c == '/n'){

                     str[count] = '/0';

                     return 1;

              }

             

              str[count++] = c;

       }

       str[count] = '/0';

       return 1;

}

 

int getToken (StringReader* sr,char* buf){

       int in = 0;

       char ch;

       int c = sr->offset;

       int k = 0;

       if (c == sr->len){

              return -1;

       }

    for (;c<sr->len;++c,sr->offset++){

                  ch=sr->str[c];

                     if (ch == '/t'||ch == ' '){

                            if (in == 1){

                                   buf[k] = '/0';

                                   return 1;

                            }           

                     }

                     else {

                            if (in == 0){

                                   in = 1;

                            }

                            buf[k++] = ch;

                     }

       }

       buf[k] = '/0';

       return 1;

}

 

void initStringReader (StringReader* sr){

       sr->len = strlen (sr->str);

       sr->offset = 0;

}

 

char* getCityName (int code){

       return city[code];

}

 

int getCityCode (char* cityName){

       for (int i = 0;i<cityNum;++i){

              if (strcmp(cityName,city[i]) == 0)

                     return i;

       }

       return -1;

}

 

void getData (int** dist){

       while ((getLine (file,sr.str))!=-1){

              initStringReader (&sr);

              getToken (&sr,buf);

              int code = getCityCode (buf);

              for (int i=0;i<cityNum;++i){

                     getToken(&sr,buf);

                     dist[i][code] = atoi(buf);

              }

       }

}

 

int** get(){

       getLine (file,sr.str);

       initStringReader (&sr);

       int i;

       int count = 0;

       while ((i = getToken (&sr,buf))!=-1){

              cityNum ++;

              int len = strlen (buf);

              for (int a=0;a<len;++a){

                     city[count][a] = buf[a];

              }

              city[count][a] = '/0';

              ++count;

       }

       int** dist =(int** )malloc ((sizeof (int*))*cityNum);

       for (i=0;i<cityNum;++i){

              dist[i] = (int*)malloc ((sizeof (int))*cityNum);

       }

       getData (dist);

 

       return dist;

      

}

/*****************************************************************************/

getdist.cpp                   

 

#include "setting.h"

 

void getdist(char ch[],int** dist)

{

       int s[M],dingwei[M];

    int n,number,u;

    int i,j,k,min,distance=0;

      

       getData (dist);

      

       system("cls");

 

              n=getCityCode(ch);

             

   

       u=1;

   number=n;

 

for(i=0;i<M;i++)

s[i]=0;

       for(j=0;j<M;j++)

       {

              for(i=0;i<M;i++)

                {

       

                     dingwei[i]=dist[number][i];

                }

                s[number]=1;       

      printf("%s->",getCityName(number));

                                                                            

                     min=MAX;                                                                                 

                     for(k=0;k<M;k++)                            

                     {

                       if(s[k]==0&&min>dingwei[k])  

                       {

                            min=dingwei[k];

                            number=k;

                       }

                       if(u==M)

                              min=dingwei[n];

                      

                     }

                     u++;

                                                

                    

                     distance+=min;

                    

                      

                    

       }

      

        printf("%s",getCityName(n));

        printf("/n距离为:%d/n",distance);

 

}/*****************************************************************************/

setting.h   // 一些头文件和函数接口

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define M 34

#define MAX 100000

typedef struct {

       char  str[1000];

       int len;

       int offset;

} StringReader;

 

int** get ();                     

void getdist(char ch[],int** dist);

int getCityCode (char* cityName);

char* getCityName (int code);

void  getData(int**dist);

/*****************************************************************************/

以下为 回溯算法

/********************************************************************************
#include "setting.h"

int x[34];
int v;
int bestV;
int bestX[34];
int n = 34;

int** dist;


void backtrack (int t,int** dist) {
 void swap(int a[], int i, int j);
  if (t > n - 1) {
   v += dist[0][x[n - 1]];
   if (v < bestV) {
    bestV = v;
    for (int i = 0; i < n; i++)
     bestX[i] = x[i];
   }
   printf("%d/n",v);
   v -= dist[0][x[n - 1]];
   return;
  }
 
 for (int i = t; i < n; i++) {
  
  swap(x, i, t);
  v += dist[x[t - 1]][x[t]];
  // 剪枝函数
  if (v < bestV)
   backtrack(t + 1,dist);
  v -= dist[x[t - 1]][x[t]];
  swap(x, i, t);
 }
}

void swap(int a[], int i, int j) {
 int temp = a[i];
 a[i] = a[j];
 a[j] = temp;
}


void getdist(int** dist){
 int i;
 for ( i = 0;i<n;++i){
  x[i] = i;
  bestX[i] = i;
 }
 v = 0;
 bestV = 99999;
  backtrack (1,dist);
 printf("%d/n",bestV);
 for (i = 0; i < n; i++)
  printf("%d/n",bestX[i]);

}

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
退火算法是一种启发式优化算法,常用于解决组合优化问题。它模拟了金属退火的过程,通过在解空间中随机搜索并逐渐减小搜索范围,最终找到全局最优解。 要使用退火算法遍历全国省会,可以将省会作为解空间中的候选解。首先,需要定义一个评估函数来衡量每个候选解的优劣。在这个问题中,可以将评估函数定义为遍历所有省会距离,即从一个省会到下一个省会的距离之和。 接下来,需要初始化一个当前解,可以是一个随机的省会序列。然后,通过不断迭代的方式,对当前解进行改变和评估,以寻找更优的解。在每次迭代中,可以随机选择两个省会进行交换,然后计算新解的评估值。如果新解更优,则接受新解;否则,根据一定的概率接受新解。这个概率与新解的优劣程度以及当前温度有关。随着迭代的进行,温度逐渐降低,接受较差解的概率也逐渐减小,从而使算法趋向于收敛到全局最优解。 下面是一个使用退火算法遍历全国省会的示例代码: ```python import random import math # 省会列表 provinces = ['北京', '天津', '上海', '重庆', '河北', '山西', '辽宁', '吉林', '黑龙江', '江苏', '浙江', '安徽', '福建', '江西', '山东', '河南', '湖北', '湖南', '广东', '海南', '四川', '贵州', '云南', '陕西', '甘肃', '青海', '台湾', '内蒙古', '广西', '西藏', '宁夏', '新疆', '香港', '澳门'] # 计算两个省会之间的距离 def distance(city1, city2): # 这里可以根据实际情况定义距离计算方法 return random.randint(1, 100) # 计算解的评估值 def evaluate(solution): total_distance = 0 for i in range(len(solution) - 1): total_distance += distance(solution[i], solution[i+1]) return total_distance # 初始化当前解 current_solution = provinces.copy() random.shuffle(current_solution) # 初始化温度和迭代次数 temperature = 100 iterations = 1000 # 退火算法主循环 for i in range(iterations): # 随机选择两个省会进行交换 index1 = random.randint(0, len(provinces) - 1) index2 = random.randint(0, len(provinces) - 1) current_solution[index1], current_solution[index2] = current_solution[index2], current_solution[index1] # 计算新解的评估值 new_solution = current_solution.copy() new_distance = evaluate(new_solution) # 判断是否接受新解 if new_distance < evaluate(current_solution): current_solution = new_solution else: probability = math.exp((evaluate(current_solution) - new_distance) / temperature) if random.random() < probability: current_solution = new_solution # 降低温度 temperature *= 0.99 # 输出最终的解 print("最短路径:", current_solution) print("距离:", evaluate(current_solution)) ``` 这段代码使用了随机交换省会的方式进行搜索,并通过降低温度的方式控制搜索范围。最终输出的最短路径距离即为遍历全国省会的结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值