算法设计实验六

实验六 利用回溯法解决售货员旅行问题

实验目的

  • 掌握回溯法的算法框架(排列树框架);
  • 利用回溯法解决售货员旅行问题.

实验内容

1. 回溯法的算法框架(排列树框架)

void backtrack(int t) {
    if (t == N) {
        output();
    } else {
        for(int i = t; i < N; i++) {
            swap(x[i], x[t]);
            if (constraints(t) && bound(t)) backtrack(t+1);
            swap(x[i], x[t]);
        }
    }   
}

2. 排列算法

问题描述:打印出 N 个元素的所有排列。

参考实现:

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

#define N  5

int x[] = {1, 2, 3, 4, 5};

void output() {
    int i;
    for (i = 0; i < N; i++)
        printf(" %d ", x[i]);
    printf("\n");
}

void swap(int i, int j) {
    int tmp = x[i];
    x[i] = x[j];
    x[j] = tmp;
}

void perm(int t) {
    if (t == N) {
        output();
    } else {
        int i;
        for (i = t; i < N; i++) {
            swap(i, t);
            perm(t + 1);
            swap(i, t);
        }
    }
}

void main() {
    perm(0);
}

3.售货员旅行问题

问题描述:某售货员到若干城市推销问题,已知各城市之间的路程,他要选定一条从驻地出发,经过每个城市一遍,最后回到驻地的路线,使总路程最小。(详见教材 P140, P166)

参考实现:

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

#define N  4 

int graph[N][N];

int x[] = { 0, 1, 2, 3, 0};

void swap(int a[], int x, int y) {
    int t = a[x];
    a[x] = a[y];
    a[y] = t;
}

int constraints(int t) {
    return graph[ x[t-1] ][ x[t] ] != 0;
}

int bound(int t, int w) {
    return 1; // 1 == true
}

void output(int w) {
    int i;
    for (i = 0; i < N; ++i) {
        printf("%d -> ", x[i]);
    }
    w += graph[ x[N-1] ][ 0 ];
    printf("0: %d\n", w);
}

void backtrack(int t, int w) {
    if (t == N) {
        output(w);
    } else {
        int i;
        for (i = t; i < N; ++i) {
            swap(x, t, i);
            if (constraints(t) && bound(t, w))
                backtrack(t + 1, w + graph[ x[t-1] ][ x[t] ]);
            swap(x, t, i);
        }
    }
}


void initGraph();

void main() {
    initGraph();
    backtrack(1, 0);
}

void addEdge(int v1, int v2, int weight) {
    graph[v1][v2] = graph[v2][v1] = weight;
}

void initGraph() {
    addEdge(0, 1, 30);
    addEdge(0, 2, 6);
    addEdge(0, 3, 4);
    addEdge(1, 2, 5);
    addEdge(1, 3, 10);
    addEdge(2, 3, 20);
}

思考

上述实现并没有实现限界函数 bound,正确地实现 bound 函数可以加快搜索解的过程,试实现 bound 函数。

posted on 2012-02-11 15:16  wuqq  阅读(226)  评论(0)    收藏  举报