旅行推销员的多片段启发式(C ++)

时间:2016-05-10 15:51:37

标签: c++ greedy traveling-salesman

我正在尝试为TSP实现多片段启发式算法。

算法是这样的:

  1. 按照权重的递增顺序对边缘进行排序。(可以任意打开关系。)将要构造的游览边缘集初始化为空集。
  2. 重复此步骤n次,其中n是要解析的实例中的城市数:将排序边列表上的下一条边添加到游览边集,前提是此添加不会创建度为3的顶点或长度小于n的周期;否则,跳过边缘。
  3. 返回一组游览边缘。
  4. 我一直在检查是否有循环。

    #include <stdio.h>
    #include <math.h>
    #include <limits.h>
    #include <queue>
    static int repeat[6];
    struct element{
        int distance;
        int x;
        int y;
    };
    
    struct element array[25];
    
    void quicksort(struct element x[78400],int first,int last){
        int pivot,j,i;
        struct element temp;
        if(first<last){
            pivot=first;
            i=first;
            j=last;
    
            while(i<j){
                while(x[i].distance<=x[pivot].distance&&i<last)
                    i++;
                while(x[j].distance>x[pivot].distance)
                    j--;
                if(i<j){
                    temp=x[i];
                    x[i]=x[j];
                    x[j]=temp;
                }
            }
    
            temp=x[pivot];
            x[pivot]=x[j];
            x[j]=temp;
            quicksort(x,first,j-1);
            quicksort(x,j+1,last);
    
        }
    }
    bool isCycle(){
    
    
    
        return true;
    }
    
    bool canAdd(int a){
        repeat[array[a].x]++;
        repeat[array[a].y]++;
        if(repeat[array[a].x] > 2 || repeat[array[a].y] > 2){
            repeat[array[a].x]--;
            repeat[array[a].y]--;
            return false;
        }
        return true;
    }
    
    
    int main(int argc, const char * argv[]) {
    
    
        int i = 0;
    
        int graph[6][6] = {
            {INT_MAX,4,8,9,12},
            {4,INT_MAX,6,8,9},
            {8,6,INT_MAX,10,11},
            {9,8,10,INT_MAX,7},
            {12,9,11,7,INT_MAX}
        };
    
        int an = 0;
        for(int a = 0; a<5; a++){
            for(int b = a; b<5; b++){
                array[an].x = a;
                array[an].y = b;
                array[an].distance = graph[a][b];
                an++;
            }
        }
    
        quicksort(array, 0, an-1);
    
    
        static int sayilar[6];
        for(int ya = 0; ya<6; ya++){
            sayilar[ya] = 0;
        }
    
        std::queue<element> tour;
        int edges = 0;
    
        while(edges != 5){
            printf("%d %d %d\n", array[i].x, array[i].y, array[i].distance);
            if(canAdd(i)){
                tour.push(array[i]);
                printf("oldu\n");
                if(isCycle()){
                    tour.pop();
                }
            }
            i++;
            edges = (int)tour.size();
            printf("%d\n", edges);
        }
    
    
        return  0;
    }
    

    有没有办法检查是否有循环?

    非常感谢。

2 个答案:

答案 0 :(得分:0)

要测试循环的图形,请设置指向第一个边/顶点的两个指针。每次迭代移动一步,每次迭代移动另外两步。每次增量后检查两个指针​​是否相等。如果我们有相等的话,那么第二个指针已经循环并且赶上了,并且有一个循环。

答案 1 :(得分:-1)

构建片段时,请在每次迭代时检查更新片段的起始城市是否与最后一个片段相同。

您可能需要更改实施以使此验证更容易。

另外,我邀请您阅读第16届混合智能系统国际会议论文集中的“关于旅行商问题的多片段旅游构建算法的实证研究” (HIS 2016)第278-287页。 DOI:10.1007 / 978-3-319-52941-7_28。