加工生产调度(贪心)

该博客探讨了一个工厂如何通过贪心算法优化产品加工顺序,以最小化总加工时间。首先,按照A车间加工时间对产品进行排序,然后在保持B车间加工时间最短的产品在最后加工的前提下,构建加工顺序。最终,通过示例代码展示了如何实现这一策略,以确保机器空闲时间最小化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

加工生产调度(贪心)

题目描述
某工厂收到了 n 个产品的订单,这 n 个产品分别在 A、B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工。
某个产品 i 在 A,B 两车间加工的时间分别为 Ai,Bi。怎样安排这 n 个产品的加工顺序,才能使总的加工时间最短。
这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在 A,B 两车间加工完毕的时间。

输入格式
第一行仅—个数据 n ,表示产品的数量;
接下来 n 个数据是表示这 n 个产品在 A 车间加工各自所要的时间;
最后的 n 个数据是表示这 n 个产品在 B 车间加工各自所要的时间。

输出格式
第一行一个数据,表示最少的加工时间;
第二行是一种最小加工时间的加工顺序。

样例
Input Output

5
3 5 8 7 10
6 2 1 4 9
34
1 5 4 2 3

数据范围与提示
对于 100%的数据, 0<n<1000,1≤Ai,Bi≤350。
本题的 SPJ 对行尾多余空格敏感,各位输出答案时不要留行尾多余空格~

思路: 加工总用时最短,就是让机器的空闲时间最短。A车间开始就会不停地进行作业,关键是B车间在加工过程中有可能要等待A车间。很明显第一个产品在A车间上加工时,B车间必须等待,最后一个产品在B车间上加工时,A车间也在等待B车间的完工。

总结: A车间加工时间短的优先加工,B车间加工时间短的最后加工

AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int c[1100],d[1100],x[1100],y[1100];
struct pp
{
	int a,b,id;
}p[11000];
bool cmp1(pp x,pp y)
{
	return x.a<y.a;
}
int main()
{
	int n,i,j=0,k=0,sum=0;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d",&c[i]);
	for(i=0;i<n;i++)//把A机器加工时间最短的部件最先加工,
	{//把B机器加工时间最短的部件,最后加工
		scanf("%d",&d[i]);
		p[i].a=min(c[i],d[i]);
		p[i].id=i;
	}//先把一组中AB所需的最短时间存入p中,排序后,a小的从前面开始,b小的从后面开始放 
	sort(p,p+n,cmp1);
//	for(i=0;i<n;i++)
//	printf("%d  %d++\n",p[i].a,p[i].id);
	int m=n-1,mm=0;
	for(i=0;i<n;i++)
	{//printf("%d  %d----\n",p[i].a,c[p[i].id]);
		if(p[i].a==c[p[i].id])
		x[mm++]=p[i].id;
		else
		x[m--]=p[i].id;
	}
	int t=c[x[0]];
	for(i=1;i<n;i++)
	{
		if(c[x[i]]<d[x[i-1]])//如果当前a加工完,前一个b还没加工完 
		d[x[i]]=d[x[i]]+d[x[i-1]]-c[x[i]];//把没加完的时间累积到当前b上 
		t+=c[x[i]];//a一直运作 
	}//如果当前a加工完,前一个b也加工完了,超出的时间会累积在最后一个b上 
	t+=d[x[n-1]];//将累积的时间加上 
	printf("%d\n",t);
	printf("%d",x[0]+1);//我的下标是从0开始的,题的下标从1开始,故加1
	for(i=1;i<n;i++)
	printf(" %d",x[i]+1);
	return 0;
}
### 关于机器调度问题中贪心算法的应用 #### 1. 贪心算法简介 贪心算法是一种在每一步都做出局部最优选择的算法,期望通过这些局部最优解来构建全局最优解。然而,在某些情况下,这种策略可能无法获得真正的全局最优解,但可以得到一个足够好的近似解[^4]。 #### 2. 机器调度问题概述 机器调度问题是计算科学领域内一类重要的组合优化问题,涉及多个任务分配给一台或多台处理器执行的时间安排。目标通常是使总完成时间最小化或其他性能指标最大化/最小化。这类问题广泛存在于生产计划、云计算资源管理等领域。 #### 3. 使用贪心法解决单机调度问题 对于简单的单机调度场景(即只有一个处理单元),可以通过以下步骤应用贪心法则: - **输入**: 给定一组作业 `{J1, J2,..., Jn}` 和它们各自的加工时长 `p[i]`。 - **输出**: 找到一种排列顺序使得最大完工时间为最小。 采用按加工时间升序排序的方式安排工作序列是一个有效的贪心策略。这被称为 Shortest Job First (SJF) 或者 SPT 法则(Smallest Processing Time)。 ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; struct Task { int id; double duration; // 加工所需时间 }; bool compareTasks(const Task& a, const Task& b){ return a.duration < b.duration; } double calculateMakespan(vector<Task>& tasks){ sort(tasks.begin(), tasks.end(), compareTasks); double currentTime = 0; for(auto &task : tasks){ currentTime += task.duration; } return currentTime; } ``` 此代码片段展示了如何按照SPT原则对任务列表进行排序并计算总的makespan(最后一个任务结束时刻)[^4]。 #### 4. 多机环境下的扩展 当面对多台相同类型的平行机器时,情况变得更加复杂。此时可采取如下改进措施之一: - 将所有待处理的任务放入优先队列中; - 每次从未被指派的工作里挑选最早截止日期的那个交给最先空闲下来的机器去运行; 这种方法称为 EDD(Earliest Due Date first), 它同样遵循了贪心的思想模式。 另外还有 LPT(Longest Processing Time) 方法适用于特定条件下的负载均衡需求[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值