我遇到了这个问题,正在努力寻找解决方法。任何想法将不胜感激!
假设我们给出一个矩阵,例如
无需尝试每个单独的排列,就可以找到第列的排序,该排序可使第一个非零元素为的行数最大化。
对于上面的示例,这样的排序(不是唯一的!)是,即
这里,对于出来的行的第一非零元素是。
我遇到了这个问题,正在努力寻找解决方法。任何想法将不胜感激!
假设我们给出一个矩阵,例如
无需尝试每个单独的排列,就可以找到第列的排序,该排序可使第一个非零元素为的行数最大化。
对于上面的示例,这样的排序(不是唯一的!)是,即
这里,对于出来的行的第一非零元素是。
Answers:
我将其称为Column Order的CO的问题是NP-hard。这是从NP难题顶点覆盖(VC)到它的简化:
令输入的VC实例为。它代表一个问题:“给定图,是否可以从V中选择一组最多个顶点,以使E中的每个边都入射到至少一个选定的顶点上?” 我们将构造一个实例(甲,ķ ')表示的问题的CO:“鉴于矩阵阿与元素{ - 1 ,0 ,1 },是否有可能对的列进行置换,以使至少在行上的1出现在-1之前?”这两个问题以决策问题形式陈述,因此每个问题的答案为是或否:正式而言,正是这种形式的问题是NP完全的(或不完全的)。不难发现,在OP的问题中陈述的更为自然的优化问题形式在复杂度方面大致相等:在阈值上进行二进制搜索可以使用决策问题解决程序来使用参数来解决优化问题,而单次调用优化问题解决程序并进行一次比较就足以解决决策问题。
令和。我们将构建一个具有(n + 1 )m + n行和n + 1列的矩阵前(n + 1 )个m行将由m个块组成,每个n + 1行,每个块代表一个需要覆盖的边缘。底部n 行包含顶点“标志”,如果一列(对应于顶点)包含在CO解决方案的左侧(对应于顶点包含在CO的顶点覆盖层中),则会导致固定费用。 VC解决方案)。
对于每个顶点,在其中创建一列:
再创建一个“栅栏”列,该列由副本-1,后跟副本+1组成。
最后,设置阈值为构造CO实例:。换句话说,我们最多允许行,其中-1出现在+1之前。我们将此违反行数称为CO解决方案的“成本”。
CO实例的解决方案和原始VC实例中的一组顶点之间的对应关系是:篱笆左侧的每一列都对应于该集合中的一个顶点,篱笆右侧的每一列都对应于该顶点顶点不是。
直观地,“ fence”列顶部的-1s强制选择要放置在其左侧的列子集,这些列在所有这些位置上共同包含+1,这对应于入射在每个列上的顶点子集边缘。 出现在“围栏”左侧的这些列中的每列在底部行中某处的不同行上都有-1 ,产生1的费用;“栅栏”底部的+1确保所有放置在其右侧的列均不产生此类费用。
显然,最多使用个顶点的VC解决方案可以为已构建的CO实例提供最多成本的解决方案:只需任意排序与顶点覆盖中的顶点对应的列,然后依次对围栏列和所有其余列进行任何排序。
仍有待证明,成本最多为的CO实例的解决方案对应于最多为个顶点的顶点覆盖。
相反,假设存在一个成本为的CO实例的解决方案,该解决方案在m行的前行中的某些行的+1之前为-1。该行属于行的块,该行对应于特定边。原始实例中此块中的每一行在构造上都是相同的;置换列可能会更改这些行,但不会影响它们相同的事实。因此,在解决方案中,这些相同行中的每行在+1之前都具有-1,这意味着至少要付出代价。但:矛盾。
由于顶部(n + 1 )个m行中的个行块中的每一个在-1之前都具有+1,因此每个对应的边都由与围栏左侧的一列相对应的顶点覆盖: ,此顶点子集构成一个顶点覆盖。由于前m个行(n + 1 )中的任何一个都没有在+1之前具有-1,因此解决方案中唯一可产生成本的地方是在n个行的底部,即位于栅栏左侧的列。每个这样的列的成本正好为1,因此假设成本最多为k,则最多必须有k这样的列,因此覆盖物中最多有个顶点。
最后,很明显,可以从VC实例以多项式时间构造CO实例,这意味着,如果存在用于求解CO的多项式时间算法,则任何VC实例也都可以通过首先构造一个CO实例来在多项式时间内求解。然后解决它。由于VC对NP很难,因此CO也是如此。
我不知道实际上是否存在多项式解。不过,根据PålGD的评论,您可以构建一个简化函数。构建输出序列将简化初始矩阵。
function simplification:
while(true)
if any row i$ has no 1 or no -1 left, remove it
if any column j has no -1 then,
remove it and put j on the leftmost available position in S,
remove all rows where column j has 1.
if any column j has no 1 then,
remove it and put j on the rightmost available position in S.
if no modification has been done on this loop, break
然后,您必须迭代地使用函数pick来全面研究组合函数:
function pick(k):
put column k on the leftmost available position in S
remove any row where column k is -1 or 1
每次选择之后,您都可以简化操作,以减少探索的可能性。我建议从-1较小的列开始贪婪地探索,这样您可能会达到下限,从而成为停止条件。
在给定的示例中,第一个简化为(如PålGD在评论中所述)
我认为一个矩阵使得这种方法比较效率不高就会有且仅有一个1,和一个-1每行/列,像
尽管如此,简化仍然节省了大约一半的勘探步骤。并且这种类型的矩阵可以拆分为几个独立的子矩阵。