2
$\begingroup$

I want to detect if a set of pairs, for example a={{2,5},{6,3},{1,4},{8,7}} contains a given pair, for example tabu={{4,1},{2,6}} but don´t be relevant the order inside pair (pair {i,j} is equal to {j,i}), so in this case.... YES!!! "a has an element of tabu.

That´s the only target.

So, Are there any function to do this directly?


I was thinking in a variable tabustatus = True if the big contains any pair of tabu, or tabustatus = False otherwise. Ordering previously the pairs for avoid the sort issue(no matter) any similar to:

a = {{1, 2}, {4, 3}, {3, 2}, {5, 2}};
tabu = {{2, 6}, {4, 1}};
asortg = Table[Sort[a[[i]], Greater], {i, 1, Length[a]}];
asortl = Table[Sort[a[[i]], Less], {i, 1, Length[a]}];
tabusortg = Table[Sort[tabu[[i]], Greater], {i, 1, Length[tabu]}];
tabusortl = Table[Sort[tabu[[i]], Less], {i, 1, Length[tabu]}];
Print["a...........", a];
Print["a - Greater.", asortg];
Print["a - Less....", asortl];
Print["----------------------"];
Print["tabu...........", tabu];
Print["tabu - Greater.", tabusortg];
Print["tabu - Less.....", tabusortl];
Print["----------------------"];
tabustatus = False;
Do[Do[Print["i..", i, "  j..", j];If[asortl[[i]] == tabusortl[[j]], Print[asortl[[i]], " - ", tabusortl[[j]]]; tabustatus = True; Break[], False]; If[tabustatus == True, Break[]], {i, 1, Length[asortl]}]; If[tabustatus == True, Break[]], {j, 1, Length[tabu]}];
Print["Tabu Status...", tabustatus];

In this case, I would need to add any Breaks[] to exit If... Do...Do... without continue searching,... since one time one is found,... TABUSTATUS=TRUE, We don´t need to continue searching.

Any faster and less tedious alternative?

$\endgroup$

3 Answers 3

3
$\begingroup$
Or @@ (MemberQ[Sort /@ tabu, #] & /@ Sort /@ a)

(* True *)

There are many ways to do this, above is fine for reasonable lists sizes, if your lists are large, there are faster methods.

$\endgroup$
3
  • $\begingroup$ Could you put the complete solution? because the other answer were delted. I think that There was an error, as you can see in sensa.square7.ch/hgjkhfhgf0.jpg $\endgroup$
    – Mika Ike
    Commented Apr 19, 2014 at 9:24
  • $\begingroup$ @MikaIke: Not sure if you're commenting @ me, mine gives correct True for the data in that image. Other answer was not mine... $\endgroup$
    – ciao
    Commented Apr 19, 2014 at 9:29
  • $\begingroup$ Yes, I only refered to whats before OR@@.... to be a function. For other visitors.The solution seems to be includes[list_, tabu_] := Or @@ (MemberQ[Sort /@ tabu, #] & /@ Sort /@ list) ....as rasher said, and other colleague puts other deleted answer. The other was erroneus, I think , as you see in sensa.square7.ch/hgjkhfhgf0.jpg $\endgroup$
    – Mika Ike
    Commented Apr 19, 2014 at 9:46
0
$\begingroup$
containsTabu = ContainsAny[Sort /@ #, Sort /@ #2]&;

containsTabu[a, tabu]

True

containsTabu[a, {{5,6},{2,3}}]

False

$\endgroup$
0
$\begingroup$

If you have large lists, than a faster approach is to use Nearest. Moreover, if you are checking membership with the same list multiple times, than this approach should be much faster. First, the OP example:

nf = Nearest[Sort /@ a -> "Index"];

!MatchQ[nf[Sort /@ tabu, {1, 0}], {{} ..}]

True

Now, for a much larger example:

a = RandomInteger[10^4, {10^6, 2}];
tabu = RandomInteger[10^8, {10^5, 2}];

nf = Nearest[Sort /@ a -> "Index"]; //AbsoluteTiming
!MatchQ[nf[Sort /@ tabu, {1, 0}], {{} ..}] //AbsoluteTiming

{0.385679, Null}

{0.042875, False}

A comparison with the other answers:

With[{s = Sort /@ tabu},
    Or @@ (MemberQ[s, #] & /@ Sort /@ a[[;;10^3]])
] //AbsoluteTiming (* ciao *)

containsTabu = ContainsAny[Sort/@#, Sort/@#2]&;

containsTabu[a, tabu] //AbsoluteTiming (* kglr *)

{25.0451, False}

{2.76778, False}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.