算法篇-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;
}




  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单片机与接口技术 课程设计(论文) 题目: 运动员号码显示板 院(系):信息科学与工程学院 专业班级: 学 号: 学生姓名: 指导教师: 教师职称: 起止时间: 课程设计(论文)任务及评语 院(系):信息科学与工程学院 教研室: 学 号 学生姓名 专业班级 课程设计(论文)题目 运动员号码显示板 课程设计(论文)任务 该控制器可实现球场运动员轮换指示,设计者完成控制器的硬件和软件设计。任务包括: 1运动员号码设置电路设计。 2电池稳压电路及充电电路设计。 3发光二极管点阵驱动。 4 CPU及控制电路设计。 5写出程序流程图及汇编程序。 指导教师评语及成绩 成绩: 指导教师签字: 年 月 日 目 录 第1章 课程设计目的与要求 1 1.1 课程设计目的 1 1.2 课程设计的实验环境 1 1.3 课程设计的预备知识 1 1.4 课程设计要求 1 第2章 课程设计内容 2 第3章 课程设计的考核 2 3.1 课程设计的考核要求 2 3.2 课程性质与学分 2 第4章 设计 3 4.1运动员号码设置电路设计 3 4.2 电池稳压电路及充电电路设计 3 4.3发光二极管点阵驱动 4 4.4 AT89C51 高性能8位单片 7 4.5课设总结 11 参考文献 12 课程设计目的与要求 1.1 课程设计目的 “单片机与接口技术”课程设计是在教学及实验基础上,对课程所学理论知识的深化和提高。因此,要求学生能综合应用所学知识,设计与制造出具有较复杂功能的小型单片机系统,并在实践的基本技能方面进行一次系统的训练。 能够较全面地巩固和应用“单片机”课程中所学的基本理论和基本方法,并初步掌握小型单片机系统设计的基本方法。 培养独立思考、独立收集资料、独立设计规定功能的单片机系统的能力;培养分析、总结及撰写技术报告的能力。 1.2 课程设计的实验环境 利用windows操作系统及应用软件进行绘图和编程。 1.3 课程设计的预备知识 熟悉单片机与接口技术课程的相关知识及电子线路CAD工具软件。 1.4 课程设计要求 按课程设计指导书提供的课题,根据第二章给出的基本要求及参数独立完成设计,课程设计说明书应包括以下内容: 1、对设计课题进行简要阐述,并说明设计任务及具体要求。 2、论述系统设计方案,并画出总体电路结构图及功能分割图。 3、能够较熟练地应用电子线路CAD工具完成单片机系统的硬件设计任务。 4、各功能模块设计说明、设计实现过程及源程序。 5、能够较熟练地应用一种编辑软件编写程序,掌握单片机系统软件设计的基本方法 6、课程设计报告应内容完整、字迹工整、图表整齐规范、数据详实。 7、课程设计总结 8、字数4000左右,有系统电气原理图。 课程设计内容 设 计 技 术 参 数 运动员号码选择2位显示码。 运动员号码设置采用8位拨码开关。 电源使用12V电池,充电电压来自AC220V。 数码每划50只发光二极管。 CPU采用at89c51 6、写出程序流程图及汇编程序。 工 作 量 1运动员号码设置电路设计。 2电池稳压电路及充电电路设计。 3发光二极管点阵驱动。 4 CPU及控制电路设计。 5写出程序流程图及汇编程序。 工 作 计 划 第一天 第二天 第三天 第四天 第五天 第二周 运动员号码设置电路设计。 电池稳压电路及充电电路设计。 发光二极管点阵驱动。 CPU及控制电路设计。 主程序、流程定时输出程序设计 画原理图、打印 第3章 课程设计的考核 3.1 课程设计的考核要求 课程设计采用五级(优、良、中、及格、不及格)评

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值