货郎担问题算法 c语言实现,求解货郎担问题的分枝限界算法

#include

#include

#include

#define TRUE (1)

#define FALSE (0)

#define MAX_CITIES (10)

#define INFINITY (999)

#define I INFINITY

typedef int bool;

typedef struct _EDGE {

int head;

int tail;

} EDGE;

typedef struct _PATH {

EDGE edge[MAX_CITIES];

int edgesNumber;

} PATH;

typedef struct _MATRIX {

int distance[MAX_CITIES][MAX_CITIES];

int citiesNumber;

} MATRIX;

typedef struct _NODE {

int bound; MATRIX matrix; PATH path; struct _NODE* left; struct _NODE* right; } NODE;

int Simplify(MATRIX*);

EDGE SelectBestEdge(MATRIX);

MATRIX LeftNode(MATRIX, EDGE);

MATRIX RightNode(MATRIX, EDGE, PATH);

PATH AddEdge(EDGE, PATH);

PATH BABA(NODE);

PATH MendPath(PATH, MATRIX);

int MatrixSize(MATRIX, PATH);

void ShowMatrix(MATRIX);

void ShowPath(PATH, MATRIX);

main()

{

PATH path;

NODE root = {

0,

{{{I, 1, 2, 7, 5},

{1, I, 4, 4,

3},

{2, 4, I, 1,

2},

{7, 4, 1, I,

3},

{5, 3, 2, 3,

I}}, 5},

{{0}, 0},

NULL, NULL

};

root.bound += Simplify(&root.matrix);

path = BABA(root);

ShowPath(path, root.matrix);

return 0;

}

PATH BABA(NODE root)

