瞬间求解最大连续和

本文探讨了求解一组整数数据中最大连续和的算法,从最极品的算法到较低效的方法进行了排序和解释。包括递归、前缀和、双层循环等策略,旨在提高计算效率。

已知一组整数数据 A1,A2,A3,A4,A5,A6.....AN ,并返回最大连续和。

先给出最极品的算法:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int maxn=10000;

int A[maxn],S[maxn];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
	int n;
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++) scanf("%d",&A[i]);
	S[0]=A[0];
	//printf("S[0]=%d\n",S[0]);
	int best=A[0],tot=0;
	for(i=1;i<n;i++) //计算前缀和 
	{
		tot++;
		S[i]=S[i-1]+A[i];
	}
	int min_S=0;//保存当前遇到的最小S,当min_S=S[0]或其他的,都不对。 
	for(int j=1;j<n;j++)
	{
		best>?=S[j]-min_S;//A[i]+……+A[j]=S[j]-S[i-1],当j确定时,减去之前遇到的最小s即可 
		min_S<?=S[j];//维护最小的s 
	}
	printf("min_S=%d\n",min_S);
  	printf("n=%d tot=%d\n",n,tot);
  	printf("%d\n",best);
    return 0;
}

剩下的由高效到低效排序如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int maxn=10000;

int A[maxn],tot;

int maxsum(int *A,int x,int y)//在[x,y)左闭右开区间中求最大连续和 
{
	if(y-x==1) return A[x];//没有这句不行,递归程序会一直运行下去。写递归函数,注意递归边界。 
	int m=x+(y-x)/2;//求靠近0的中点 
	int max=maxsum(A,x,m)>?maxsum(A,m,y);//求解子问题 
	int i,v,L,R;
	L=A[m-1];v=0;
	for(i=m-1;i>=x;i--) L>?= v+=A[i];//由划分处向左边求最大连续和 
	tot+=(m-x);// 记录加法操作数目 
	R=A[m];v=0;
	for(i=m;i<y;i++) R>?= v+=A[i];//由划分处向右边求最大连续和  
	tot+=(y-m);
	return max>?L+R;//合并问题 
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
	int n;
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++) scanf("%d",&A[i]);
	tot=0;
	int best=maxsum(A,0,n);//直接调用求解[0,n)的最大连续和 
  	printf("n=%d tot=%d\n",n,tot);
  	printf("%d\n",best);
    return 0;
}

O(n2):

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int maxn=10000;

int A[maxn],S[maxn];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
	int n;
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++) scanf("%d",&A[i]);
	S[0]=A[0];
	int best=A[0],tot=0;
	for(i=1;i<n;i++) 
	{
		tot++;
		S[i]=S[i-1]+A[i];
	}
	for(i=0;i<n;i++)
	  for(int j=i;j<n;j++) 
	  {
 		 tot++;
  		 best>?=S[j]-S[i-1];
  	}
  	printf("n=%d tot=%d\n",n,tot);
  	printf("%d\n",best);
    return 0;
}

O(n*n*n):

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int maxn=30;

int A[maxn];
int main()
{
#ifndef ONLINE_JUDGE
    //freopen("in.txt","r",stdin);
#endif
	int n;
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++) scanf("%d",&A[i]);
	int best=A[0],tot=0;
	for(i=0;i<n;i++)
	  for(int j=i;j<n;j++)
	  {
	  	 int sum=0;
  		 for(int k=i;k<=j;k++) 
  		 {
 		  	sum+=A[k];
 		  	tot++;
	  	 }
  		 best>?=sum;
  	}
  	printf("n=%d tot=%d\n",n,tot);
  	printf("%d\n",best);
  	printf("Time used=%.2lf\n",(double)clock()/CLOCKS_PER_SEC);	
    return 0;
}

### 使用NSGA-II算法解决柔性作业车间调度问题 #### 1. 算法概述 NSGA-II (Non-dominated Sorting Genetic Algorithm II) 是一种高效的多目标进化算法,广泛应用于各种复杂的优化问题中。该算法通过非支配排序拥挤距离计算来保持种群多样性并找到帕累托最优解集。 对于柔性作业车间调度问题(Flexible Job Shop Scheduling Problem, FJSP),其主要特点是每道工序可以在多个候选机床上执行,并且不同机床处理同一工序的时间可能不同。因此,在设计适应度函数时需考虑两个重要指标:总加工时长(makespan)以及机器负荷平衡程度[^1]。 #### 2. 编码方式 为了表示一个完整的解决方案,通常采用两种编码方法相结合的方式: - **操作序列编码**:记录各工件的操作顺序; - **机床分配编码**:指定每个操作所使用的具体机床编号。 这两种信息共同构成了染色体结构,作为遗传算法中的个体表示形式。 #### 3. 初始化种群 随机生成一组满足约束条件的初始方案集合,即构成第一代种群P₀。这里需要注意的是要确保每一个成员都是可行解,也就是说不会违反任何给定的任务前置关系或其他限制因素。 #### 4. 遗传算子定义 针对上述双层编码机制分别实现交叉与变异运算规则: - 对于操作序列部分,可以借鉴单点/两点交换、插入等经典策略; - 关于机床指派,则可通过局部调整或全局重置来进行扰动变化。 这些操作有助于探索更多潜在优质区域内的可能性分布状况。 #### 5. 计算适应度值 根据设定的目标函数评估当前群体内各个体的表现优劣程度。在此场景下,重点考察以下两项性能参数: - `C_max` :整个系统的完成时刻,也就是最后一个被安排任务结束后的瞬间; - 平均负载率或者最大负载差异,用来衡量设备间工作量均衡性的好坏。 这两个维度相互制约又彼此关联,故而形成了典型的多目标寻优框架[^2]。 #### 6. 构建下一代种群Q₁ 利用快速非支配分层技术对父辈P₀实施分类整理;接着按照既定比例选取优秀样本进入临时存储池S;再从剩余对象里挑选若干补充至其中直至达到预定规模n为止;最后将两者混合重组得到新世代Q₁。 #### 7. 终止准则判定 当迭代次数到达预设阈值Tmax 或者连续几轮未见显著改善迹象时停止循环过程,输出最终获得的最佳前沿面近似结果。 ```matlab function Result = NSGA2(MachineNum, jobNum, jobInfo, operaNumVec, candidateMachine) % 参数初始化... while not(terminationCriterionMet()) % 执行一轮标准流程... % 更新统计信息... end % 返回最优解集及其对应属性向量. end ``` #### 8. 结果可视化展示 绘制三维散点图用于直观呈现所得Pareto Front特性曲线走势特征。横轴代表最大完工时间,纵轴反映机器的最大负荷水平,Z轴则体现总体负担累积总量的变化趋势。 ```matlab figure(1); scatter3(Result.obj_matrix(:,1), Result.obj_matrix(:,2), Result.obj_matrix(:,3), ... 150,'rp','filled'); xlabel('最大完工时间'); ylabel('机器最大负荷'); zlabel('总机器负荷', 'Rotation', 90); legend('NSGA2'); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值