精华内容
下载资源
问答
  • 遗传算法解决5种多旅行商问题(mtsp)的matlab程序 从不同起点出发回到起点(固定旅行商数量) 从不同起点出发回到起点(旅行商数量根据计算可变) 从同一起点出发回到起点 从同一起点出发不会到起点
  • %多旅行商问题的matlab程序 function varargout = mtspf_ga(xy,dmat,salesmen,min_tour,pop_size,num_iter,show_prog,show_res) % MTSPF_GA Fixed Multiple Traveling Salesmen Problem (M-TSP) Genetic Algorithm ...
  • 经过计算机验证,很好用。 function varargout = mtsp_ga(xy,dmat,salesmen,min_tour,pop_size,num_iter,show_prog,show_res)
  • 遗传算法解决5种多旅行商问题(mtsp)的matlab程序 分别为以下5中情况: 1.从不同起点出发回到起点(固定旅行商数量) 2.从不同起点出发回到起点(旅行商数量根据计算可变) 3.从同一起点出发回到起点 4.从同一起点...
  • 遗传算法解决5种多旅行商问题(mtsp)的matlab程序 分别为以下5中情况: 1.从不同起点出发回到起点(固定旅行商数量) 2.从不同起点出发回到起点(旅行商数量根据计算可变) 3.从同一起点出发回到起点 4.从同一...
  • 遗传算法解决5种多旅行商问题(mtsp)的matlab程序 分别为以下5中情况: 1.从不同起点出发回到起点(固定旅行商数量) 2.从不同起点出发回到起点(旅行商数量根据计算可变) 3.从同一起点出发回到起点 4.从同一起点...
  • 遗传算法解决5种多旅行商问题(mtsp)的matlab程序 分别为以下5中情况: 1.从不同起点出发回到起点(固定旅行商数量) 2.从不同起点出发回到起点(旅行商数量根据计算可变) 3.从同一起点出发回到起点 4.从同一起点...
  • 本算法可以求得从一个城市出发的旅行商问题,而且通过参数设定,可使各路均衡,望对大家有所帮助。 本算法可以求得从一个城市出发的旅行商问题,而且通过参数设定,可使各路均衡,望对大家有所帮助。
  • 遗传算法解决5种多旅行商问题(mtsp)的matlab程序 分别为以下5中情况: 1.从不同起点出发回到起点(固定旅行商数量) 2.从不同起点出发回到起点(旅行商数量根据计算可变) 3.从同一起点出发回到起点 4.从同一起点...
  • 全排列与回溯法解旅行商问题

    千次阅读 2016-06-03 20:00:05
    虽然说全排列好像很简单,但真的当用程序来生成时还一时不知道怎么办,但是我觉得穷举法是很算法的基础,比如回溯法,排序等,我会以旅行商问题来说明全排列,只需一次就会了。1.开始回溯法的本质也是搜索,只是...

    虽然说全排列好像很简单,但真的当用程序来生成时还一时不知道怎么办,但是我觉得穷举法是很多算法的基础,比如回溯法,排序等,我会以旅行商问题来说明全排列,只需一次就会了。


    1.开始

    回溯法的本质也是搜索,只是加上了约束条件,使搜索的次数减少许多,我们把约束条件和目标函数的边界称为剪枝策略。

    对于旅行商这个问题,说的是一个商人想从一个城市出发,不重复地走遍所有城市然后回到起点,每个城市间有不同的旅行费用,求花最少的钱走完?

    典型的一个图的存储结构,如下例子:

    1

    我采用简单的二维矩阵存储结构,接下来:
    我会给出穷举的算法,然后加上约束条件,最后进行对比。

    穷举法

    穷举次序列的本质是全排列,采用递归生成,打印全过程:
    仔细的看代码就好,注释很详细,全排列的精髓就在那了:

    #include <iostream>
    using namespace std;
    
    int *x;//城市编号数组
    int *bestx;//路线
    int w = 0;//过渡变量
    int bestw = INT32_MAX;//最优的费用
    
    void Tsp(int **a, int n, int s);
    int main() {
        int **a;//a[i][j]表示从第i个城市到第j个的费用
        int n;//城市个数
    
        cin >> n;
    
        x = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = i;//表示第i个城市编号,0到n-1
        }
        bestx = new int[n];
    
        a = new int*[n];
        for (int i = 0; i < n; i++) {
            a[i] = new int[n];
        }
        //输入费用矩阵表示图
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> a[i][j];
            }
        }
    
        Tsp(a, n, 1);//传1表示只搜从0开始的全排,传0表示所有全排
    
        cout << "最优的是:" << bestw << endl;
    
        for (int i = 0; i < n; i++) {
            delete a[i];
        }
        delete[]a;
        delete[]x;
        delete[]bestx;
        return 0;
    }
    void Tsp(int **a, int n, int s) {
        if (s == n) {
            w = 0;//清零
            cout << "bestx: ";
            for (int i = 0; i < n; i++) {
                bestx[i] = x[i];
                cout << bestx[i] << " ";
                if (i < n - 1) {
                    w += a[x[i]][x[i + 1]];
                }
                else {
                    w += a[x[i]][x[0]];//回到起点的费用
                }
            }
            cout << "w:" << w << endl;
            if (bestw > w) {
                bestw = w;//更新最优值
            }
        }
        else {
            for (int i = s; i < n; i++) {
                //为什么要交换呢?因为要将x[s]作为起点进行往下搜索
                int t = x[i]; x[i] = x[s]; x[s] = t;
                Tsp(a, n, s + 1);
                t = x[i]; x[i] = x[s]; x[s] = t;
            }
        }
    }

    运行结果如下:

    5
    0 3 3 2 6
    3 0 7 3 2
    3 7 0 2 5
    2 3 2 0 3
    6 2 5 3 0
    bestx: 0 1 2 3 4 w:21
    bestx: 0 1 2 4 3 w:20
    bestx: 0 1 3 2 4 w:19
    bestx: 0 1 3 4 2 w:17
    bestx: 0 1 4 3 2 w:13
    bestx: 0 1 4 2 3 w:14
    bestx: 0 2 1 3 4 w:22
    bestx: 0 2 1 4 3 w:17
    bestx: 0 2 3 1 4 w:16
    bestx: 0 2 3 4 1 w:13
    bestx: 0 2 4 3 1 w:17
    bestx: 0 2 4 1 3 w:15
    bestx: 0 3 2 1 4 w:19
    bestx: 0 3 2 4 1 w:14
    bestx: 0 3 1 2 4 w:23
    bestx: 0 3 1 4 2 w:15
    bestx: 0 3 4 1 2 w:17
    bestx: 0 3 4 2 1 w:20
    bestx: 0 4 2 3 1 w:19
    bestx: 0 4 2 1 3 w:23
    bestx: 0 4 3 2 1 w:21
    bestx: 0 4 3 1 2 w:22
    bestx: 0 4 1 3 2 w:16
    bestx: 0 4 1 2 3 w:19
    最优的是:13
    请按任意键继续. . .

    回溯法

    现在,我们加上约束条件:

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    int *x;//城市编号数组
    int *bestx;//最好的路线
    int bestw = 0;//最优的费用
    int cc = 0;//过渡变量cost
    
    void Tsp(int **a, int n, int s);
    int main() {
        int **a;//a[i][j]表示从第i个城市到第j个的费用
        int n;//城市个数
    
        cin >> n;
    
        x = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = i;//表示第i个城市编号,0到n-1
        }
        bestx = new int[n];
    
        a = new int*[n];
        for (int i = 0; i < n; i++) {
            a[i] = new int[n];
        }
        //输入费用矩阵表示图
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> a[i][j];
            }
        }
    
        Tsp(a, n, 1);
    
        cout << "最优的是:" << bestw << endl;
    
        for (int i = 0; i < n; i++) {
            delete a[i];
        }
        delete[]a;
        delete[]x;
        delete[]bestx;
        return 0;
    }
    void Tsp(int **a, int n, int s) {
        if (s == n) {
            //找到一条路线,下面判断条件的含义
            //a[x[n - 1]][x[0]] != 0:0表示城市不可达
            //cc + a[x[n - 1]][x[0]] < bestw:加上返回起点的费用是否大于最优的费用
            if ((a[x[n - 1]][x[0]] != 0 && (cc + a[x[n - 1]][x[0]] < bestw)) || bestw == 0) {
                cout << "bestx: ";
                for (int i = 0; i < n; i++) {
                    bestx[i] = x[i];
                    cout << bestx[i] << " ";
                }
                bestw = cc + a[x[n - 1]][x[0]];
                cout << "bestw:" << bestw << endl;
            }
        }
        else {
            for (int i = s; i < n; i++) {
                //这里就是递归遍历的地方,加了约束条件,和上面一样
                //递归的基础是:前面交换了,回溯时得交换回来,加了得减回来
                if ((a[x[i - 1]][x[i]] != 0 && cc + a[x[i - 1]][i] < bestw) || bestw == 0) {
                    int t = x[i]; x[i] = x[s]; x[s] = t;
                    cc += a[x[s - 1]][x[s]];
                    Tsp(a, n, s + 1);
                    cc -= a[x[s - 1]][x[s]];
                    t = x[i]; x[i] = x[s]; x[s] = t;
                }
            }
        }
    }

    再来看运行结果:

    2

    总结

    可以看出约束条件还是很有用的。
    全排列的大体框架都差不多,操作都在s==n里。

    展开全文
  • 有很从磁盘读取数据的需求,包括顺序读取、随机读取。为了提高效率,需要人为安排磁盘读取。然而,在现实中,这种做法很复杂。我们考虑一个相对简单的场景。磁盘有许多轨道,每个轨道有许多扇区,用于存储数据。当...

    Problem Description
    有很多从磁盘读取数据的需求,包括顺序读取、随机读取。为了提高效率,需要人为安排磁盘读取。然而,在现实中,这种做法很复杂。我们考虑一个相对简单的场景。磁盘有许多轨道,每个轨道有许多扇区,用于存储数据。当我们想在特定扇区来读取数据时,磁头需要跳转到特定的轨道、具体扇区进行读取操作。为了简单,我们假设磁头可以在某个轨道顺时针或逆时针匀速旋转,旋转一周的时间是360个单位时间。磁头也可以随意移动到某个轨道进行读取,每跳转到一个相邻轨道的时间为400个单位时间,跳转前后磁头所在扇区位置不变。一次读取数据的时间为10个单位时间,读取前后磁头所在的扇区位置不变。磁头同时只能做一件事:跳转轨道,旋转或读取。现在,需要在磁盘读取一组数据,假设每个轨道至多有一个读取请求,这个读取的扇区是轨道上分布在 0到359内的一个整数点扇区,即轨道的某个360等分点。磁头的起始点在0轨道0扇区,此时没有数据读取。在完成所有读取后,磁头需要回到0轨道0扇区的始点位置。请问完成给定的读取所需的最小时间。

    Input
    输入的第一行包含一个整数M(0<M<=100),表示测试数据的组数。对于每组测试数据,第一行包含一个整数N(0<N<=1000),表示要读取的数据的数量。之后每行包含两个整数T和S(0<T<=1000,0<= S<360),表示每个数据的磁道和扇区,磁道是按升序排列,并且没有重复。
     
    Output
    对于每组测试数据,输出一个整数,表示完成全部读取所需的时间。
     
    Sample Input
    3
    1
    1 10
    3
    1 20
    3 30
    5 10
    2
    1 10
    2 11
     
    Sample Output
    830
    4090
    1642


    解题思路:

    这题目和双调欧几里得旅行商问题思想是一样的,从一个点出发,不重复的到达每一个点,最后到达起点,求最短距离。

    现学的这个,参考:

    http://www.cppblog.com/doer-xee/archive/2009/11/30/102296.html

    http://www.cnblogs.com/-sunshine/archive/2012/07/23/2605251.html

    http://blog.csdn.net/xiajun07061225/article/details/8092247

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn=1010;
    const int inf=0x7fffffff;
    int cas;
    int n;
    struct Node
    {
        int t,s;
    }node[maxn];
    double dp[maxn][maxn];
    
    int dis(Node a,Node b)//计算两个磁道读取数据位置的距离(包括磁道距离+扇区距离)
    {
        int ci=abs(a.t-b.t)*400;
        int MAX=(a.s>b.s?a.s:b.s);
        int MIN=(a.s<b.s?a.s:b.s);
        int shan=min(MAX-MIN,360-MAX+MIN);
        return ci+shan;
    }
    int DP(int n)//双调欧几里得旅行商问题算法
    {
        dp[1][2]=dis(node[1],node[2]);
        for(int j=3;j<=n;j++)
        {
            for(int i=1;i<=j-2;i++)
                dp[i][j]=dp[i][j-1]+dis(node[j-1],node[j]);
            dp[j-1][j]=inf;
            for(int k=1;k<=j-2;k++)
            {
                int temp=dp[k][j-1]+dis(node[k],node[j]);
                if(temp<dp[j-1][j])
                    dp[j-1][j]=temp;
            }
        }
        dp[n][n]=dp[n-1][n]+dis(node[n-1],node[n]);
        return dp[n][n];
    
    }
    int main()
    {
        cin>>cas;
        while(cas--)
        {
            cin>>n;
            node[1].t=0,node[1].s=0;
            for(int i=1;i<=n;i++)
                cin>>node[i+1].t>>node[i+1].s;
            n++;
            cout<<DP(n)+10*(n-1)<<endl;//别忘了加上读取数据的时间
        }
        return 0;
    }


    展开全文
  • tsp旅行商问题和高级搜索方法

    千次阅读 2015-12-23 16:02:33
    一、 问题介绍 中国邮递员问题tsp 输入:中国144个城市数据 输出:最短路径序列及路径长度 ...很多问题属于优化问题,或者可以转化为优化问题,如TSP问题,皇后问题等。 2. 用一个城市的序列表示一个可能

    一、    问题介绍

    中国邮递员问题tsp

    输入:中国144个城市数据

    输出:最短路径序列及路径长度

    1.       采用局部搜索算法实现

    2.       采用模拟退化算法实现

    二、    程序设计与算法分析

    1.     待解决的问题实际上是优化与组合优化问题。很多问题属于优化问题,或者可以转化为优化问题,如TSP问题,皇后问题等。

    2.     用一个城市的序列表示一个可能的解,通过交换两个城市的位置获取S的邻居。

    逆序交换方法设xi、xj是选取的两个城市,所谓的逆序交换方式是指,通过逆转xi、xj两个城市之间的城市次序来得到S的邻居。

    3.     local search:

    基本思想:在搜索过程中,始终向着离目标最接近的方向搜索。

    目标可以是最大值,也可以是最小值。

    本题中目标为最小值。

    算法步奏:

    1.随机的选择一个初始的可能解x0∈D,xb=x0,P=N(xb);

    2.    如果不满足结束条件,则

    3.    Begin

    4.    选择P的一个子集P',xn为P'中的最优解

    5.    如果f(xn)<f(xb),则xb=xn,P=N(xb),

    转2;f(x)为指标函数。

    6. 否则P=P–P',转2。

    7.    End

    8.    输出计算结果

    9.    结束

                          4.    localsearch中存在的问题:

                                     得到的答案往往是局部最优,而不是全局最优解。

                          5.    解决local search中问题的方法:

    1)       每次并不一定选择邻域内最优的点,而是依据一定的概率,从 邻域内选择一个点,指标数优的点,被选中的概率比较大, 而指标函数差的点,被选中的概率比较小。

    2)       函数的递增递减可能不均匀,在最优值附近可能变化极快,最好采用变步长的方式,越接近最优解时步长越小。

    3)       起始点的选择可能会影响最终的解:随机的生成一些初始点,从每个初始点出发进行搜索,找到各自的最优解。再从这些最优解中选择一个最好的结果作为最终的结果。

    6. 以上决方法可以结合在一起使用,比如第一、第二种方 法的结合,就产生了模拟退火方法。

    7. 模拟退火思想综述:

    在高温下,系统基本处于无序的状态,基本以等概率落入各个状态在给定的温度下,系统  落入低能量状态的概率大于系统落入高能量状态的概率,这样在同一温度下,如果系统交换的 足够充分,则系统会趋向于落入较低能量的状态。随着温度的 缓慢下降,系统落入低能量状态的概率逐步增加,而落入高能量状态的概率逐步减少,使得系统各状态能量的期望值随温度的下降单调下降,而只有那些能量小于期望值的状态,其概率 才随温度下降增加,其他状态均随温度下降而下降。因此,随着能量期望值的逐步下降,能量低于期望值的状态逐步减少, 当温度趋于0时,只剩下那些具有最小能量的状态,系统处于其他状态的概率趋近于0。因此最终系统将以概率1处于具有最小能量的一个状态。

                           8.  达到最小能量状态三个条件:

    1)       初始温度必须足够高;

    2)       在每个温度下,状态的交换必须足够充分;

    1.             3)    温度T的下降必须足够缓慢

     9.  算法流程:

    1)       随机选择一个解i,k=0,t0=Tmax(初始温度),计算指标函数f(i)

    2)       如果满足结束条件,则转(15)。

    3)       Begin

    4)       如果在该温度内达到了平衡条件,则转(13)。

    5)       Begin

    6)       从i的邻域N(i)中随机选择一个解j。

    7)       计算指标函数f(j)。

    8)       如果f(j)<f(i),则i=j,f(i)=f(j),转(4)。

    9)       计算P (i->j) =exp{ -( f(j)-f(i) )/t };

    10)     如果Pt(i=>j)>Random(0,1),则i=j,f(i)=f(j)。

    11)     转(4)

    12)     End

    13)     tk+1=Drop(tk),k=k+1。

    14)     End

    15)     输出结果。

    16)     结束。

      10.  算法中的问题:

    1)       初始温度的选取:

    一个合适的初始温度,应保证平稳分布中每一个状态的概率基本相等,也就是接受概率P近似等于1。可选初始温度为1,每次温度上升5%,直到接受概率为0.9为止。

    2)       内循环的结束条件,即每个温度状态交换何时结束:

    固定长度方法:在每一个温度下,都使用相同的Lk。Lk的选取与具体的问题相关,一般与邻域的大小直接关联,通常选择为问题规模n的一个多项式函数。

    3)       外循环的结束条件,即温度下降到什么时候结束:

    无变化控制法:如果在相邻的n个温度中,得到的解的指标函数值无任何变化,则说明算法已经收敛。

    4)       温度的下降方法:

    等比例的下降温度:如每次温度下降5%。

              

    三、    实验结果

    1.   local_search实验结果:


    2.   模拟退火实验结果:

     


     


    四    local_search实现:

    // 实验4:中国邮递员问题
    // 输入:中国144个城市数据
    // 输出:最短路径序列及路径长度
    // 4.1 采用局部搜索算法实现
    
    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN=144;
    double len=0;
    struct Point{
    	int num,x,y;
    	double dist(Point &r){
    		return sqrt((x-r.x)*(x-r.x)+(y-r.y)*(y-r.y));
    	}
    }point[144];
    
    // 生成一个随机路径开始搜索
    void init(){
    	len=0;
    	// 生成全排列
    	for(int i=0;i<MAXN;++i){
    		int pos=rand()%MAXN;
    		swap(point[pos],point[i]);
    	}
    	for(int i=0;i<MAXN-1;++i)
    		len+=point[i].dist(point[i+1]);
    	len+=point[0].dist(point[MAXN-1]);
    }
    
    
    void readData(){
    	freopen("Cities(144).txt","r",stdin);
    	for(int i=0;i<144;++i)
    		scanf("%d%d%d",&point[i].num,&point[i].x,&point[i].y);
    	double ans=0;
    }
    
    void localSearch1(){
    	int times=20000000;
    	while(times--){
    		int pos1=rand()%MAXN,pos2=rand()%MAXN;
    		if(pos1>pos2) swap(pos1,pos2);
    		if(pos1==pos2 || (pos1==0 && pos2==MAXN-1)) continue; 
    		double offset=point[pos1].dist(point[(pos2+1)%MAXN])+point[pos2].dist(point[(pos1-1+MAXN)%MAXN])-point[pos1].dist(point[(pos1-1+MAXN)%MAXN])-point[pos2].dist(point[(pos2+1)%MAXN]);
    		if(offset<0){
    			len+=offset;
    			while(pos1<pos2) swap(point[pos1++],point[pos2--]);
    		}
    
    	}
    }
    
    int main(){
    	srand((unsigned int)time(NULL));
    	readData();
    	init();
    	localSearch1();
    	printf("len:\n%f\npath:\n",len);
    	for(int i=0;i<MAXN;++i)
    		printf("%d ",point[i].num);
    	printf("\n");
    	return 0;
    }
    
    
    
    


    五.   模拟退火实现:

    // 实验4:中国邮递员问题
    // 输入:中国144个城市数据
    // 输出:最短路径序列及路径长度
    // 4.1 采用局部搜索算法实现
    
    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN=144;
    const double E=2.718281828459;
    double len=0,temperature=1,recent_len[2]={1e12,1e12};
    struct Point{
        int num,x,y;
        double dist(Point &r){
            return sqrt((x-r.x)*(x-r.x)+(y-r.y)*(y-r.y));
        }
    }point[144];
    
    inline double rand0_1(){
        return 1.0*rand()/RAND_MAX;
    }
    
    double get_receive_rate(){
        int receive=0,times=300,t=300;
        while(t--){
            int pos1=rand()%MAXN,pos2=rand()%MAXN;
            if(pos1>pos2) swap(pos1,pos2);
            if(pos1==pos2 || (pos1==0 && pos2==MAXN-1)){
                ++receive;
                continue;
            }
            double offset=point[pos1].dist(point[(pos2+1)%MAXN])+point[pos2].dist(point[(pos1-1+MAXN)%MAXN])-point[pos1].dist(point[(pos1-1+MAXN)%MAXN])-point[pos2].dist(point[(pos2+1)%MAXN]);
            if(offset<=0 || pow(E,-offset*1.0/temperature)>=rand0_1())
                ++receive;
        }
        return 1.0*receive/times;
    }
    
    
    // 生成一个随机解作为初始解,并计算一个合适的初始温度(使得接受概率大于0.9)
    void init(){
        len=0;
        // 生成全排列
        for(int i=0;i<MAXN;++i){
            int pos=rand()%MAXN;
            swap(point[pos],point[i]);
        }
        for(int i=0;i<MAXN-1;++i)
            len+=point[i].dist(point[i+1]);
        len+=point[0].dist(point[MAXN-1]);
        while(get_receive_rate()<0.9) temperature*=1.05;
    }
    
    
    void readData(){
        freopen("Cities(144).txt","r",stdin);
        for(int i=0;i<144;++i)
            scanf("%d%d%d",&point[i].num,&point[i].x,&point[i].y);
        double ans=0;
    }
    
    void anneal(){
    	int times=1e4;
        while(temperature>0.001){
    		times*=1.01;
    		int t=times;
    //		printf("temperature=%f\ttimes=%d\tlen=%f\n",temperature,t,len);
            while(t--){
                int pos1=rand()%MAXN,pos2=rand()%MAXN;
                if(pos1>pos2) swap(pos1,pos2);
                if(pos1==pos2 || (pos1==0 && pos2==MAXN-1)) continue;
                double offset=point[pos1].dist(point[(pos2+1)%MAXN])+point[pos2].dist(point[(pos1-1+MAXN)%MAXN])-point[pos1].dist(point[(pos1-1+MAXN)%MAXN])-point[pos2].dist(point[(pos2+1)%MAXN]);
                if(offset<=0 || pow(E,-offset*1.0/temperature)>=rand0_1()){
                    len+=offset;
                    while(pos1<pos2) swap(point[pos1++],point[pos2--]);
                }
            }
    		if(len==recent_len[0] && len==recent_len[1]) break;
            temperature*=0.98;
    		recent_len[0]=recent_len[1];
    		recent_len[1]=len;
        }
    }
    void debug(){
    }
    
    int main(){
        srand((unsigned int)time(NULL));
        readData();
        init();
        debug();
        anneal();
        printf("len:\n%f\npath:\n",len);
        for(int i=0;i<MAXN;++i)
            printf("%d ",point[i].num);
        printf("\n");
        return 0;
    }
    
    
    
    


     

    展开全文
  • 有非常从磁盘读取数据的需求。包含顺序读取、随机读取。为了提高效率,须要人为安排磁盘读取。然而,在现实中。这样的做法非常复杂。我们考虑一个相对简单的场景。磁盘有很轨道,每一个轨道有很扇区,用于存储...

    Problem Description
    有非常多从磁盘读取数据的需求。包含顺序读取、随机读取。

    为了提高效率,须要人为安排磁盘读取。然而,在现实中。这样的做法非常复杂。

    我们考虑一个相对简单的场景。磁盘有很多轨道,每一个轨道有很多扇区,用于存储数据。当我们想在特定扇区来读取数据时,磁头须要跳转到特定的轨道、详细扇区进行读取操作。为了简单,我们如果磁头能够在某个轨道顺时针或逆时针匀速旋转,旋转一周的时间是360个单位时间。磁头也能够任意移动到某个轨道进行读取。每跳转到一个相邻轨道的时间为400个单位时间。跳转前后磁头所在扇区位置不变。

    一次读取数据的时间为10个单位时间,读取前后磁头所在的扇区位置不变。磁头同一时候仅仅能做一件事:跳转轨道,旋转或读取。如今,须要在磁盘读取一组数据,如果每一个轨道至多有一个读取请求,这个读取的扇区是轨道上分布在 0到359内的一个整数点扇区。即轨道的某个360等分点。

    磁头的起始点在0轨道0扇区。此时没有数据读取。在完毕全部读取后,磁头须要回到0轨道0扇区的始点位置。

    请问完毕给定的读取所需的最小时间。

    Input
    输入的第一行包括一个整数M(0<M<=100),表示測试数据的组数。对于每组測试数据,第一行包括一个整数N(0<N<=1000),表示要读取的数据的数量。之后每行包括两个整数T和S(0<T<=1000,0<= S<360),表示每一个数据的磁道和扇区,磁道是按升序排列,而且没有反复。
     
    Output
    对于每组測试数据,输出一个整数,表示完毕所有读取所需的时间。
     
    Sample Input
    3
    1
    1 10
    3
    1 20
    3 30
    5 10
    2
    1 10
    2 11
     
    Sample Output
    830
    4090
    1642


    解题思路:

    这题目和双调欧几里得旅行商问题思想是一样的,从一个点出发,不反复的到达每个点,最后到达起点。求最短距离。

    现学的这个,參考:

    http://www.cppblog.com/doer-xee/archive/2009/11/30/102296.html

    http://www.cnblogs.com/-sunshine/archive/2012/07/23/2605251.html

    http://blog.csdn.net/xiajun07061225/article/details/8092247

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn=1010;
    const int inf=0x7fffffff;
    int cas;
    int n;
    struct Node
    {
        int t,s;
    }node[maxn];
    double dp[maxn][maxn];
    
    int dis(Node a,Node b)//计算两个磁道读取数据位置的距离(包含磁道距离+扇区距离)
    {
        int ci=abs(a.t-b.t)*400;
        int MAX=(a.s>b.s?

    a.s:b.s); int MIN=(a.s<b.s?a.s:b.s); int shan=min(MAX-MIN,360-MAX+MIN); return ci+shan; } int DP(int n)//双调欧几里得旅行商问题算法 { dp[1][2]=dis(node[1],node[2]); for(int j=3;j<=n;j++) { for(int i=1;i<=j-2;i++) dp[i][j]=dp[i][j-1]+dis(node[j-1],node[j]); dp[j-1][j]=inf; for(int k=1;k<=j-2;k++) { int temp=dp[k][j-1]+dis(node[k],node[j]); if(temp<dp[j-1][j]) dp[j-1][j]=temp; } } dp[n][n]=dp[n-1][n]+dis(node[n-1],node[n]); return dp[n][n]; } int main() { cin>>cas; while(cas--) { cin>>n; node[1].t=0,node[1].s=0; for(int i=1;i<=n;i++) cin>>node[i+1].t>>node[i+1].s; n++; cout<<DP(n)+10*(n-1)<<endl;//别忘了加上读取数据的时间 } return 0; }



    转载于:https://www.cnblogs.com/yfceshi/p/6907038.html

    展开全文
  • 主要研究领域为整数规划与组合优化,曾出版部研究旅行商问题的专著,其中与人合著的The Taveling Salesman Problem:A Computational Study获2007年Lanchester奖。 目录 · · · · · · 目 录 第 1 章 难题大...
  • &#13; 喜欢的话可以扫码关注我们的公众号哦,更精彩尽在微信公众号【程序猿声】 ...TSP问题(Traveling Salesman Problem,旅行商问题),由威廉哈密顿爵士和英国数学家克克曼T.P.Kirkman于19世纪初提出...
  • 程序可以在窗口里用鼠标随意点击来产生不同的“城市”,最短距离也是直观的...热心提醒:模拟退火法在该程序中没有单一的退火方向,等同于随机遍历,你可以自己想办法设置退火方向,我还没想出来怎么办╮(╯▽╰)╭
  • 嗯哼,第一次写博客,准确说是第一次通过文字的方式记录自己的工作,闲话少叙,技术汪的博客就该直奔技术主题(关于排版问题,会在不断写博客的过程中慢慢学习,先将就着用吧,重在技术嘛~~~)。遗传算法(Genetic ...
  • 对于一些离散问题,如旅行商TSP问题,这些算法就不怎么适用了,需要一定的转换。重点来了:很多人的转换方法其实是不对的,金玉其外,败絮其中。比如TSP问题,他们依然使用实数编码,如实数编码是【0.44 0.62 0.56 ...
  • 趣味javascript程序

    2016-04-28 09:34:00
    遗传算法解决旅行商问题(TSP) 2014年11月16日其它JS程序算法 旅行商问题(TSP)是经典的NP完全问题,也经常被程序员们用来测试和练习各种算法的效率。这是我写的一个纯粹练手的程序,还未完善,随后应该会稍...

空空如也

空空如也

1 2 3
收藏数 58
精华内容 23
关键字:

多旅行商问题程序