1

Let's say I have a matrix of N lines and N columns. Let's take N = 5. How can I make a .pl program which returns me a list of N random pairs in which the distance between any pair is minimum 2? A pair is of form (i, j), where i represents the line and j represents the column of an element. I made the distance function:

dist(X1, Y1, X2, Y2, D) :-  
    D is round(sqrt((X2 - X1)**2 + (Y2 - Y1)**2)).

The main should look like this:

?- L = []
?- make_list(L).
L = [pair(5,5), pair(1,1), pair(3, 3), pair(1,5), pair(5, 1)]

Can you give me any useful piece of code or at least some ideas?

false
  • 10,264
  • 13
  • 101
  • 209
charqus
  • 469
  • 1
  • 5
  • 15
  • First of all - how would you represent that matrix? – Eugene Sh. May 15 '15 at 20:23
  • Sorry for omitting that ... I would hardcoded them, like this: matrix(1, 1). matrix(1, 2). .................. matrix(5, 4). matrix(5, 5). – charqus May 15 '15 at 20:32
  • Sorry, I can't see how this representation will define a 5x5 matrix. It has to contain 25 values. – Eugene Sh. May 15 '15 at 20:35
  • Eugene Sh., that's why I have put "...........", press this [pastebin](http://pastebin.com/37j5TdPc) to see the full list – charqus May 15 '15 at 20:40
  • 2
    Brief, `matrix(X,Y) :- between(1,5,X), between(1,5,Y).` – false May 15 '15 at 20:43
  • Thank you @false, this would help me to not hardcode my matrix ... Now can you give me an idea on how to build my predicate in order to find 5 pairs that for any other pair the distance between those two is minimum 2? – charqus May 15 '15 at 20:47
  • 1
    `(X2-X1)^2 + (Y2-Y1)^2 >= 2^2` is a better test – false May 15 '15 at 20:51
  • Still, I don't get what is `matrix(1,2)` ? Is it a first row / second column? So where is the value? – Eugene Sh. May 15 '15 at 20:56
  • Indeed @false, you are right again. Eugene, I think I was a bit incomprehensible. Actually, I have to check if the distance of positions between two elements is minimum 2, not the distance of values between two elements is minimum 2 ... – charqus May 15 '15 at 20:58
  • There are many things left unspecified: How long should this list be? As long as possible? Can it contain cycles etc. – false May 15 '15 at 21:00
  • Oh. That makes more sense. In this case you don't even need to represent the matrix. It's dimensions would be enough – Eugene Sh. May 15 '15 at 21:01
  • `step(pair(X1,Y1),pair(X2,Y2)) :- matrix(X1,Y1), matrix(X2,Y2), X2-X1)^2 + (Y2-Y1)^2 >= 2^2.` That's for sure. But what else? – false May 15 '15 at 21:03
  • Guys, sorry for being obscure, again. All I need is to create a list from 5 random pairs which complies the property described above ... Here I posted some code: http://pastebin.com/Lc6zhqqa; @false, if I call find(X1, X2, X3, X4) from swi-prolog, it will give me an (X1, X2), (X3, X4) elements with the property described above ... If I press ; (semicolon) it will give me another one, and so forth ... This is not what I really need ... What I really need is a new predicate of arity 1 ( if possible ), which when I call it from swi-prolog, it will return me a list with 5 random (unique) pairs. – charqus May 15 '15 at 21:07
  • `?- step(P1,P2),step(P2,P3),step(P3,P4),step(P4,P5).` However, this permits cycles. Add goals `dif(P1, P3), dif(P2, P4), ...` to avoid them – false May 15 '15 at 21:10
  • Yea, but actually this gives me only "true" as a result, not a list which contains the pairs with their positions ... EDIT: And one more thing, it never gives me random pairs, always the pairs are preserved as result ... – charqus May 15 '15 at 21:16
  • Oh no: Above query produces an answer `P1 = pair(...` for `P1, ... P5`. So the answer is not just `true` – false May 16 '15 at 19:14

1 Answers1

0

I suggest the following pseudocode

  1. Obtain the list of all valid pairs - use e.g. findall/3 with rules suggested in the comments :)
  2. Compute the list length - use lenght/2
  3. Choose random list item - described in the similar question

This should work well :) give it a try, it's quite straightforward.

Community
  • 1
  • 1
petrbel
  • 2,428
  • 5
  • 29
  • 49