算法篇-12-分支限界-限定价格内最小重量机器设计&运动员最佳组队

本系列所有代码https://github.com/YIWANFENG/Algorithm-github

限定价格内最小重量机器设计

题目:

一个机器,由n个部件组成,每个部件都可从m各不同的供应厂商处购得,设w[i][j]是从j处购得部件i的重量,c[i][j]是价格。给出总价格不超过d的最小重量机器设计。

算法分析与相关公式:

既然要最小重量,我们就选中以当前购物方案E的总重量w作为优先级。

其中当前E还应包含c(当前花费),以避免花费超界,既可以在此设置限界函数。当然还应有一个level保存当前方案已经选购到了第几个部件。在搜索中很明显,若当前优先队列头上的元素的level超过n,即可视为找到一最优解,应退出搜索。

在程序一开始先选购第一个,然后把所有选择他的方案求出,若方案超费,不入优先队列。

选完一节点后从优先队列中选取头部继如此过程即可。

#include <iostream>
#include <queue>
#include <vector> 

//限定价格内最小重量机器设计 - 分支限界
 
using namespace std;

class Node{
public:
	int *x;	//结果 
	int w;
	int c;
	int level;
	bool operator<(const Node & a)  const
	{
		return w<a.w;
	}
};

class Machine
{
private:
	int n;			//n个部件 
	int m;			//m个供应商 
	int *weight;	//weight[i][j]相应重量 
	int *cost;		//cost[i][j]相应价格 
	int d;			//总价格 
	
	
public:
	int Solve(int n_,int m_,int *w_,int *c_,int d_,int *result)
	{
		n = n_;  
		m = m_;
		weight = w_;
		cost = c_;
		d = d_;
		priority_queue<Node> q;
		Node E;
		E.c = 0;
		E.w = 0;
		E.level = -1;
		E.x = new int[n];
		
		while(E.level+1<n)  {
			for(int i=0;i<m;++i) {
				//确保不超价格 
				if(E.c+cost[(E.level+1)*m+i]<=d) {
					Node N;
					N.c = E.c+cost[(E.level+1)*m+i];
					N.w = E.w+weight[(E.level+1)*m+i];
					N.level = E.level+1;
					N.x = new int[n];
					for(int j=0;j<=E.level;++j) {
						N.x[j] = E.x[j];
					}
					N.x[E.level+1] = i;
					q.push(N);	
				}
			}
			delete []E.x;
			if(q.empty()) break;
			E = q.top();
			q.pop();
		}
		if(E.x == NULL) return -1;
		for(int i=0;i<n;++i) {
			result[i] = E.x[i];
		}
		delete []E.x;
		while(!q.empty()) {
			E = q.top();
			delete [] E.x;
			q.pop();
		}
		return E.w;
	}

};



int main()
{
	int n=3,m=3,d=4;
	int c[] = {1,2,3,3,2,1,2,2,2};
	int w[] = {1,2,3,3,2,1,2,2,2};
	int *result = new int[n];
	Machine ma;
	cout<<"BestW:"<<ma.Solve(n,m,w,c,d,result)<<endl;
	for(int i=0;i<n;++i) {
		cout<<result[i]<<' ';
	}
	delete [] result;	
	cin.get();
	return 0;
}


运动员最佳组队

题目:

 羽毛球队有男女运动员各n人。给定n×n矩阵PQP[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势;Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势。由于技术配合和心理状态等各种因素影响,P[i][j]不一定等于Q[j][i]。男运动员i和女运动员j配对组成混合双打的男女双方竞赛优势为P[i][j]*Q[j][i]。设计一个算法,计算男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大。

算法分析与相关公式:

此题求解类似限定价格内最小重量机器设计,不同之处在于此题解空间为排列树。

在这里我们选择的是

int level; //level号男运动员

int c; //目前安排能力加成

int *x; //人员安排方式 

在每一次搜索扩展时,level之前的运动员已经安排好了,所以只需要安排level之后的即可。

在这我并没有添加限界函数。

#include <iostream>
#include <queue>
#include <vector> 

//  运动员最佳组队 - 分支限界
 
using namespace std;

class Node {
public:
	int level;		//第level号男运动员
	int c;			//目前安排能力加成
	int *x;			//人员安排方式 
	bool operator <(const Node &a) const 
	{
		return this->c < a.c; 
	}
}; 
void Swap(int &a,int &b)
{
	if(a==b) return;
	int c =a;
	a = b;
	b = c;
}

class Organize
{
private:
	int n;		//n男n女 
	int *P;		//p[i][j] 是男i与女j一起时的能力加成 
	int *Q;		//Q[i][j] 是女i与男j一起时的能力加成
	int bestc;
	
public:	
	int Solve(int n_,int *p_,int *q_,int *result)
	{
		n = n_;
		Q = q_;
		P = p_;
		Node E;
		E.c = 0;
		E.level = 0;
		E.x = new int[n];
		for(int i=0;i<n;++i) E.x[i] = i;
		priority_queue<Node> qq;
		bestc = 0;
		while(E.level<=n) {
			//产生当前节点的扩展节点 
			if(E.level == n) {
				if(E.c>bestc) {
					bestc = E.c;
					for(int i=0;i<n;++i) {
						result[i]=E.x[i];
						//if(E.c == 55)
						//cout<<result[i]<<endl;
					}
					delete [] E.x;
				}
			}
			else {
				for(int i=E.level;i<n;++i) {
					Swap(E.x[E.level],E.x[i]);
					Node N;
					N.c = E.c + P[E.level*n+E.x[E.level]] * Q[E.x[E.level]*n+E.level];
					N.level = E.level+1;
					N.x = new int[n];
					for(int j=0;j<n;++j) N.x[j] = E.x[j];
					qq.push(N);
					Swap(E.x[E.level],E.x[i]);
				}
				delete [] E.x;
			}
			if(qq.empty()) break;
			E= qq.top() ; 
			qq.pop();
		}
		while(!qq.empty()) {
			E = qq.top();
			delete [] E.x;
			qq.pop();
		}
		return bestc;
	}
};

int main()
{
	int n = 3;
	int p[] = {10,2,3,2,3,4,3,4,5};
	int q[] = {2,2,2,3,5,3,4,5,1};
	int *result = new int [n];
	
	Organize org;
	cout<<"Best:"<<org.Solve(n,p,q,result)<<endl;
	
	
	for(int i=0;i<n;++i) 
	cout<<result[i]<<' ';
	cin.get();
	delete [] result;
	return 0;
}




猜你喜欢

转载自blog.csdn.net/hffhjh111/article/details/53907420