分支限界法求货郎担问题

10025413228
5100183126
201610071
1051251006
239711100
#include<iostream>
#include<fstream>
using namespace std;

typedef int Type;
#define N 5
#define ZERO 0
#define MAX 1000

typedef struct node_data {
	Type c[N][N];   
	int row_init[N];
	int col_init[N]; 
	int row_cur[N]; 
	int col_cur[N]; 
	int ad[N];
	int k;
	Type w;           
	struct node_data* next;
}NODE;

Type c[N][N];
Type ad[N];


Type row_min(NODE* node, int row, Type& second)
{
	Type temp;
	int i;
	int flag = 0;
	if (node->c[row][0] < node->c[row][1]) {
		temp = node->c[row][0];
		second = node->c[row][1];
	}
	else {
		temp = node->c[row][1];
		second = node->c[row][0];
	}
	for (i = 2; i < node->k; i++) {
		if (node->c[row][i] < temp) {
			second = temp;
			temp = node->c[row][i];
		}
		else if (node->c[row][i] < second)
			second = node->c[row][i];
	}

	for (i = 0; i < node->k; i++)
		if (node->c[row][i] == MAX)
			flag++;
	if (node->k == flag)
		return 0;
	return temp;
}

Type col_min(NODE* node, int col, Type& second)
{
	Type temp;
	int i;
	int flag = 0;
	if (node->c[0][col] < node->c[1][col]) {
		temp = node->c[0][col];
		second = node->c[1][col];
	}
	else {
		temp = node->c[1][col];
		second = node->c[0][col];
	}
	for (i = 2; i < node->k; i++) {
		if (node->c[i][col] < temp) {
			second = temp;
			temp = node->c[i][col];;
		}
		else if (node->c[i][col] < second)
			second = node->c[i][col];
	}

	for (i = 0; i < node->k; i++)
		if (node->c[i][col] == MAX)
			flag++;
	if (node->k == flag)
		return 0;
	return temp;
}

Type array_red(NODE* node)
{
	int i, j;
	Type temp, temp1, sum = ZERO;
	for (i = 0; i < node->k; i++) {       
		temp = row_min(node, i, temp1);  
		for (j = 0; j < node->k; j++) {
			if (node->c[i][j] == MAX)
				continue;
			node->c[i][j] -= temp;
		}
		sum += temp;                  
	}
	for (j = 0; j < node->k; j++) {        
		temp = col_min(node, j, temp1);  
		for (i = 0; i < node->k; i++) {
			if (node->c[i][j] == MAX)  
				continue;
			node->c[i][j] -= temp;
		}
		sum += temp;                 
	}
	return sum;
}

Type edge_sel(NODE* node, int& vk, int& vl)
{
	int i, j;
	Type temp, d = ZERO;
	Type* row_value = new Type[node->k];
	Type* col_value = new Type[node->k];
	for (i = 0; i < node->k; i++)                 
		row_min(node, i, row_value[i]);
	for (i = 0; i < node->k; i++)             
		col_min(node, i, col_value[i]);
	for (i = 0; i < node->k; i++) {
		for (j = 0; j < node->k; j++) {
			if (node->c[i][j] == ZERO) {
				temp = row_value[i] + col_value[j];
				if (temp > d) {             
					d = temp;
					vk = i;
					vl = j;              
				}
			}
		}
	}
	delete row_value;
	delete col_value;
	return d;
}


void del_rowcol(NODE* node, int vk, int vl)
{
	int i, j, vk1, vl1;
	for (i = vk; i < node->k - 1; i++)
		for (j = 0; j < vl; j++)
			node->c[i][j] = node->c[i + 1][j];
	for (j = vl; j < node->k - 1; j++)
		for (i = 0; i < vk; i++)
			node->c[i][j] = node->c[i][j + 1];
	for (i = vk; i < node->k - 1; i++)
		for (j = vl; j < node->k - 1; j++)
			node->c[i][j] = node->c[i + 1][j + 1];
	vk1 = node->row_init[vk];
	node->row_cur[vk1] = -1;
	for (i = vk1 + 1; i < N; i++)
		node->row_cur[i]--;
	vl1 = node->col_init[vl]; 
	node->col_cur[vl1] = -1; 
	for (i = vl1 + 1; i < N; i++) 
		node->col_cur[i]--;
	for (i = vk; i < node->k - 1; i++) {
		node->row_init[i] = node->row_init[i + 1];
	}
	for (i = vl; i < node->k - 1; i++)
		node->col_init[i] = node->col_init[i + 1];
	node->k--;
}

void edg_byp(NODE* node, int vk, int vl)
{
	int k, l;
	vk = node->row_init[vk];  
	vl = node->col_init[vl];
	node->ad[vk] = vl;    
	k = node->row_cur[vl];  
	l = node->col_cur[vk];  
	if ((k > 0) && (l >= 0)) {
		node->c[k][l] = MAX;
	}
}

NODE* initial(Type c[][N], int n)
{
	int i, j;
	NODE* node = new NODE;      
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++) {
			node->c[i][j] = c[i][j];
		}

	for (i = 0; i < n; i++) {
		node->row_init[i] = i;
		node->col_init[i] = i;
		node->row_cur[i] = i;
		node->col_cur[i] = i;
	}
	for (i = 0; i < n; i++) {
		node->ad[i] = -1;
	}
	node->k = n;
	return node;
}

