浅谈保序回归问题
前言
保序回归问题应该算是一个非常诡异也非常困难的问题。
只是因为去年联合省选出了,出于义务决定学习一下。然而也没能学得特别深(实力限制),只能算作是浅谈。
参考的是高睿泉的论文《浅谈保序回归问题 》,只是记下了其中的一部分内容。
偏序关系
一个非常基础的概念,但这里还是简单讲一下。
设\(\texttt{op}\)是集合\(S\)上的一种二元运算,满足:
- 自反性:\(\forall x\in S,x\ \texttt{op}\ x\)。
- 自对称性:\(\forall x,y\in S\),若\(x\ \texttt{op}\ y\)且\(y\ \texttt{op}\ x\),则\(x=y\)。
- 传递性:\(\forall x,y,z\in S\),若\(x\ \texttt{op}\ y\)且\(y\ \texttt{op}\ z\),则\(x\ \texttt{op}\ z\)。
那么,就称\(\texttt{op}\)是\(S\)上的非严格偏序关系,记作\(\le\)。
\(L_p\)问题的定义
给定正整数\(p\),一张点集为\(V\),边集为\(E\)的有向无环图\(G\),每个点上有两个代价参数\(y_i\)和\(w_i\)。
对于\(G\)中的一条有向路径\(v_i\rightarrow v_j\),它表示的是\(v_i\le v_j\)。
而我们要做的是求出一个点值序列\(f\),满足\(\forall v_i\le v_j,f_i\le f_j\),最小化代价:
对于相同的\(p\),这种问题就称作\(L_p\)问题。
整体二分求解保序回归问题
一些特殊的保序回归问题有着特殊的解法,但这里只介绍它的通法,就是整体二分。
在此之前先定义一个序列\(s\)向集合\(S=\{a,b\}\)取整的概念,就是指让\(s\)中小于\(a\)的所有数变成\(a\),大于\(b\)的所有数都变成\(b\),使得所有的数都落在\(S=\{a,b\}\)这个值域区间内。
然后我们在原问题的基础上构造一个新的\(S=\{a,b\}\)问题,就是要让原问题不仅满足原本的限制,还要让所有\(f_i\in[a,b]\),同时最小化回归代价。
对此,来要分\(p\)是否等于\(1\)两种情况来讨论。
第一类:\(p=1\)
引理: 在\(L_1\)问题中,如果任意\(y_i\)均不在区间\((a,b)\)中,且存在一个最优解序列\(z\)满足任意\(z_i\)均不在区间\((a,b)\)中,若\(z^S\)为\(S\)问题的一组最优解,那么原问题一定存在一个最优解序列\(z\)满足\(z\)可以向\(S\)取整得到\(z^S\)。
证明就考虑反证法,要分成多类讨论,这里略去了。
根据这个引理,只要通过一组\(S\)问题的最优解,就能确定原问题中\(z_i\)与\((a,b)\)的大小关系。
因此我们只需整体二分,每当二分到一个区间\([L,R]\)的时候,只需求解其中\(S=\{mid,mid+1\}\)的问题的最优解,这样一来就能确定出每个\(f_i\)的取值应该落在哪半区间中了。
第二类:\(1 < p < \infty\)
定义一个点集的\(L_p\)均值为满足\(\forall f_i=k\)时回归代价最小的\(k\)。
引理: 当\(1<p<\infty\)时,点集的\(L_p\)均值唯一。
证明就是考虑对于\(g(x)=\sum_{v_i\in V}|x-y_i|^p\)求导,发现:
因为随着\(x\)的增大,前者显然递增,后者显然递减,二者相减则\(g'(x)\)必然单调,因此\(g'(x)\)至多只有一个零点。
又由于\(\forall y_i<x\)时显然\(g'(x)>0\),\(\forall y_i>x\)时显然\(g'(x)<0\),因此\(g'(x)\)必然有零点。
其实对于\(1<p<\infty\)时的情况,我们仍旧能像前面那样子去整体二分,只不过最优解可能为实数。
实数的情况下,只要把代价修改为中点处的导数即可。
网络流处理\(S\)问题
整体二分时要处理\(L_p\)问题对应的\(S\)问题,相当于是一个集合划分,每个点只有两种选择。
而一对偏序关系\(v_i\le v_j\),此时就能看作把\(v_i\)选入了右集合就必须把\(v_j\)也选入右集合,成了经典的最小权闭合子图问题,可以网络流求解。
算法流程总结
我们整体二分,记录当前点集对应的答案区间\([L,R]\)。
把区间根据\(mid\)划分成两份,每个点计算选入左右区间的贡献差,与源点和汇点连边。
按照最小权闭合子图的套路,给存在偏序关系的点之间连边。
跑网络流,由于网络流会跑到增广失败才结束,最后一次增广失败时未被访问到的点相当于是保留与汇点的边被选入左集合,被访问到的点相当于是保留与源点的边被选入右集合
然后递归下去做即可。