回溯发实验

#include < iostream >
#include
< cmath >
#include 
< ctime >
#include
< vector >
#include
< stack >
#include
< iomanip >
using   namespace  std;
#define  INF 0x7fffffff

struct  point
{
    
int  x,y;
}p[
40 ];

int  n;              // TSP点数
double  d[ 40 ][ 40 ];   // 点的距离
double  Min;         // 最优解
double  cur;         // 当前值
int  path[ 40 ];    // 结果路径
int  a[ 40 ];          // 过程路径

//
// 随机生成TSP的点并求出之间的距离

void  init()
{
    srand(time(NULL));
    memset(d,
0 , sizeof (d));
    
int  i,j;
    
int  x,y;

    
for (i = 1 ;i <= n;i ++ )
    {
        
for (j = 1 ;j <= n;j ++ )
            d[i][j] 
=  INF;
        a[i] 
=  i;
    }

    Min 
=  INF;
    cur 
=   0.0 ;

    i 
=   1 ;
    
while ( 1 )
    {
        
if ( i  ==  n + 1  )  break ;
        x 
=  rand() % 500 ;
        y 
=  rand() % 500 ;
        
int  flag  =   0 ;

        
for ( j  =   1  ; j  <  i ; j ++ )
        {
            
if ( x  ==  p[j].x  ||  y  ==  p[j].y )
            {
                flag 
=   1 ;
                
break ;
            }
        }
        
if ( flag  ==   0  )
        {
            p[i].x 
=  x;
            p[i].y 
=  y;
            i
++ ;
        }
    }

    
for ( i  =   1 ; i  <=  n;  i ++  )
    {
        
for (j  =   1 ; j  <=  n; j ++  )
        {
            d[i][j] 
=  sqrt( (p[i].x - p[j].x) * (p[i].x - p[j].x)  +  (p[i].y - p[j].y) * (p[i].y - p[j].y) );
        }
    }
        
}

/// /
// 回溯法搜索TSP路径和最优值

void  dfs( int  i)
{
    
if ( i  ==  n )   // 找到最优路径
    {
        
if (  d[a[n - 1 ]][a[n]]  !=  INT_MAX  &&  d[a[n]][ 1 !=  INT_MAX  &&
            ( cur 
+  d[a[n - 1 ]][a[n]]  + d[a[n]][ 1 <  Min  ||  Min  ==  INF ) )
        {
            
for int  k  =   1 ; k  <=  n; k ++  )   // 存储最优路径
                path[k]  =  a[k];
            Min 
=  cur  +  d[a[n - 1 ]][a[n]]  + d[a[n]][ 1 ];
        }
    }

    
else
    {
        
for int  j  =  i; j  <=  n; j ++ )   // 寻求路径子树
        {
            
if ( d[a[i - 1 ]][a[j]]  !=  INT_MAX  &&  ( cur  +  d[a[i - 1 ]][a[j]]  <  Min  ||  Min  ==  INF ) )
            {
                swap(a[i],a[j]);
                cur 
=  cur  +  d[a[i - 1 ]][a[i]];
                dfs(i
+ 1 );
                cur 
=  cur  -  d[a[i - 1 ]][a[i]];
                swap(a[i],a[j]);
            }
        }
    }
}


int  main()
{   
    
int  i,j;
    
int  chioce;

    cout
<< "             回溯法求解TSP问题             " << endl;
    
while 1  )
    {
         cout
<< "            1.回溯法求解TSP              " << endl;
         cout
<< "            2.退出程序                     " << endl;
         cin
>> chioce;

         
if ( chioce  ==   1 )
         {
            cout 
<<   " 请输入TSP的点数  "   <<  endl;
            cin
>> n;
            cout
<< endl;
            init();

            cout
<< " 路线矩阵: " << endl;
            
for ( i  =   1 ; i  <=  n;  i ++  )
            {
                
for (j  =   1 ; j  <=  n; j ++  )
                {
                    printf(
" %.0lf\t " ,d[i][j]);
                }
                cout 
<<  endl;        
            }

            dfs(
2 );   // 回溯搜索

            path[n
+ 1 =   1 ;
            printf(
" 长度: %lf\n路径: " , Min);
            
for ( i  =   1  ; i  <=  n + 1  ; i ++  )
                cout 
<<  path[i]  <<   "   " ;
            cout
<< endl;
        }
        
else
            
break ;

    }
    
return   0 ;
}

转载于:https://www.cnblogs.com/future-lin/archive/2009/06/28/1512803.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值