List Prolog求NxN矩阵的平方

List Prolog求NxN矩阵的平方,list,matrix,prolog,List,Matrix,Prolog,我有一个列表L=[[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]Ii。这代表了我的矩阵。大小可以动态更改,因此块大小可以不同,4x4=4个元素,9x9=9个元素 我想得到组成列表的4个正方形(在本例中是4乘4的矩阵)。如果我有这个矩阵: 5 6 7 8 10 11 12 13 1 2 3 4 14 15 16 17 结果应该是: R = [5,6,10,11],[7,8,12,13],[1,2,14,15],[3,4,16,17].

我有一个列表
L=[[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]
Ii。这代表了我的矩阵。大小可以动态更改,因此块大小可以不同,4x4=4个元素,9x9=9个元素

我想得到组成列表的4个正方形(在本例中是4乘4的矩阵)。如果我有这个矩阵:

5  6  7  8
10 11 12 13
1  2  3  4
14 15 16 17 
结果应该是:

R = [5,6,10,11],[7,8,12,13],[1,2,14,15],[3,4,16,17].

欢迎提出任何建议。谢谢

您首先需要的是一个杠杆,用于将列表列表转换为矩阵。二维矩阵与列表列表的区别是什么?坐标系的概念。因此,需要一种方法将坐标对与矩阵中的相应值关联起来

at(Matrix, X, Y, V) :- nth0(X, Matrix, Row), nth0(Y, Row, V).
这个谓词使得在(X,Y)处对矩阵进行索引并得到值V成为可能。事实证明,在我看来,这是Prolog强大功能的一个大规模演示,因为一旦有了这个简单的谓词,您将获得:

  • 在提供的点处获得值的能力:

    ?- at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], 1,3, V).
    V = 13.
    
  • 迭代整个矩阵的能力(仅实例化
    矩阵
    ,并将其他参数保留为变量):

  • 在矩阵中搜索值的能力:

    ?- at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, 14).
    X = 3,
    Y = 0 ;
    false.
    
所以这是一个非常有用的杠杆!在传统的lanugage中,您需要三个不同的函数来完成所有这些事情,但这是不同的,因为在Prolog中,我们只需要定义事物之间的关系(在本例中,是数据结构和坐标对),Prolog可以完成相当多的繁重工作

现在很容易看出我们如何通过定义我们希望看到的X和Y值集来生成特定的子矩阵。例如,要获得左上角矩阵,我们将执行以下操作:

?- between(0,1,X), between(0,1,Y), 
   at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, V).
X = Y, Y = 0,
V = 5 ;
X = 0,
Y = 1,
V = 6 ;
X = 1,
Y = 0,
V = 10 ;
X = Y, Y = 1,
V = 11.
我们当然可以使用
findall/3
在一个地方收集解决方案:

?- findall(V, (between(0,1,X), between(0,1,Y), 
               at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, V)),
           Vs).
Vs = [5, 6, 10, 11].
你的问题剩下的基本上是一些算术。让我们看看是否有一个正方形矩阵:

square_matrix(M, Degree) :-
    length(M, Degree),
    maplist(length, M, InnerDegrees),
    forall(member(I, InnerDegrees), I=Degree).
这不是一个完美的谓词,因为它不会生成!但它会告诉我们矩阵是否为正方形,如果是,它的阶数是多少:

?- square_matrix([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], D).
D = 4.
一旦你做到了这一点,你必须做的有点公式化:

  • 确保度是一个完美的正方形
  • 取度的平方根。这就是您有多少行或列(平方根4=2,2行和2列,平方根9=3,3行和3列)
  • 在该位置矩阵的(行、列)坐标和(x、y)坐标列表之间建立关系。例如,在4x4矩阵中,有四个平铺:(0,0)、(0,1)、(1,0)和(1,1)。(0,0)的坐标为(0,0)、(0,1)、(1,0)、(1,1),但(1,1)的坐标为(2,2)、(2,3)、(3,2)、(3,3)。如果您手动执行其中一些操作,您将看到这相当于为两个坐标从0到行/列计数(减1)的所有排列添加x和y偏移量
  • 既然已经有了这种关系,就需要进行迭代并组装输出。我想
    maplist/N
    就足够了

  • 希望这有帮助

    到目前为止,你尝试了什么?我知道我需要什么,但我不知道如何用prolog编程,我的知识非常基础。如果你在这个网站上搜索
    [prolog]矩阵
    你也应该找到很多这样的想法。也许,
    平方矩阵(M,度):-length(M,度),maplist(flip(length,Degree),M.
    (使用
    flip(A,B,C):-呼叫(A,C,B)。
    )?(在RosettaCode的斑马页上看到
    flip
    )@WillNess聪明!
    ?- square_matrix([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], D).
    D = 4.