void Q_insert(NODE* qbase, NODE* xnode) {
	NODE* p;
	if (qbase->next == NULL) {
		qbase->next = xnode;
		xnode->next = NULL;
	}
	else if (xnode->w < qbase->next->w) {
		xnode->next = qbase->next;
		qbase->next = xnode;
	}
	else {
		p = qbase->next;
		while (p->next) {
			if ((xnode->w > p->w) && (xnode->w < p->next->w)) {
				xnode->next = p->next;
				p->next = xnode;
				break;
			}
			p = p->next;
		}
		if (p->next == NULL) {
			p->next = xnode;
			xnode->next = NULL;
		}
	}
	p = qbase->next;

}

NODE* Q_delete(NODE* qbase) {
	NODE* p;
	p = qbase->next;
	qbase->next = p->next;
	return p;
}

template <class Type>
Type traveling_salesman(Type c[][N], int n, int ad[])
{
	int i, j, vk, vl;
	Type d, w, bound = MAX;
	NODE* xnode, * ynode, * znode, * qbase;
	qbase = new NODE;
	qbase->next = NULL;
	xnode = initial(c, n);      
	xnode->w = array_red(xnode); 
	while (xnode->k != 0) {
		d = edge_sel(xnode, vk, vl);   
		znode = new NODE;          
		*znode = *xnode;       
		znode->c[vk][vl] = MAX;	

		array_red(znode);       
		znode->w = xnode->w + d;      
		if (znode->w < bound)         
			Q_insert(qbase, znode);  
		else delete znode;        
		ynode = new NODE;          
		*ynode = *xnode;            
		edg_byp(ynode, vk, vl);     
		ynode->c[vl][vk] = MAX;
		del_rowcol(ynode, vk, vl);    

		ynode->w = array_red(ynode);
		ynode->w += xnode->w;   
		if (ynode->k == 2) {        
			if ((ynode->c[0][0] == ZERO) &&
				(ynode->c[1][1] == ZERO)) {
				ynode->ad[ynode->row_init[0]] = ynode->col_init[0];
				ynode->ad[ynode->row_init[1]] = ynode->col_init[1];
			}
			else {
				ynode->ad[ynode->row_init[0]] = ynode->col_init[1];
				ynode->ad[ynode->row_init[1]] = ynode->col_init[0];
			}                   
			ynode->k = 0;
		}
		if (ynode->w < bound) {     
			Q_insert(qbase, ynode); 
			if (ynode->k == 0)        
				bound = ynode->w;
		}
		else delete ynode;    
		xnode = Q_delete(qbase);  
	}
	w = xnode->w;             
	for (i = 0; i < n; i++) {         
		ad[i] = xnode->ad[i];
	}
	delete xnode;           
	while (qbase->next) {        
		xnode = Q_delete(qbase);
		delete xnode;
	}
	return w;          
}

void main() {
	int i, j;
	ifstream fin("1.txt");
	if (!fin) {
		cout << "cannpt open file!" << endl;
		exit(0);
	}
	for (i = 0; i < N; i++)
		for (j = 0; j < N; j++) {
			fin >> c[i][j];
		}
	fin.close();
	cout << traveling_salesman(c, N, ad) << endl;
	cout << "\t";
	for (i = 0; i < N; i++)
		cout << i << "\t";
	cout << endl;
	cout << "ad:\t";
	for (i = 0; i < N; i++)
		cout << ad[i] << "\t";
	cout << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用分支限界法求解货郎问题的伪码: ``` class City: def __init__(self, name, distance): self.name = name self.distance = distance def tsp(cities): n = len(cities) path = [0] * (n + 1) visited = [False] * n best_path = [0] * (n + 1) best_distance = float('inf') def calculate_distance(path): total_distance = 0 for i in range(n): total_distance += cities[path[i]].distance[path[i+1]] return total_distance def branch_and_bound(curr_city, curr_distance, depth): nonlocal best_distance, best_path if depth == n: curr_distance += cities[curr_city].distance[0] if curr_distance < best_distance: best_distance = curr_distance best_path = path.copy() for i in range(1, n): if not visited[i]: path[depth] = i visited[i] = True new_distance = curr_distance + cities[curr_city].distance[i] if new_distance < best_distance: branch_and_bound(i, new_distance, depth + 1) visited[i] = False branch_and_bound(0, 0, 0) return best_path, best_distance ``` 这段伪码实现了一个`City`类来表示每个城市,其中包含了城市的名称和与其他城市的距离。`tsp`函数使用分支限界法来解决货郎问题。它通过递归地在每个节点处进行分支和限界来搜索最优路径。`path`列表用于保存当前的路径,`visited`列表用于标记已经访问过的城市。`best_path`和`best_distance`分别用于保存最优路径和最小距离。`calculate_distance`函数用于计算给定路径的总距离。`branch_and_bound`函数是核心的分支限界算法实现,它通过遍历每个未访问过的城市进行分支,并在每个节点处进行限界剪枝判断。最终,函数返回最优路径和最小距离。 请注意,这只是一个简化的伪码示例,实际的实现可能需要更多的优化和边界条件处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值