寻找最佳订购


9

我遇到了这个问题,正在努力寻找解决方法。任何想法将不胜感激!

假设我们给出一个矩阵{1,0,1}n × k,例如

[1010110001011011101110001]

无需尝试每个单独的排列,就可以找到第列的排序,该排序可使第一个非零元素为的行数最大化。ci1

对于上面的示例,这样的排序(不是唯一的!)是,即(c3,c4,c1,c2,c5)

[1010100101100110111100101]

这里,对于出来的行的第一非零元素是。451


您尝试了哪些算法方法?您在哪里遇到这个问题?您能相信原始来源吗?您可以分享有关背景或动机的任何信息吗?您可能会发现此页面有助于改善您的问题。
DW

1
我想建议一个预处理步骤:让一个半正列(resp。row)成为只有0和1s的列(resp。row)。建议删除所有半正列,以及半正列中带有1的行。在您的示例中,这将删除第1、3和4行。现在,剩下的行和列都包含-1。可能无济于事,但推理起来可能更简单。
帕尔GD

我们可以假设行数比列数小得多吗?这可能使问题变得更容易。
安吉拉·普雷托里乌斯

1
@Pål,可以对不包含1的行和列进行类似的预处理。但是,我认为这样做并不容易推论:只是更小。
彼得·泰勒

1
FWIW这是一个交叉岗位。haijo,如果您没有在一个堆栈上收到答案,并认为另一个堆栈可能更好,则可以标记它并请求迁移。交叉发布不是很好的礼节,因为回答者不知道您可能在另一个站点上收到的答案,并且可能会浪费他们的时间来重复它们。
彼得·泰勒

Answers:


4

我将其称为Column Order的CO的问题是NP-hard。这是从NP难题顶点覆盖(VC)到它的简化:

VC和CO的决策问题形式

令输入的VC实例为(V,E,k)。它代表一个问题:“给定图(V,E),是否可以从V中选择一组最多k个顶点,以使E中的每个边都入射到至少一个选定的顶点上?” 我们将构造一个实例ķ '表示的问题的CO:“鉴于矩阵与元素{ - 1 0 1 }VE(A,k)A{1,0,1},是否有可能对A的列进行置换,以使至少在k行上的1出现在-1之前?”这两个问题以决策问题形式陈述,因此每个问题的答案为是或否:正式而言,正是这种形式的问题是NP完全的(或不完全的)。不难发现,在OP的问题中陈述的更为自然的优化问题形式在复杂度方面大致相等:在阈值上进行二进制搜索可以使用决策问题解决程序来使用参数来解决优化问题,而单次调用优化问题解决程序并进行一次比较就足以解决决策问题。

从VC实例构造CO实例

n=|V|m=|E|。我们将构建一个具有n + 1 m + n行和n + 1列的矩阵An + 1 )个m行将由m个块组成,每个n + 1行,每个块代表一个需要覆盖的边缘。底部n(n+1)m+nn+1(n+1)mmn+1n 行包含顶点“标志”,如果一列(对应于顶点)包含在CO解决方案的左侧(对应于顶点包含在CO的顶点覆盖层中),则会导致固定费用。 VC解决方案)。

对于每个顶点vi,在其中创建一列:

  • 顶端之间(n+1)m行时,j的第块n+1行的所有含有一个1时边缘ej入射vi,否则为0,和
  • 底部n行都是0除i个,这是-1。

再创建一个“栅栏”列,该列由(n+1)m副本-1,后跟n副本+1组成。

最后,设置阈值k为构造CO实例:(n+1)m+nk。换句话说,我们最多允许k行,其中-1出现在+1之前。我们将此违反行数称为CO解决方案的“成本”。

证明

CO实例的解决方案和原始VC实例中的一组顶点之间的对应关系是:篱笆左侧的每一列都对应于该集合中的一个顶点,篱笆右侧的每一列都对应于该顶点顶点不是。

直观地,“ fence”列顶部的-1s强制选择要放置在其左侧的列子集,这些列在所有这些位置上共同包含+1,这对应于入射在每个列上的顶点子集边缘。 出现在“围栏”左侧的这些列中的每列在底部n行中某处的不同行上都有-1 ,产生1的费用;“栅栏”底部的+1确保所有放置在其右侧的列均不产生此类费用。

显然,最多使用k个顶点的VC解决方案可以为已构建的CO实例提供最多k成本的解决方案:只需任意排序与顶点覆盖中的顶点对应的列,然后依次对围栏列和所有其余列进行任何排序。

仍有待证明,成本最多为k的CO实例的解决方案对应于最多为k个顶点的顶点覆盖。

