SF 上机:最小重量机器设计,工作分配问题,多处最优服务次序,汽车加油,有重复元素的全排列, 租用游艇代码(改编自矩阵连乘),改写的二分搜索

最小重量机器设计 

 
/*******************************/
#include<iostream> 
#include<fstream>
#include<iomanip>
using namespace std;  

class Machineshop{ 
	friend int Machine(int **,int **,int,int,int,int []); 
	private: 
	void Backtrack(int t); 
	int **w;          //各供应商的部件的重量
	int **c;          //各供应商的部件的价格
	int *x;           //当前设计方案
	int *bestx;       //当前最优设计方案
	int cc;           //当前价格
	int cw;           //当前重量
	int bestw;        //当前最小重量
	int n;            //部件数
	int m;            //供应商数
	int d;            //价格最大预算
}; 

 void Machineshop::Backtrack(int i){//搜索第i层结点
	///
	 if(i>n){                       //到达叶结点
		 for(int j=1;j<=n;j++) 
			 bestx[j]=x[j];         //当前最优设计方案
	   bestw=cw;                    //当前最优(小)重量
	} 
	else 
		for(int j=1;j<=m;j++){ 
			x[i]=j;
			cw+=w[i][j]; 
			cc+=c[i][j];
			if(cc<=d && cw<bestw) //总价格不超过d,而且当前重量小于当前最优重量 
				Backtrack(i+1);
			cw-=w[i][j]; 
			cc-=c[i][j];
		} 
	/// 
} 

 int Machine(int **w,int **c,int n,int m,int d,int bestx[]){ 
    Machineshop X;        //初始化X
	X.x=new int[n+1]; 
	X.m=m; 
	X.n=n;
	X.d=d;
	X.w=w;
	X.c=c;
	X.cc=0;
	X.cw=0;
	X.bestx=bestx;
	X.bestw=32767; 
	for(int i=1;i<=n;i++) 
		X.x[i]=0;
	X.Backtrack(1); 
	return X.bestw; 
} 

int main(){ 
	int **w,**c,*bestx,n,m,d,i,j,f;
	ifstream inFile("input.txt");
    if(!inFile)
    {
        cerr<<"Can not open file."<<endl;   //cerr 标准错误输出流
        exit(1);
    }
    inFile>>n>>m>>d;	
    w=new int *[n+1]; 
	for(i=1;i<=n;i++) 
		w[i]=new int[m+1]; 
	for(i=1;i<=n;i++) 
		for(j=1;j<=m;j++){ 
			inFile>>w[i][j];
		} 
    c=new int *[n+1]; 
	for(i=1;i<=n;i++) 
		c[i]=new int[m+1]; 
	for(i=1;i<=n;i++) 
		for(j=1;j<=m;j++){ 
			inFile>>c[i][j];
		} 
	bestx=new int[n+1]; 
	for(i=1;i<=n;i++) 
		bestx[i]=0; 
	f=Machine(w, c, n, m, d, bestx);	
	cout<<"最佳设计方案:"<<endl; 
	for(i=1;i<=n;i++) 
		cout<<"第"<<i<<"个零件选用第"<<bestx[i]<<"个销售商"<<endl;  
	cout<<"最小重量:"<<f<<endl; 

} 

 

工作分配问题

 
/*******************************/
#include<iostream> 
#include<fstream>
#include<iomanip>
using namespace std;  

class Jobassignment{ 
	friend int Job(int **,int,int []); 
	private: 
	void Backtrack(int t); 
	int **c;          //c[i][j]为第i个工作分配给第j个工人所需的费用
	int *x;           //当前分配方案
	int *bestx;       //当前最优分配方案
	int cc;           //当前费用
	int bestc;        //当前最小总费用
	int n;            //工作数(也是工人数)
}; 
 void Swap(int &a,int &b)
 {
	 if(a!=b){
	 int temp=a;a=b;b=temp;
	 }
 }

 void Jobassignment::Backtrack(int i){//搜索第i层结点
	 if(i>n){                       //到达叶结点
		 for(int j=1;j<=n;j++) 
			 bestx[j]=x[j];         //当前最优分配方案
	   bestc=cc;                    //当前最优(小)费用
	} 
	else 
		for(int j=i;j<=n;j++){ 
			Swap(x[i],x[j]);
			cc+=c[i][x[i]];        //加上工作i分配给第x[i]个工人需要的费用
			if(cc<bestc)                 
				Backtrack(i+1);				
			cc-=c[i][x[i]];
			Swap(x[i],x[j]);
		} 
} 

 int Job(int **c,int n,int bestx[]){ 
    Jobassignment X;        //初始化X
	X.x=new int[n+1]; 
	X.n=n;
	X.c=c;
	X.cc=0;
	X.bestx=bestx;
	X.bestc=32767; 
	for(int i=1;i<=n;i++) 
		X.x[i]=i;           //初始化解向量为1,2,3,...,n
	X.Backtrack(1); 
	return X.bestc; 
} 