{

int i;

static int minDist = INFINITY;

static PATH minPath;

EDGE selectedEdge;

NODE *left, *right;

puts("Current

Root:\n------------");

ShowMatrix(root.matrix);

printf("Root Bound:%d\n", root.bound);

if (MatrixSize(root.matrix, root.path) == 2)

{

if (root.bound <

minDist) {

minDist =

root.bound;

minPath =

MendPath(root.path, root.matrix);

getch();

return

(minPath);

}

}

selectedEdge = SelectBestEdge(root.matrix);

printf("Selected Edge:(%d, %d)\n",

selectedEdge.head + 1, selectedEdge.tail + 1);

left = (NODE *)malloc(sizeof(NODE));

right = (NODE *)malloc(sizeof(NODE));

if (left == NULL || right == NULL) {

fprintf(stderr,"Error

malloc.\n");

exit(-1);

}

left->bound = root.bound;

left->matrix =

LeftNode(root.matrix, selectedEdge);

left->path = root.path;

left->left = NULL;

left->right = NULL;

right->bound =

root.bound;

right->matrix =

RightNode(root.matrix, selectedEdge, root.path);

right->path =

AddEdge(selectedEdge, root.path);

right->left = NULL;

right->right = NULL;

left->bound +=

Simplify(&left->matrix);

right->bound +=

Simplify(&right->matrix);

root.left = left;

root.right = right;

puts("Right Branch:\n------------");

ShowMatrix(right->matrix);

puts("Left Branch:\n-----------");

ShowMatrix(left->matrix);

if (right->bound <

minDist) {

BABA(*right);

}

else {

printf("Current minDist is %d,

", minDist);

printf("Right Branch's Bound(=

%d).\n", right->bound);

printf("This branch is

dead.\n");

}

if (left->bound <

minDist) {

BABA(*left);

}

else {

printf("Current minDist is %d,

", minDist);

printf("Left Branch's Bound(=

%d).\n", left->bound);

printf("This branch is

dead.\n");

}

printf("The best answer now is %d\n",

minDist);

return (minPath);

}

PATH MendPath(PATH path, MATRIX c)

{

int row, col;

EDGE edge;

int n = c.citiesNumber;

for (row = 0; row < n;

row++) {

edge.head = row;

for (col = 0; col

< n; col++) {

edge.tail =

col;

if

(c.distance[row][col] == 0) {

path

= AddEdge(edge, path);

}

}

}

return path;

}

int Simplify(MATRIX* c)

{

int row, col, min_dist, h;

int n = c->citiesNumber;

h = 0;

for (row = 0; row < n; row++)

{

min_dist = INFINITY;

for (col = 0; col

< n; col++) {

if

(c->distance[row][col] < min_dist)

{

min_dist

= c->distance[row][col];

}

}

if (min_dist == INFINITY)

continue;

for (col = 0; col

< n; col++) {

if

(c->distance[row][col] != INFINITY) {

c->distance[row][col]

-= min_dist;

}

}

h += min_dist;

}

for (col = 0; col < n; col++)

{

min_dist = INFINITY;

for (row = 0; row

< n; row++) {

if

(c->distance[row][col] < min_dist)

{

min_dist

= c->distance[row][col];

}

}

if (min_dist == INFINITY)

continue;

for (row = 0; row

< n; row++) {

if

(c->distance[row][col] != INFINITY) {

c->distance[row][col]

-= min_dist;

}

}

h += min_dist;

}

return (h);

}

EDGE SelectBestEdge(MATRIX c)

{

int row, col;

int n = c.citiesNumber;

int maxD;

EDGE best, edge;

int D(MATRIX, EDGE);

maxD = 0;

for (row = 0; row < n; row++)

{

for (col = 0; col

< n; col++) {

edge.head =

row;

edge.tail =

col;

if

(!c.distance[row][col] && maxD < D(c, edge))

{

maxD

= D(c, edge);

best

= edge;

}

}

}

return (best);

}

int D(MATRIX c, EDGE edge)

{

int row, col, dRow, dCol;

int n = c.citiesNumber;

dRow = INFINITY;

for (col = 0; col < n; col++)

{

if (dRow <

c.distance[edge.head][col] && col != edge.tail) {

dRow =

c.distance[edge.head][col];

}

}

dCol = INFINITY;

for (row = 0; row < n; row++)

{

if (dCol <

c.distance[row][edge.tail] && row != edge.head) {

dCol =

c.distance[row][edge.tail];

}

}

return (dRow + dCol);

}

MATRIX LeftNode(MATRIX c, EDGE edge)

{

c.distance[edge.head][edge.tail] =

INFINITY;

return c;

}

MATRIX RightNode(MATRIX c, EDGE edge, PATH

path)

{

int row, col;

int n = c.citiesNumber;

EDGE loopEdge;

EDGE LoopEdge(PATH, EDGE);

for (col = 0; col < n;

col++)

c.distance[edge.head][col] =

INFINITY;

for (row = 0; row < n;

row++)

c.distance[row][edge.tail] =

INFINITY;

loopEdge = LoopEdge(path, edge);

c.distance[loopEdge.head][loopEdge.tail] =

INFINITY;

return (c);

}

EDGE LoopEdge(PATH path, EDGE edge)

{

int i, j;

EDGE loopEdge;

loopEdge.head = edge.tail;

loopEdge.tail = edge.head;

for (i = 0; i < path.edgesNumber;

i++) {

for (j = 0; j <

path.edgesNumber; j++) {

if

(loopEdge.head == path.edge[j].head) {

loopEdge.head

= path.edge[j].tail;

break;

}

}

}

for (i = 0; i < path.edgesNumber;

i++) {

for (j = 0; j <

path.edgesNumber; j++) {

if

(loopEdge.tail == path.edge[j].tail) {

loopEdge.tail

= path.edge[j].head;

break;

}

}

}

return (loopEdge);

}

PATH AddEdge(EDGE edge, PATH path)

{

path.edge[path.edgesNumber++] = edge;

return path;

}

int MatrixSize(MATRIX c, PATH path)

{

return (c.citiesNumber - path.edgesNumber);

}

void ShowPath(PATH path, MATRIX c)

{

int i, dist;

EDGE edge;

int n = path.edgesNumber;

dist = 0;

printf("\nThe path is: ");

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

edge = path.edge[i];

printf("(%d, %d) ", edge.head +

1, edge.tail + 1);

dist +=

c.distance[edge.head][edge.tail];

}

}

void ShowMatrix(MATRIX c)

{

int row, col;

int n = c.citiesNumber;

for (row = 0; row < n;

row++) {

for (col = 0; col

< n; col++) {

if

(c.distance[row][col] != INFINITY) {

printf("=",

c.distance[row][col]);

}

else {

printf(" -");

}

}

putchar('\n');

}

getch();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值