\\ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\\强连通有向图\\作者:安德鲁·霍罗伊德,2022年1月\\ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\\如果打算计算几个以上的项,那么就给PARI更多的内存!\\这可以用“default”完成。例如:\\默认值(parisizemax,10^9)\\简介\\ ------------\\Liskovets首先列举了强图。此处使用的方法\\包括莱特和罗宾逊的重大(巧妙)改进\\(和/或阅读)。[警告:这不是为了准确或完整\\历史记录]\\这里的主要参考文件是:\\R.W.Robinson,带强分量限制的计数有向图,\\组合数学与图论’95(T.-H.Ku编辑),《世界科学》,新加坡(1995),343-354。\\尽管本文讨论了标记的情况和\\源和汇,它包含此处用作简单方程式的方法:\\\\特别是式(18)规定:\\Ggf(exp(-C(x)))*Ggf,\\其中C(x)是任意一组强连通有向图的e.g.f\\G(x)是例如f.是强分量为C(x)的图的集合\\罗伯逊用三角形表示的Ggf()是运算符\\将e.g.f.转换为g.g.f.(图形生成函数)。\\虽然该等式是针对由\\例如,f,它适用于由循环指数系列表示的组合类。\\\\一些特殊情况:\\Ggf(exp(-Singleton))*Ggf,\\Ggf(exp(-强连接有向图))*Ggf,\\Ggf(exp(-强连接定向图))*Ggf。\\\\第二个方程式可以重写:\\强连接图=-log(UnGcf(1/Ggf(图)))。\\\\下面注释的PARI很快证明了它的威力\\标记案例的方程式:\\Ggf算子只需将级数的项除以2^(k*(k-1)/2)和\\UnGgf做这个实验。/*Ggf(p)={my(n=serprec(p,x)-1);serconvol(p,sum(k=0,n,x^k/2^(k*(k-1)/2),O(x*x^n))}UnGgf(p)={my(n=serprec(p,x)-1);serconvol(p,sum(k=0,n,x^k*2^(k*(k-1)/2),O(x*x^n))}强分量(graphEgf)={-log(UnGgf(1/Ggf))}数列Egf(n)={和(k=0,n,2^(k*(k-1))*x^k/k!,O(x*x^n))}\\序列A053763-有向图的数量。Vec(塞拉普拉斯语(DigraphEgf(12))\\序列A003030-强连通有向图的个数。Vec(serlaplace(强组件(DigraphEgf(12)))*/\\\\未标记的案例遵循相同的行,但没有\\相当于Ggf(据我所知),所以“UnGgf(1/Ggf(graphEgf))”\\作为单个操作“InvGgfCIData”执行。相反\\需要一个循环指数系列。\\(关于以PARI幂级数表示的循环指数系列的一些PARI代码,请参见A339645)\\这里我们使用了一种更有效的数组表示,因为all\\使用标准幂级数函数无法快速实现重要操作。\\实际代码开始。\\连接两个排序的小向量,保持顺序。\\专门用于合并两个分区。\\例如:合并([1,1,4],[3,6])=>[1,1,3,4,6]合并(p1,p2)={my(v=向量小(#p1+#p2),i=1,j=1,k=1);而(i<=#p1&&j<=#p2,如果(p1[i]<=p2[j],v[k]=p1[i;i++,v[k]=p2[j;j++);k++);而(i<=#p1,v[k]=p1[i];i++;k++);而(j<=#p2,v[k]=p2[j];j++;k++);v;}\\创建要排序的分区映射。\\分区的秩是它在分区的生成顺序中出现的顺序。\\这用于支持按分区索引的矩阵。\\尽管有更多节省内存的方法可以利用\\分区的特定顺序,这是总内存占用的一小部分。构建分区索引(n)={my(M=Map(),ix=1);对于部分(p=n,映射(M,p,ix);ix++);M;}\\给出特定类型(其中该类型是分区)的排列数。permcount(v)={my(m=1,s=0,k=0,t);对于(i=1,#v,t=v[i];k=if(i>1&&t==v[i-1],k+1,1);m*=t*k;s+=t);s!/m}\\用于构造各种图的循环索引序列的函数。\\参数v是(循环类型的)分区\\参数yf用于在需要时捕获边缘数据。数字边缘(v,yf)={prod(i=2,#v,prod(j=1,i-1,my(g=gcd(v[i],v[j]));yf(v[i]*v[j]/g)^(2*g))有循环边的数字(v,yf)={prod(i=2,#v,prod(j=1,i-1,my(g=gcd(v[i],v[j]));yf(v[i]*v[j]/g)^(2*g)))*prod(i=1,#v,yf(v[i])^v[i]}定向图形边(v,yf)={prod(i=2,#v,prod(j=1,i-1,my(g=gcd(v[i],v[j]));yf(v[i]*v[j]/g)^g))*prod(i=1,#v,my,c=v[i]);yv(c)^((c-1)\2))}\\可以将上面的其中一个传递给此函数,以实际创建周期索引序列。\\循环指数序列表示为向量向量。图形CIData(n,edgeFunc,yf=e->2)={my(结果=向量(n+1));对于(n=0,n,my(v=向量(numbpart(n)),xi=0);部分(p=n,xi++;v[xi]=permcount(p)*edgeFunc(p,yf););结果[1+n]=v;);结果;}\\这是InvGgf的未标记等价物(1/Ggf(graphEgfSeries))\\这是它自己的反义词。这是求强图个数的核心算法。\\与A122078中给出的“DagCycleIndexData”函数进行比较。InvGgfCIData(块,yf=e->2)={my(n=#blocks-1,results=向量(n+1));结果[1]=[1];对于(n=1,n,my(v=向量(numbpart(n)),pm=建筑分区索引(n);对于(i=1,n,my(j=n-i,uj=结果[j+1],ui=块[i+1],b=二项式(n,i),Q=向量(i),xj=0);对于部分(pj=j,xj++;对于(s=1,#Q,Q[s]=prod(t=1,#pj,my(g=gcd(s,pj[t]));yf(s*pj[t]/g)^g);我的(xi=0);对于部分(pi=i,xi++;my(col=mapget(pm,Merge(pi,pj)));v[col]-=uj[xj]*b*ui[xi]*prod(t=1,#pi,Q[pi[t]]);); \\ 圆周率); \\ 第页); \\ 结果[n+1]=v;); \\ n个结果;}\\帮助将存储为向量向量的循环索引序列转换为o.g.f.,以计数未标记的对象。未标记Ogf(数据)={总和(n=0,#data-1,vecsum(data[n+1])*x^n/n!,O(x^#数据));}\\唯一需要的其他操作是组合对数。给出了它的循环索引系列实现\\在A339645中(组合物种的功能)。这里我们作弊,先转换成o.g.f,然后取\\逆欧拉变换是组合对数的o.g.f.等价物。\\欧拉逆变换(单变量和多变量)\\单变量版本获取一个向量并返回相同长度的向量。InvEulerT(v)={my(p=log(1+x*Ser(v)));dirdiv(向量(#v,n,polcoef(p,n)),向量(#vn,1/n))}\\多元版本适用于幂级数。主变量必须是x。InvEulerMTS(p)={my(n=serprec(p,x)-1,q=log(p),vars=variables(p));总和(i=1,n,moebius(i)*substvec(q+O(x*x^(n\i))),vars,apply(v->v^i,vars))/i)}\\强连通定向图的序列。A350489seq(n)={concat([1],-InvEulerT(Vec(-1+未标记Ogf(InvGgfCIData(GraphCIData(n,OrientedGraphEdges,e->3))))}A350750行(n)={my(v=Vec(-InvEulerMTS(未标记Ogf(InvGgfCIData(GraphCIData(n,OrientedGraphEdges,e->1+2*y^e),e->1+y^e,))));向量(#v,n,Vecrev(v[n],1+n*(n-1)/2))}A350751seq(n)={my(g=-InvEulerMTS)(未标记Ogf(InvGgfCIData(GraphCIData(n,OrientedGraphEdges,e->1+2*y^e+O(y*y^n)),e->1+y^e+O(y*y^n,))));Vec(总和(i=1,n,polcof(g,i,x)),-n)}\\强连通有向图的序列。A035512seq(n)={concat([1],-InvEulerT(Vec(-1+未标记Ogf(InvGgfCIData(GraphCIData(n,DigraphEdges))))]}A057276行(n)={[Vecrev(p)|p<-Vec(-InvEulerMTS(未标记Ogf(InvGgfCIData(GraphCIData(n,DigraphEdges,e->1+y^e),e->1+y^e)))]}A350753行(n)={my(yf(e)=1+y^e+O(y*y^n))A350752seq(n)={my(yf(e)=1+y^e+O(y*y^n))\\具有多个边和环的强连通有向图的序列。A139622行(n)={my(yf(e)=1/(1-y^e)+O(y*y^n))A139627seq(n)={my(A=A139622rows(n));concat([1],向量(#A,n,vecsum(A[n]))}\\此处不使用以下内容,但转换表示为向量向量的循环指数序列\\变成幂级数。取决于A339645 PARI脚本中定义的sMonomic函数。ToCycleIndexSeries(数据)={总和(n=0,#数据-1,my(行=数据[n+1],t=0,xi=0);对于部分(pi=n,xi++;t+=row[xi]*s单项式(pi));x^n*t/n!,O(x^#数据));}\\结束