Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为Young tableaux编程_C_Prolog_Diagram_Constraint Programming_Clpfd - Fatal编程技术网

C 为Young tableaux编程

C 为Young tableaux编程,c,prolog,diagram,constraint-programming,clpfd,C,Prolog,Diagram,Constraint Programming,Clpfd,一个奇怪的问题随之而来: 我在学校里做一个问题解决比赛,他们允许我们使用电脑。因为我是比赛中唯一知道如何编码的人,所以我使用C和Pascal程序来更快地解决问题。我已经通过伪代码到代码的练习、算法、Collatz猜想验证等来完成了。 现在,昨天我正在为下一个挑战(4月18日)进行训练,我看到了一个关于Young tableaux的练习。它的措辞是这样的(我会尽我所能从意大利语翻译): “Ferrers图是分布在一个或多个水平行中的N个框的配置,左对齐并配置为每行包含的框数等于或小于其上的行数。这

一个奇怪的问题随之而来:
我在学校里做一个问题解决比赛,他们允许我们使用电脑。因为我是比赛中唯一知道如何编码的人,所以我使用C和Pascal程序来更快地解决问题。我已经通过伪代码到代码的练习、算法、Collatz猜想验证等来完成了。
现在,昨天我正在为下一个挑战(4月18日)进行训练,我看到了一个关于Young tableaux的练习。它的措辞是这样的(我会尽我所能从意大利语翻译):
“Ferrers图是分布在一个或多个水平行中的N个框的配置,左对齐并配置为每行包含的框数等于或小于其上的行数。这些配置也可以通过框数列表来描述,如下图所示:

(来源:)

Young tableau是由N个框组成的Ferrers图,其中填充了从1到N的整数。例如:

(来源:)

如果对框中的数字进行排序,使其按行和列的顺序递增,则该表为“标准”(例如:第一、第三和第五个表)。在标准表中,第一行的第一个框始终包含1。N始终位于图表中某一行的最左框中。


问题

考虑[6,3,2,1,1,1]Ferrers图:
1) 如果6固定在第1行的第6个框中,11固定在第1列的最后一个框中,您可以用多少种方式以标准方式完成图表?

2) 如果7固定在第1行的第6个框中,11固定在第1列的最后一个框中,您可以用多少种方式以标准方式完成图表?

3) 如果8固定在第1行的第6个框中,11固定在第1列的最后一个框中,您可以通过多少种方式以标准方式完成图表?”


我曾试图用一个矩阵来编写一个解决方案,其中填充了这些数字,并用“-1”作为“行结束字符”,但我被卡住了。我如何编写代码“以各种可能的方式填写表格,使表格成为标准?”

如果不使用程序,我相信1)的答案是2。手工推导可能会让人找到一个算法解决方案

第一行以1开头,以6结尾。因此,可以进入第1行的数字必须满足以下条件:1 第一列以1开头,以11结尾。可以进入第一列的数字必须满足类似条件:1 现在只剩下3个号码:12 13 14。只有两种方法可以在tableaux的其余3个单元格中排列它们。可安排如下:

12 13

十四,

--或--

12 14

十三,


试图在代码中解决这个问题,可以采用蛮力路径,或者研究约束传播和回溯技术。这就是为什么早些时候有人建议使用Prolog。另一种语言是Python。

这是一个约束逻辑编程问题。使用编程语言Prolog。Sicstus prolog与clpfd库

考虑到布局本身:

ABCDEF
GHI
JK
L
M
N
--代码--


以下是使用SWI Prolog解决第一个问题的示例解决方案:

:- use_module(library(clpfd)).

tableau(Ts) :-
        Ts = [[A,B,C,_,_,F],
              [G,H,I],
              [J,K],
              [L],
              [M],
              [N]],
        A = 1,
        maplist(ascending, Ts),
        ascending([A,G,J,L,M,N]),
        ascending([B,H,K]),
        C #< I,
        append(Ts, Vs),
        all_different(Vs),
        Vs ins 1..14,
        F = 6,
        N = 11,
        label(Vs).

ascending(Vs) :- chain(Vs, #<).

为了解决这个问题,我将使用约束编程(CP)。在学习一个新的CP系统时,年轻的画面实际上是我试图解决的标准问题之一。以下是迄今为止的实现列表:

我已经改变了“普通”迷你锌模型,为您的具体问题增加了一些额外的限制。请参见此处的完整模型:

(Minizing的含量非常高,很容易用于解决此类问题。)

简要介绍模型中的表示: 对于大小为n(n的划分)的问题,框表示为网格(“x”,大小为n乘以n),值为1到n+1,其中每行和每列按递增顺序排序;因此,n+1最后排序,并作为空值。然后处理分区结构(“p”)以符合Young/Ferrer结构(有关详细信息,请参见模型)

三个问题中的每一个都有两个额外的约束条件(与问题的标准公式相比):

  • 在第一行的第六个方框中应该有一个特定的数字 添加的约束是 x[1,6]=6%或7或8

  • 11应该在第一列的最后一个框中 这是一个有点棘手,但我的方式是这样的,即。 在第一列中,11应该是小于n+1的值中的最后一个, i、 e.列中以下所有值均为n+1:

     exists(j in 1..n) (
          x[j,1] = 11 /\ forall(k in j+1..n) (x[k,1] = n+1)
     )
    
因此,如果我正确理解了这些问题,答案是: 1) 2解决方案 2) 10种解决方案
3) 30种解决方案

这是著名科尔曼著作中的练习。我发现学习这个问题很有帮助,可以创建这种结构,提取最小元素,并保持数据结构不变。

因此,我认为Prolog是比C更好的工具选择。很长时间以来,我一直在这里看到这样一个措辞良好的问题。在这里,我今天最后一次投票。嗯……什么是Prolog?想一想,在没有实际生成解决方案的情况下,如何计算填充它的方法的数量。动态编程、记忆和递归将是您的朋友。由于其他竞争对手不使用程序,因此必须有一个不涉及大量计算的解决方案。好问题!在画这个画面的时候,我注意到如果我把我画的纸顺时针旋转90度,它看起来是一样的。此外,在第一列中,除1、6和11之外,可以有1和11之间的任何数字,在第一行中,除1和6之外,可以有1和6之间的任何数字。有14个
?- tableau(Ts), maplist(writeln, Ts).
[1,2,3,4,5,6]
[7,12,13]
[8,14]
[9]
[10]
[11]
    Ts = [[1, 2, 3, 4, 5, 6], [7, 12, 13], [8, 14], [9], [10], [11]] ;
[1,2,3,4,5,6]
[7,12,14]
[8,13]
[9]
[10]
[11]
    Ts = [[1, 2, 3, 4, 5, 6], [7, 12, 14], [8, 13], [9], [10], [11]] ;
false.
 exists(j in 1..n) (
      x[j,1] = 11 /\ forall(k in j+1..n) (x[k,1] = n+1)
 )