精华内容
下载资源
问答
  • 多项式复杂度的算法
    2020-08-09 17:30:45

    20200809_数据结构C++语言版_读书笔记14_对数多项式复杂度

    每日小知识

    【mount -o】。是用loop设备,在linux挂载本地iso文件使用的。-o就是loop回环设备。

    一、相关术语

    • logarithmic-time algorithm
      对数多项式时间复杂度的算法。

    二、相关内容

    第1章,绪论

    1.3 复杂度分析

    1.3.1 对常数O(logn)

    ■对数多项式复杂度

    一般地,凡运行时间可以表示和度量为T(n)=O(logcn)形式的这一类算法(其中常数c>0),均统称作“对数多项式复杂度的算法”(polylogarithmic-time algorithm)。

    此类算法的效率虽不如常数复杂度算法理想,但从多项式的角度仍能无限接近于后者,故也是极为高效的一类算法。

    三、看不懂的内容

    无。

    四、相关笔试题

    面试例题20:公有继承和私有继承的区别是什么?
    A、没有区别。
    B、私有继承使对象都可以继承,只是不能访问。
    C、私有继承使父类中的函数转化成私有。
    D、私有继承使对象不能被派生类的子类访问。

    **解析:**A肯定错,因为子类只能继承父类的protected和public,所以B也是错误的。
    C的描述不全面,父类可能有自己的私有方法成员,所以也是错误的。
    **答案:**D。

    本文归类

    建议归类到【数据结构】。

    明日计划

    标题:数据结构C++语言版_读书笔记15_线性O
    小知识:编译VIM。

    参考文献:

    《数据结构(C++语言版)》,第13页。

    《程序员面试手册》,第30页。

    mount -o是什么意思
    https://www.cnblogs.com/bkylee/p/5548652.html

    面试进度

    Linux视频学习进度,4.1.3与4.1.4,文件处理,touch,cp -r。

    更多相关内容
  • 多项式复杂度有弱多项式和强多项式两种,弱多项式就是关于输入长度( nnn、 mmm 之类的,以及 log值域log 值域log值域)为多项式复杂度,强多项式就是在加减乘除为 O(1)O(1)O(1) 时复杂度关于数据规模为多项式(就是

    前言

    Ouuan Orz

    当然,先说一下弱多项式是啥?

    OI 界中叫做 Dinic 和 EK 的那两个最大流算法,把其中的 BFS 改成求最短路,复杂度都是与值域多项式相关的,即复杂度是伪多项式的。

    多项式复杂度有弱多项式和强多项式两种,弱多项式就是关于输入长度( n n n m m m 之类的,以及 l o g 值 域 log 值域 log)为多项式复杂度,强多项式就是在加减乘除为 O ( 1 ) O(1) O(1) 时复杂度关于数据规模为多项式(就是说跟值域完全无关,只和 n , m n, m n,m 之类的相关,复杂度关于 n , m n, m n,m 之类的为多项式)。

    当然,这时 O u u a n Ouuan Ouuan说的。

    算法讲解

    要求

    1. s t st st无入边, e d ed ed无出边。
    2. 可以有负环。

    无源汇最小费用流

    对于有源汇最小费用最大流的定义我们改一下:

    没有 s t st st e d ed ed,同时最小化 ∑ ( i , j ) ∈ E c o s t ( i , j ) ∗ f ( i , j ) \sum\limits_{(i,j)∈E}cost(i,j)*f(i,j) (i,j)Ecost(i,j)f(i,j)

    当然,这个时候你可能会好奇这个我们讲的有源汇最小费用最大流有个 d e r der der的关系?

    那如果我们从 e d ed ed s t st st连接一条无限小的边,使得流量越多越好,然后后面减掉就行了。

    做法

    首先,这个流是最小费用当且仅当图中不存在负环,证明和上篇重制版最小费用最大流博客雷同,不予以赘述。

    首先明白一个定理:如果把每条边容量乘 2 2 2,则对应流量乘 2 2 2,最小费用乘 2 2 2,因为乘 2 2 2一定不存在负环。

    那么接下来就非常简单了,把边权拆成二进制,维护残余网络 G G G,一开始 G G G中的容量和流量都为 0 0 0,然后二进制从高到低扫描,每一位把所有边的容量和流量乘 2 2 2,但是需要注意,有些边这一位二进制可能为 1 1 1,因此这条边会加入到残余网络中,这就非常的蛋疼了,好的方法是这条边是 ( x , y ) (x,y) (x,y),在加入前从 y y y跑一遍最短路,如果 d [ x ] + c o s t ( x , y ) < 0 d[x]+cost(x,y)<0 d[x]+cost(x,y)<0,那么就不加入,并且把 y y y x x x的最短路的流量全部减一,当然,如果这条边原本就存在,则直接流量 + 1 +1 +1即可。

    至于为什么直接跑最短路即可,因为我们维护的残余网络中一定没有负环啊。

    时间复杂度: O ( n m 2 log ⁡ U ) O(nm^2\log{U}) O(nm2logU) U U U是边中的最大流量。

    例题:https://uoj.ac/problem/487

    #include<cstdio>
    #include<cstring>
    #define  N  5100
    #define  M  110000
    using  namespace  std;
    typedef  long  long  LL;
    template<class  T>
    inline  T  mymin(T  x,T  y){return  x<y?x:y;}
    template<class  T>
    inline  T  mymax(T  x,T  y){return  x>y?x:y;}
    int  n,m;
    struct  node
    {
    	int  x,y,next;
    	LL  c/*表示它们现在现有的流量*/,d;
    }a[M];int  len=1,last[N];
    LL  cap[N];//表示它们原本的流量 
    inline  void  ins_node(int  x,int  y,LL  c,LL  d){len++;a[len].x=x;a[len].y=y;a[len].d=d;cap[len]=c;a[len].next=last[x];last[x]=len;}
    inline  void  ins(int  x,int  y,LL  c,LL  d){ins_node(x,y,c,d);ins_node(y,x,0,-d);}
    //SPFA
    LL  d[N];
    int  list[N],head,tail,pre[N];
    bool  v[N],vv[N];
    void  spfa(int  st,int  ed)
    {
    	list[head=1]=st;tail=2;
    	memset(d,20,sizeof(d));d[st]=0;
    	memset(pre,0,sizeof(pre));
    	memset(v,0,sizeof(v));v[st]=1;
    	while(head!=tail)
    	{
    		int  x=list[head++];if(head==n+1)head=1;
    		v[x]=0;
    		for(int  k=last[x];k;k=a[k].next)
    		{
    			int  y=a[k].y;
    			if(a[k].c>0  &&  d[y]>d[x]+a[k].d)
    			{
    				d[y]=d[x]+a[k].d;
    				pre[y]=k;
    				if(!v[y])
    				{
    					v[y]=1;
    					list[tail++]=y;
    					if(tail==n+1)tail=1;
    				}
    			}
    		}
    	}
    }
    LL  cost=0,ans=0,ffuck=0;
    void  trash(int  st,int  ed)
    {
    	LL  mmax=0/*,sum=0用来记录st-ed添加的那一条边应该是多少*/,summ=0;
    	for(int  i=2;i<=len;i++)
    	{
    //		if(a[i].d>0)sum+=a[i].d;
    		summ+=cap[i];
    		mmax=mymax(mmax,cap[i]);
    	}
    	ins(ed,st,summ,-(LL)999999999);
    	mmax=mymax(mmax,cap[len-1]);
    	int  l=1;
    	while(((LL)1<<l)-1<mmax)l++;
    	
    	for(int  ll=l;ll>=1;ll--)//从高位到低位开始扫描二进制 
    	{
    		cost<<=1;
    		LL  shit=((LL)1<<(ll-1));
    		memset(vv,0,sizeof(vv));
    		for(int  i=2;i<=len;i++)
    		{
    			a[i].c<<=1;
    			if(a[i].c)a[i].c+=(cap[i]&shit)>0,vv[i]=1;
    		}
    		//对于所有已经存在的边不用扫描 
    		for(int  i=2;i<=len;i++)
    		{
    			if(vv[i])continue;
    			if(cap[i]&shit)//反向边绝对不会进来 
    			{
    				int  x=a[i].x,y=a[i].y;
    				spfa(y,x);
    				if(d[x]+a[i].d<0/*负环!!!!*/)
    				{
    					cost+=a[i].d;
    					x=pre[x];
    					while(x)
    					{
    						cost+=a[x].d;
    						a[x].c--;a[x^1].c++;
    						x=pre[a[x].x];
    					}
    					a[i^1].c++;
    				}
    				else  a[i].c++;
    			}
    		}
    	}
    	for(int  k=last[st];k;k=a[k].next)
    	{
    		if(!(k&1))ans+=cap[k]-a[k].c;
    	}
    	printf("%lld %lld\n",ans,cost-(cap[len-1]-a[len-1].c)*a[len-1].d+ffuck);
    }
    int  main()
    {
    	int  st,ed;
    	scanf("%d%d%d%d",&n,&m,&st,&ed);
    	for(int  i=1;i<=m;i++)
    	{
    		int  x,y;LL  c,d;scanf("%d%d%lld%lld",&x,&y,&c,&d);
    		if(x==y)
    		{
    			if(d<0)ffuck+=c*d;//自环 
    		}
    		else  ins(x,y,c,d);
    	}
    	trash(st,ed);
    	return  0;
    }
    

    细节

    无限小?

    边权?

    总结

    放心,因为比赛一般都是构图题,难以卡掉 Z K W ZKW ZKW E K EK EK,所以,大胆的,放心的用 Z K W ZKW ZKW吧,学这个算法就图一乐。

    参考资料

    洛谷的讨论

    弱多项式复杂度算法非常非常好的常考资料,真的非常非常好

    要准备NOIP啦,赛后补充Dij的做法,还有亿点细节补充。

    代码也要补点注释。

    赛前还是直接打个简单思路就去准备比赛了。

    展开全文
  • 这是最近一篇的关于多项式复杂度的笔记嘞~大家也在疫情期间加油学习!!! #9.3.5 Multinomial fitness complexity(多项式复杂度) #subset,子集;intersect,相交 def isSubset(L1, L2): 假定L1和L2是列表 如果...
  • PTAS 针对periodic任务,在每个核上采用EDF调度,是一种可以以 误差接近理论最优的实时任务分配算法,其中 是一个我们人为指定的常数,最牛逼的是,该算法在运行时可以以多项式复杂度时间得到以为误差的最优分配结果...

    PTAS 是针对多核分区调度的,最初的那篇论文,是提出了一个分配思想,而没有指定分区调度中具体是采用固定优先级调度和动态优先级比如EDF调度。然后后面一个论文就将其具体化,且高效实现了,该文章的算法过程如下。

    针对periodic任务,在每个核上采用EDF调度,是一种可以以 \varepsilon 误差接近理论最优的实时任务分配算法,其中 \varepsilon 是一个我们人为指定的常数,最牛逼的是,该算法在运行时可以以多项式复杂度时间得到以\varepsilon 为误差的最优分配结果。该论文理解起来还是很有难度的。该方法的实现过程如下:首先指定\varepsilon(下面我们的分析用字母e代替了),然后穷举法生成所有可行的分配表(2的n次方这样的指数时间复杂度),然后运行时(比如实时操作系统正在运行了)查找匹配该分配表,从而得到分配结果。

    详细过程如下:

    1.  离散化利用率0-1的所有到区间:(e/(1+e), e],(e, e(1+e)],(e, e(1+e)^2],.....。然后所有利用率点ui都会取所在区间的右端点值,也就是round up(或者叫做modified)。这样之后可能存在的利用率点仅为:e,e(1+e),e(1+e)^2,......。总共有多少个利用率点呢,这个可以算的,我们记为|V(e)|。我们会发现后一个利用率值除以前一个都等于(1+e),而且利用点的个数和人为指定的常数e都是有关系的,所以叫做人为指定误差嘛。很明显,如果是单核,能容纳的最多任务为1/e个了。
    2. 这样我们就可以把一个任务集n个任务的利用率分配情况给穷举出来了。
      比如e=0.4(我们计算出只有3个利用率点,0.4, 0.56, 0.784,因此|V(e)|=3)。那么对于每个核,我们都能穷举出所有可能的利用率存在方式,表示为有序对(下面会介绍),比如<2,0,0>,<1,1,0>,<0,0,1>,<0,1,0>,其中<2,0,0>表示0.4利用率处可以有2个0.4利用率,但是0.56处和0.784处都不能有该点利用率的任务了,因为加起来大于1了,就不可调度了。这些合法有序对为,<2,0,0>,<1,1,0>,<1,1,0>,<0,0,1>,<0,1,0> ,其中<1,0,0>这个就叫做非最大有序对(或者说非饱和),因为该有序对再加入一个0.4利用的任务,照样还是可调度的。所以最大有序对意思是再加入一个e利用率的任务,就不可调度了。处理器只有一个核的情况,最大有序对表述为( 构造的时间复杂度为1/e为指数的 )
      L1(e)={ <2,0,0>,<1,1,0>,<0,0,1>,<0,1,0> },用z1表示某个有序对的编号,也叫ID
      多核情况下,每个核都用这个表示即可,因为是同构多核。


      用户给定输入3个任务,它们的利用率{0.3,0.35,0.55},利用率转换(叫做modified)后为{0.4,0.4,0.56},表示为下面要说的有序对,就是<2,1,0>(这个是输入的),该任务集在两个核上的分配,就会有很多种情况,其中可行的分配方式只有下面2种而已(每个核上利用率小于1该核即可调度)。因此我们可以用一个有序对来表示分配结果<x1,x2,...,xi,...,x|V(e)|>,这里的|V(e)|是作为x的下标。xi表示分配在e(1+e)^i这个利用率点的任务数。这个例子中,分配方法1,对于核1,就是<2,0,0>,对于核2,就是<0,1,0>。分配方法2,对于核1,就是<1,1,0>,对于核2,就是<1,0,0>。


      如果是2个核,最大化该如何表述呢,首先肯定是针对一个目标有序对<y1,y2,...y|V(e)|>,此时该有序对就是这2个核所能容纳下的最大利用率了,任意添加一个小的e利用率进去,都会导致分配失败(构造这样,时间复杂度|L1(e)|^m)。那么很明显,这个最大化的有序对,分配在两个核上,每个核也处于最饱和状态了,即每个核的最大有序对里挑出来一个呗,那上面的z1就是核1上挑出来的有序对的编号,z2,就是核2上挑出来的有序对的编号。因此形式化表述为:
      (<y1,y2,...,y|V(e)|>),<z1,z2,...,zm>),m为核数。

      Lm(e)={ (<y1,y2,...,y|V(e)|>),<z1,z2,...,zm>),(<y1’,y2’,...,y‘|V(e)|>),<z1’,z2‘,...,zm’>),......, }。  构建的查找表


      上面例子表述为:
      L2(e)={(<4,0,0>),<1,1>),(<3,1,0>),<1,2>),(<3,0,1>),<1,3>)},这个就是PTAS算法在运行前预处理时构建的查找表

      上面的意思是,假如对于<4,0,0>这个是round up后的目标任务集,表示有4个0.4利用率的任务,那这个有序对为什么是2核处理器中最大有序对呢,因为你随便再给一个利用率(0.4,0.56.0.784这几个随便给一个),都会分配失败。这个分配结果就是每个核都在0.4那儿分配两个就行了,也就是核1:<2,0,0>,核2也是:<2,0,0>,查询上面L1(e)的表达式可知,编号都是1的有序对,因此表示为<z1,z2>为<1,1>。同理(<3,1,0>),<1,2>)也是这么得来的。

      我们会发现这样一个性质,就是待分配最大化有序对的每个分量成员,就是每个核最大化有序对对应分量求和需要相等,比如(<4,0,0>),<1,1>)中的4,在核1中是2,核2中也是2,加起来就是4了。那么如果现在用户给一个任务集,表示为了<3,0,0>有序对,问我们能不能分配成功,当然可以,因为我们能找到预处理时候上面构造的查找表,和查找表中的<4,0,0>相匹配,发现每个分量只要小于等于查找表中的<4,0,0>的每个分量,则该<3,0,0>有序对就可以分配成功,就用对应的<1,1>这个分配方式即可,即核1分配两个0.4利用率的任务,核2就只分配剩下的一个就行了(虽然最饱满的情况是可以分2个0.4的)
    3. 终于解释完了上面的最大有序对,其实分配的过程就是,预先建立好查找表Lookup table,从上面直到为1/e为指数的时间复杂度的,但是没关系,这个是系统运行前预处理阶段完成的,然后运行阶段,任意给一个任务集,只需要进行round up修改为有序对,然后和查找表中的进行匹配(就是每个分量都小于查找表中某个有序对即可,这个匹配过程多项式时间复杂度的),然后就能知道分配成功或者失败了,成功也能知道具体如何分配核的了。
      真正的运行时阶段,就是多项式时间复杂度而已,这就PTAS分配算法名字的由来。

      (当然PTAS算法还考虑了有些任务利用率小于e/(1+e)的情况,这个最后分配即可,看看哪个核能放下就分配即可)

       

    总结: PTAS分配算法确实做到了多项式时间复杂度的可指定精度(和理论最优分配算法的差距)的分配,但是该算法构建查找表因为还是有点复杂(不吃透这个算法原理就没法弄),而查找表会占用很多的内存空间,因此该算法实际系统中用到的不多,但是这个方法很有启发意义,空间换时间。实际实时系统中用得较多的是启发式分配算法(虽然不能最优,但是可以很接近最优,而且实现简单,不需要占什么内存,时间复杂度也低,而且还有个重要的点:PTAS不能适应任务动态加入的情况,而启发式算法(也叫近似算法)则可以比如FF),比如FF,NF,WF,BF等,下个博客就讲解这几个算法。

    多核实时调度—任务分配启发式算法解读_标biao的博客-CSDN博客

    展开全文
  • 如题。 最大生成DAG可以简单理解为对于一张有向图,去掉一些边,使其变成有向无环图,最小化去掉的边的边权和。
  • 多项式复杂度

    千次阅读 2014-09-06 10:37:49
    上篇的标记算法中,谈到这个O(K)的算法是一个指数级复杂度算法,其实对那道题目本身来说,K是固定的,既然不是输入,那也无所谓复杂度,之所以有O(K)这种说法,是把K当做一种输入了,这是看待输入的角度问题,倒...
  • 多项式时间算法

    千次阅读 2020-03-29 21:30:35
    时间复杂度并不是表示一个程序解决问题需要花多少时间,而是当问题规模扩大后,程序需要的时间长度增长得有多快。 也就是说,对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的好坏,而...
  • 多项式的时间复杂度

    千次阅读 2016-12-25 12:33:25
  • 算法常见复杂度分析

    2020-04-16 15:00:11
    算法(algorithm) 是指用来操作...时间维度:算法执行所消耗的时间,即时间复杂度 空间维度:算法执行所消耗的内存,即空间复杂度 一、大O时间复杂度分析法 1> 概念:并不表示代码真正执行花费的时间,而是表示...
  • 多项式时间复杂度及NP问题

    千次阅读 2014-11-06 10:24:45
    O(a^n)和O(n!)型复杂度,它是非多项式级的。与非多项式时间复杂度相关的问题叫:非确定性多项式(non-deterministic ...NPC:非确定性多项式完全问题则是一类目前大家认为没有多项式算法去解决的问题,是NP问题中
  • 算法中七种常见的时间复杂度

    万次阅读 多人点赞 2020-09-17 17:11:17
    O(1) — 常数复杂度 O(log n) — 对数复杂度 O(n) — 线性复杂度 O(n log n) — 对数线性复杂度 O(nᵏ) — 多项式复杂度 O(kⁿ) — 指数复杂度 O(n!) — 阶乘复杂度 下图描绘了各种复杂度的算法中,当输入规模增长...
  • 降低GFDM峰均功率比的低复杂度算法.docx
  • 1.多项式时间复杂度 定义: 解决问题需要的时间与问题的规模之间是多项式关系。 多项式关系形如O(n^k)O(n^k),k为某个常数,n是问题的输入规模。例如,时间复杂度为O(nlog(n))、O(n^3)都是多项式时间复杂度。...
  • BM算法,用于计算序列的线性复杂度及其反馈多项式。使用JAVA实现
  • 什么是伪多项式时间算法

    千次阅读 2020-04-02 09:54:43
    首先一定要搞清楚下面的定义。 “输入规模”:一个问题的输入规模是保存输入数据所需要的bit位数。 (不理解“伪多项式时间”,可能很大程度上是由于对...伪多项式时间算法算法的时间复杂度是输入数据大小的多项式...
  • 多项式(时间)算法

    千次阅读 2019-04-16 22:06:29
    在计算理论领域中,若一个数值算法的实践复杂度可以表示为输入数值N的多项式,则称其时间复杂度为伪多项式时间。由于N的值是N的位数的幂,故该算法的时间复杂度实际上应视为输入数值N的位数的幂。 伪多项式(时间)...
  • 子集和。近似算法能够获得近似值和近似解,并且是一种完全多项式时间近似方案。 包括指数时间算法、修整算法、近似算法,可以获得近似值和近似解
  • 复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?为什么需要复杂度分析?大O复杂度表示法;时间复杂度分析;几种常见时间复杂度空间复杂度分析;复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度。 ...
  • 机器学习之多项式回归算法(Polynomial Regression).很多场合线性模型无法很好的拟合目标数据曲线,这就需要引入非线性回归模型。对于非线性回归存在多种策略,第一种策略是将非线性回归转化成线性回归;第二种策略是...
  • 关于求解线性序列的极小多项式和线性复杂度的BM算法实操理解 在流密码中,线性反馈移位寄存器(LFSR)是非常重要部件。学过线性移位寄存器序列相关知识的朋友都知道,Berlekamp-Massey算法(以下简称BM算法)是求解序列...
  • 1.多项式时间复杂度定义:问题需要的时间(复杂度)与问题的规模之间是多项式关系。例如,多项式关系形如O(nk)O(n^k),k为某个常数,n是问题的输入规模。例如,时间复杂度为O(nlog(n))、O(n^3)都是多项式时间复杂度...
  • 多项式时间复杂度指的是解决问题需要的时间与问题的规模之间是多项式关系。 多项式关系形如,k为某个常数,n是问题的输入规模(例如n个未知数)。例如,时间复杂度为O(nlog(n))、O(n3)O(nlog(n))、O(n^3)O(nlog(n))、...
  • 基于工作流的Petri网结构化建模方法,证明了工作流</div><div>网的T一不变量和P一不...与以往非多项式分解算法相比,克</div><div>服了遍历的不足,降低了算法复杂度,给出的实例验证了算</div><div>法的有效性.</div>
  • 时间复杂度 定性描述了算法的运行时间。(并不是表示解决一个问题花了多少时间,而是描述问题规模扩大与算法运行时间增加的关系) 常见的时间复杂度有: 常数时间O(1),如访问数组中的单个元素; 对数时间O(log n...
  • 什么是多项式算法、非多项式算法

    千次阅读 2016-04-15 21:58:00
    一种是O(1),O(log(n)),O(n^a)等,我们把它叫做多项式级的时间复杂度,因为它的规模n出现在底数的位置;另一种是O(a^n)和O(n!)型复杂度,它是非多项式级的,其...判定是否是多项式算法和非多项式算法就是看时间复杂度
  • 第三章 表、栈和队列 3.6 编写两个多项式相加的函数 时间复杂度为O(M+N) 【数据结构与算法分析】学习笔记课后答案第三章3.6 3.7多项式加法乘法不同时间复杂度

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,739
精华内容 9,095
关键字:

多项式复杂度的算法

友情链接: scsw.rar