int main(){ 
	int **c,*bestx,n,i,j,bestc;
	ifstream inFile("input.txt");
    if(!inFile)
    {
        cerr<<"Can not open file."<<endl;   //cerr 标准错误输出流
        exit(1);
    }
    inFile>>n;	
    c=new int *[n+1]; 
	for(i=1;i<=n;i++) { 
		c[i]=new int[n+1]; 
		for(j=1;j<=n;j++)
			inFile>>c[i][j];
	} 
	bestx=new int[n+1]; 
	for(i=1;i<=n;i++) 
		bestx[i]=0; 
	bestc=Job(c, n, bestx);	
	cout<<"最佳分配方案:"<<endl; 
	for(i=1;i<=n;i++) 
		cout<<"第"<<i<<"个工作选用第"<<bestx[i]<<"个工人"<<endl;  
	cout<<"最小总费用:"<<bestc<<endl; 

} 

 

 

 

多处最优服务次序:

#include <iostream> 	
using namespace std;
float service(int *people,int n,int s) 
{ 
    int *m; 
	int temp; 
	int i,j,a,sum=0; 
	m=new int[s]; 
	for(i=0;i<n;i++){  
    	for(j=n-1;j>i;j--){ 
          if(people[j]<people[j-1]){ 
	        temp=people[j]; 
	        people[j]=people[j-1]; 
	        people[j-1]=temp; 
		  } 
		} 
	} 
	
	for(i=0;i<s;i++)m[i]=0; //初始化服务处空闲时间 
	
	for(j=0;j<n;j++){      //安排n位顾客 
	    a=0; 
	    for(i=1;i<s;i++)if(m[a]>m[i])a=i;   //找目前空闲时间最早的服务处a
    	m[a]+=people[j]; 
    	sum+=m[a]; 
	} 
   /*上面部分等价于
    a=0
	for(j=0;j<n;j++){ 
	  m[a]+=people[j]; 
	  sum+=m[a]; 
	  a++;
	  if(a==s) a=0
	}*/ //无需再查找空闲时间最早的服务处,按顺序使用即可
	return sum*1.0/n; 
	} 

    int main() 
	{ 
	int *people; 
	int n; 
	int s; 
	cout<<"请输入顾客人数:"; 
	cin>>n; 
	people=new int[n]; 
	cout<<"请输入提供服务的场地数:"; 
	cin>>s; 
	cout<<"请输入各个顾客服务的时间("<<n<<"个数):"; 
    for(int i=0;i<n;i++)cin>>people[i]; 
	cout<<"最小平均等待时间:"<<service(people,n,s)<<endl<<endl; 
	return 0;
}

 

汽车加油:

/*
汽车从初始地点出发,向目的地行进,中间有K个加油站,加满油能行驶距离为n(千米)。
从文件第一行读入n 和k的值,文件第二行是k+1段路每段的距离。求最少的加油次数。
*/
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<iomanip>
using namespace std;
int main()
{ 
    int n=0;
    int k=0;
    int distAfterRefuel=0;
    bool isRefuel=false;
    int refuelCounter=0;
    ifstream inFile1;
	inFile1.open("input.txt",ios::in);
    if(!inFile1)
    {
        cerr<<"Can not open file."<<endl;   //cerr 标准错误输出流
        exit(1);
    }

    inFile1>>n>>k;
    int * distanceArray;
    distanceArray=new int[k+1];

    if(!distanceArray)
    {
        cerr<<"malloc failed."<<endl;
        exit(1);
    }

    cout<<"每次加完油可行驶\t"<<n<<"km"<<endl;
    cout<<"加油站个数:\t"<<k<<endl;
    for(int i=0;i<k+1;i++)
    {
        inFile1>>distanceArray[i];        
		//distancearray[i]指从i站到i+1站的间距,distancearray[0]指从出发点到第1个加油站的间距
        if(distanceArray[i]>n)
        {
            cout<<"no solution!"<<endl;
            return 0;
        }
    }

	distAfterRefuel=distanceArray[0];
    for(int i=1;i<=k;i++)
    {
        if(distAfterRefuel==n||distAfterRefuel+distanceArray[i]>n)
			//油刚好用完,或油没有用完,但剩下的油不够跑到下一站,则需要在第i站加油
        {
            cout<<"  在站点"<<i<<"加油"<<endl;
            refuelCounter++;
            distAfterRefuel=0; //加油后里程重新从0计
        }
		else //可以前行到下一站
		{   cout<<"  在站点"<<i<<"不加油"<<endl;
		}
		
		distAfterRefuel+=distanceArray[i];//行驶至下一站
    }

    cout<<"总加油次数: "<<refuelCounter<<endl;
    ofstream outFile("output.txt",ios::out);
    outFile<<refuelCounter;

    delete[] distanceArray;
    return 0;
}

 有重复元素的全排列:

 

#include <iostream>
using namespace std;

