8
votes

Comment transposer une matrice dans Prolog

Comment puis-je transposer une liste comme [[1,2,3] [4,5,6] [6,7,8]] à [[1,4, 6], [2,7,8], [3,6,9]] ?

Pour le décrire: je voudrais retourner la matrice 90 degrés à gauche. Comment puis-je faire ça?


0 commentaires

8 Réponses :


2
votes

voici Un fragment d'une réponse plus grande :

% transposed(+A, ?B) iff matrix B is transposed matrix A
transposed(A, B) :- transposed(A, [], B).
transposed(M, X, X) :- empty(M), !.
transposed(M, A, X) :- columns(M, Hs, Ts), transposed(Ts, [Hs|A], X).

% empty(+A) iff A is empty list or a list of empty lists
empty([[]|A]) :- empty(A).
empty([]).

% columns(+M, ?Hs, ?Ts) iff Hs is the first column
%   of matrix M and Ts is the rest of matrix M
columns([[Rh|Rt]|Rs], [Rh|Hs], [Rt|Ts]) :- columns(Rs, Hs, Ts).
columns([[]], [], []).
columns([], [], []).


1 commentaires

Merci :) peut-être que cela peut être utile. D'abord, je préfère utiliser la fonction transpose / 2, si je l'obtiens à travailler en quelque sorte ...



9
votes

Pas sûr que votre exemple est correct, mais je reçois l'idée.

Si vous utilisez Swi-prolog, vous pouvez utiliser le Module CLPFD , comme:

: - Utilisez_module (Bibliothèque (CLPFD)).

Vous permettant d'utiliser le prédicat transpose / 2 , comme celui-ci: xxx

sinon (si aucun swi-prolog), vous pouvez simplement utiliser cette implémentation (ce qui est arrivé à être un ancien dans le CLPFD de swi): xxx

pour une version mise à jour qui utilise des constructions intégrées de FLETL et de maplist, voir clpfd.pl .


6 commentaires

Merci! J'utilise Swi Prolog et j'ai essayé votre première solution. Mais lors de la frappe "User_Module (Bibliothèque (CLPFD))." J'obtiens l'erreur suivante: "Erreur: Source_Sink` Bibliothèque (CLPFD) "n'existe pas" Savez-vous comment résoudre ce problème?


Je suppose que vous n'avez pas vraiment la bibliothèque clpfd ou votre installation de SWI-PL est éclaté. clpfd.pl devrait résider dans le répertoire bibliothèque / clp (sous le répertoire à domicile SWI-PL). Si c'est là, alors peut-être que Swi-pl ne pouvait tout simplement pas le trouver; Dans ce cas, peut-être votre exécutable pl a un nom différent du fichier ___. RC de fichier de configuration, également dans le répertoire racine SWI-PL (ils doivent être identiques). Sinon, il suffit d'utiliser simplement la définition que j'ai postée qui est la mise en œuvre de clpfd 'S transpose / 2 de toute façon.


D'accord. La bibliothèque était manquante et je l'ai copiée en bibliothèque / CLP. Mais ça ne marche toujours pas. J'ai un fichier nommé "plwin.rc" dans le directeur PL-racine et un dossier bin avec les exécutables. Déplacer le .rc dans le dossier bin ne le résout pas .. alors dois-je le modifier?


Si la bibliothèque a été initialement manquante, votre copie de SWI-PL n'aurait peut-être pas été configurée pour rechercher des bibliothèques à cet endroit, il suffit de copier simplement des fichiers autour de ne pas atteindre grandement (vous pouvez avoir un problème de configuration à la place, que je ' Je ne sais pas comment résoudre sans voir votre système). Essayez de mettre à niveau vers la dernière version: swi-prolog.org/download/stable


@shanarky: belle réponse, +1! Il y a de nouveau code dans bibliothèque (CLPFD) qui parvient à le faire plus élégamment maintenant. Le lien vers le code source a également changé. J'espère que vous pouvez mettre à jour la réponse en conséquence.


@mat merci. J'ai fourni un lien à la mise en œuvre mise à jour dans le CLPFD, mais j'ai quitté l'ancienne mise en œuvre dans ma réponse car je l'aime mieux (il n'utilise pas intégré que d'autres implémentations de Prologs n'auraient peut-être pas).



0
votes

Une approche itérative: xxx


0 commentaires

0
votes

Ma solution avec des noms complets pour une meilleure compréhension: xxx pré>

une "ligne" peut être un col ou une rangée. P>

L'idée réside dans l'annexe des éléments dans les listes d'une matrice vide. (E.G. Tous les éléments de la première rangée = les premiers éléments de tous les cols => Tous les éléments de la première I-nième rangée = les éléments I-Nth de tous les cols) P>

Il fonctionne sur ma machine car ce protocole de session me montre: P>

5 ?- transposeMatrix([[1,2],[3,4]],T).
T = [[1, 3], [2, 4]] ;
false.

6 ?- transposeMatrix([[1],[2]],T).
T = [[1, 2]] ;
false.

7 ?- transposeMatrix([[1,2,3],[4,5,6]],T).
T = [[1, 4], [2, 5], [3, 6]] ;
false.

8 ?- transposeMatrix([[1]],T).
T = [[1]] ;
false.


0 commentaires

1
votes

approche plus simple: xxx

efficace également xxx


2 commentaires

Toute raison de mettre les cas plus simples durer?


Je ne peux pas commander les résultats.



7
votes

C'est la plus petite solution que je pourrais proposer.

Code H1>
[[2,3],
 [5,6],
 [8,9]]


0 commentaires

0
votes

Une autre approche:

delete_one_list([], []).
delete_one_list([[_|L]|LLs], [L|Ls]) :-
  delete_one_list(LLs, Ls).

transpose_helper([], []).
transpose_helper([[X|_]|Xs], [X|Ys]) :-
  transpose_helper(Xs, Ys).

transpose([[]|_], []).
transpose(List, [L|Ls]) :-
  transpose_helper(List, L),
  delete_one_list(List, NewList),
  transpose(NewList, Ls).


0 commentaires

1
votes

Une autre approche simple: xxx


0 commentaires