相反,假设存在一个成本为k的CO实例的解决方案,该解决方案在m行的前(n+1)m行中的某些行的+1之前为-1。该行属于(n+1)行的块,该行对应于特定边uv。原始实例A中此块中的每一行在构造上都是相同的;置换列可能会更改这些行,但不会影响它们相同的事实。因此,在解决方案中,这些n+1相同行中的每行在+1之前都具有-1,这意味着至少要付出代价n+1。但kn<n+1:矛盾。

由于顶部n + 1 )个m行中的m个行块中的每一个在-1之前都具有+1,因此每个对应的边都由与围栏左侧的一列相对应的顶点覆盖: ,此顶点子集构成一个顶点覆盖。由于前m个n + 1 )中的任何一个都没有在+1之前具有-1,因此解决方案中唯一可产生成本的地方是在n个行的底部,即位于栅栏左侧的列。每个这样的列的成本正好为1,因此假设成本最多为k,则最多必须有k(n+1)m(n+1)mnkk这样的列,因此覆盖物中最多有k个顶点。

最后,很明显,可以从VC实例以多项式时间构造CO实例,这意味着,如果存在用于求解CO的多项式时间算法,则任何VC实例也都可以通过首先构造一个CO实例来在多项式时间内求解。然后解决它。由于VC对NP很难,因此CO也是如此。


每当有这样一个好的答案时,我都想知道是否应该用“有价值的网络答案”之类的东西替换或加入“热网络问题”。
John L.

您能否阐明如何找到答案?这应该比答案本身更具启发性。
John L.

1
@ Apass.Jack:谢谢!:)我没有特殊的策略,可以花很长时间在错误的方向上徘徊。例如,在这里我花了很长时间思考可以减少汉密尔顿循环(就元素排序而言,这是相似的),然后才意识到我的构造将允许与子轮廓相对应的配置,因此将不起作用。通常,我总是尝试从“ Vertex Cover”或“ Partition”中缩小,然后再选择“ Clique”。“有价值的网络答案”听起来像是个好主意:)
j_random_hacker

1
@ Apass.Jack:一个有用的一般想法是考虑如何在不改变答案的情况下“缩放”目标问题实例-例如,如果目标问题(我们试图证明的目标)是“顶点覆盖”,则使任何正整数不相交的图表的副本,也乘以阈ķ通过ř叶答案不变。通常,您希望某些违规(目标解决方案与有效的源解决方​​案不对应)会“压倒”某些其他违规,在这种情况下,您可以“乘以”与更重要的违规相对应的小工具。rkr
j_random_hacker

1
为了减少答案,我们想对一个存在两个“力”的问题进行编码:尝试覆盖所有边缘,并尝试使用尽可能少的顶点。第一个是更重要的在这里,所以我“乘达”所对应的边缘行:现在是单边违规成本,这意味着它更糟糕的是错过一个单一的边缘,而不是包括所有顶点。我现在才意识到,我应该编辑答案以明确表明我们正在处理这两个问题的决策问题版本,其中阈值参数是问题实例的一部分……n+1
j_random_hacker

2

我不知道实际上是否存在多项式解。不过,根据PålGD的评论,您可以构建一个简化函数。构建输出序列S将简化初始矩阵。

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在评论中所述)

  • S[0]=c3,去除r1,r3
  • S[1]=c4,去掉r4
  • S[2]=c2 这使您可以使用简单的矩阵进行探索。
    [1111]

我认为一个矩阵使得这种方法比较效率不高就会有且仅有一个1,和一个-1每行/列,像

[110000110000001100001100000011000011]

尽管如此,简化仍然节省了大约一半的勘探步骤。并且这种类型的矩阵可以拆分为几个独立的子矩阵。


1
@ Apass.Jack我编辑得更精确了。是的,我的意思是列在输出序列中的位置。
Optidad

认为简化步骤可能足以满足实际目的(例如在线编程练习?)。
John L.

谢谢,实际上我很想估算摊销的时间成本,但我真的不知道该怎么办。这可能吗 ?还是很大程度上取决于问题?
Optidad

2
我尝试了摊销时间分析,这似乎很困难。我怀疑NP的完整性。另一方面,简化步骤可以更通用。列Ĵ使得他们的共享非零部分的非零部分,柱Ĵ可以如果存在额外的非零部分被去除Ĵ不包含1和列可以去除如果满足额外非零部分Ĵ不包含-1。ijijjij
John L.

1
另一个主导规则是:每当您有两列j时,至少有1行,其中i为-1,j为+1,没有行,其中i为+ 1,j为-1,则有将放在第一位永远没有任何优势。比方说,Ĵ主宰在这种情况下。您可以在内部pick(k)中实现此功能,方法是检查k是否主导了已放置的任何列:如果是,则可以修剪搜索树的此分支。ijijijijikk
j_random_hacker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.