template<class Type>
int ch(Type list[],int k,int i)
{
	if(i>k)
		for(int t=k;t<i;t++)
			if(list[t]==list[i])
				return 0;
	return 1;
}

template<class Type>
void perm(Type list[],int k,int m)
{
  if (k==m) 
  {
	  for (int i=0;i<=m;i++)
		  cout<<list[i]; cout<<endl;
  }
  else
  {
	  for(int i=k;i<=m;i++)
	  if(ch(list,k,i))
    {
		  swap(list[k],list[i]);
		  perm(list,k+1,m); 
		  swap(list[k],list[i]);
	  }
  }
}
template<class Type>
inline void swap(Type &a,Type &b)
{
	Type temp=a;a=b;b=temp;
}
int main()
{
	int list[3]={1,2,3};
	perm(list,0,2);
	return 0;
}

 

 租用游艇代码(改编自矩阵连乘):

#include<iostream> 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define z 4        //数组z行z列,站点个数=z-1 
using namespace std;

void Traceback(int i,int j,int**s)
{
	if(i+1==j || j==s[i][j])      //边界条件:在j站换船
	{
		cout<<"换船站"<<j<<endl;
		return;
	}
	Traceback(i,s[i][j],s);
	Traceback(s[i][j],j,s);
}
void MatrixChain(int n,int **m,int **s)
{
	for (int r = 3; r <= n; r++)            //r=2(两个站)时,m[i][i+1]的最优值就是初始值r[i][i+1],无需参与计算 
		for (int i = 1; i <= n - r+1; i++)
		{
			int j=i+r-1;                       
			for (int k = i+1; k < j; k++)   //换船位置从i+1到j-1(位置j已经在赋初值时用过了) 
			{
				int t = m[i][k] + m[k][j] ;
				if (t < m[i][j])            
				{
					m[i][j] = t; s[i][j] = k;
				}
			}
		}
		
}
void Print(int**m,int r,int c)
{ 
	for(int i=1;i<=r;i++)
	{
		for(int j=1;j<=c;j++)
		{
			if(i>j)
				cout<<"\t";   // 横向跳到下一制表位置
			else
				cout<<m[i][j]<<"\t";   
		}
		cout<<endl<<endl;
	}
}

int main()
{
    int r[z][z]=
    /* 实例1     */   //z=4时,3个站, 注意开始处设置z的值
	{{0,0,0,0},
	{0,0,5,15},
	{0,0,0,7},
	{0,0,0,0}}; 
	 /*	实例2           //z=5,4个站, 注意在开始处更改z的值
    {{0,0,0,0,0},
	{0,0,5,16,25},
	{0,0,0,10,12},
	{0,0,0,0,7},
	{0,0,0,0,0}};   */ 
	/*  实例3          //z=6,5个站, 注意在开始处更改z的值
    {{0,0,0,0,0,0},
	{0,0,5,8,10,20},
	{0,0,0,4,8,12},
	{0,0,0,0,3,6},
	{0,0,0,0,0,2},
	{0,0,0,0,0,0}};    */

	int **m = new int * [z];
	for(int i = 1; i < z; i ++)
		m[i] = new int [z];
	int **s = new int *[z];
	for(int j = 1; j < z; j ++)
		s[j] = new int [z];
		
	for(int i=1;i<z;i++)
		for(int j=1;j<z;j++)
			m[i][j]=r[i][j];     //初始化m数组,m[i][j]的初始值为租金r[i][j] 
	
	for (int i = 1; i <z; i++) 
		for(int j=1;j<z;j++)
		{
			s[i][j] = j;      //初始化s数组,初始值表示在j换船  
		}
	MatrixChain( z-1, m, s);  //求最优值 
	cout<<"最优值矩阵m:"<<endl;  
	Print(m,z-1,z-1);        //显示二维数组m                      
	cout<<"最优解矩阵s:"<<endl;   
	Print(s,z-1,z-1);        //显示二维数组s
	cout<<"最优值:m[1]["<<z-1<<"]="<<m[1][z-1]<<endl<<endl;  
	                       
	cout<<"最优换船位置:"; 
    Traceback(1,z-1,s);      //求最优解     
	cout<<endl;
	return 0;
}
 

 

 

改写的二分搜索 :

#include <iostream>
using namespace std;
template<class Type> 
int BinarySearch(Type a[ ],const Type& x,Type left,Type right,Type &i,Type &j )
{
	while (left<=right){ 
        Type mid = (left+right)/2;
        if (x == a[mid]) {i=j=mid; return 1;}
        if (x < a[mid]) right = mid-1; 
		else left = mid+1;
	}
	i=right; j=left;
	return 0;
} 
int main()
{	int a[5]={0,1,2,3,5};
	int x=3;
    int i,j,k;
	k=BinarySearch(a,x,0,4,i,j);
	if (k==1)
		cout<<"found x"<<endl;
	else
		cout<<"not found x"<<endl;
	cout<<"i="<<i<<endl;
	cout<<"j="<<j<<endl;
	return 0;
}

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值