3
$\begingroup$

This is my list:

list = {2.6135182051634342, -2.6690957180727297, 
   0.26060239174734157, -0.4182243295792278};

I wanna gather it every two number,which make this group's diffrence's absolute value is nearest 3.14.

We can see this distance martix.

 DistanceMatrix[list, 
      DistanceFunction -> (First[Abs[#1 - #2]] &)] // MatrixForm

enter image description here

As we see.The $(1st,4th)$ and $(2nd,3rd)$ is we want to group.Implies we result is {{2.6135182051634342,-0.4182243295792278},{-2.6690957180727297,0.26060239174734157}}

But this code doesn't work,becuase the Nearest's first parameter cannot be a matrix.

mat = DistanceMatrix[list, 
   DistanceFunction -> (First[Abs[#1 - #2]] &)];
Position[mat, Nearest[mat, 3.14, 2]]

Or there are other more better method to do this?


Let's extended this topic.Assumption we have a list2 like this.But wanna group it every two element that make its sum nearest 100.So how to do it?

SeedRandom[2016317];
list2 = RandomSample[Range@100, 20];
DistanceMatrix[list, 
  DistanceFunction -> (First[Plus[#1, #2]] &)] // MatrixForm

enter image description here

$\endgroup$
  • $\begingroup$ @Dr.belisarius Can we don't set a threshold value?Because the value is not easy to confirm at times. $\endgroup$ – yode Mar 17 '16 at 3:28
  • $\begingroup$ You didn't mention "without element repetitions" in your first formulation of the question. Moving target questions are generally frowned upon here and I, for one, don't answer them anymore as they are an endless process. $\endgroup$ – Dr. belisarius Mar 20 '16 at 16:30
  • $\begingroup$ @Dr.belisarius The poor language competence undermining me.I didn't deliberately frown you.Actually the function is used in this to judge whether two points are in a line.I felt very very upset for letting you down.And I post a new quetion for this "new target". $\endgroup$ – yode Mar 21 '16 at 1:20
  • $\begingroup$ Ok, no prob. :) $\endgroup$ – Dr. belisarius Mar 21 '16 at 1:21
4
$\begingroup$
f[l_List, nbr_Integer, near_Real] := Module[{k, f},
  k = Subsets[Range@Length@l, {2}]; 
  f = Nearest[# -> Range@Length@#] &[EuclideanDistance @@ l[[#]] & /@ k];
  k[[f[near, nbr]]]
  ]

list = {2.6135182051634342, -2.6690957180727297, 
       0.26060239174734157, -0.4182243295792278};

f[list, 2, N@Pi]

(* {{1, 4}, {2, 3}} *)

Your other example:

SeedRandom[2016317];
list2 = RandomSample[Range@100, 20];
f[list2, 2, 100.]

(* {{14, 18}, {18, 20}} *)
$\endgroup$
  • $\begingroup$ we result is {{2.6135182051634342,-0.4182243295792278},{-2.6690957180727297,0.26060239174734157}}.Of course,your code can do it. $\endgroup$ – yode Mar 17 '16 at 3:30
  • $\begingroup$ I'm sorry to cancel the acceptance.But some problem isn't be found before this. $\endgroup$ – yode Mar 20 '16 at 9:32
3
$\begingroup$

I'll show how to use Nearest for this, using the larger example.

SeedRandom[2016317];
list2 = RandomSample[Range@100, 20]

(* Out[1510]= {20, 42, 89, 8, 56, 96, 39, 21, 40, 76, 62, 14, 51, 5,
  66, 84, 73, 99, 37, 7} *)

nf = Nearest[list2];

Now we use the fact that the NearestFunction can take a list argument (shortcut for mapping in this case) when dimensions are appropriate. For each element we want to find the one(s) that with it sum closest to 100.

nf[100 - list2]

(* Out[1507]= {{76, 84}, {56}, {8, 
  14}, {89}, {42}, {5}, {62}, {76}, {62}, {21}, {39, 
  37}, {84}, {51}, {96}, {37}, {14}, {21}, {5}, {62}, {96}} *)

--- edit ---

Here is how one can restrict so that we only keep values that come within a threshold of the goal. I'll also use Map so that this will work in versions prior to Mathematica 10.1 or so.

Cases[
 Map[{#, nf[100 - #, {Infinity, 1.5}]} &, list2], {_, {__}}]

(* Out[1590]= {{96, {5}}, {39, {62}}, {62, {39, 
   37}}, {5, {96}}, {37, {62}}} *)

--- end edit ---

$\endgroup$
  • $\begingroup$ Fails on v9. Is it a v10 feature? $\endgroup$ – Dr. belisarius Mar 17 '16 at 17:56
  • $\begingroup$ The listability is, yes. In v9 I guess use Map. $\endgroup$ – Daniel Lichtblau Mar 17 '16 at 18:28
  • $\begingroup$ Thanks for your answer.But I'm very sorry for misunderstanding your meaning.As the Dr.belisarius's coustom function f,I can get the result like this list2[[#]]&/@f[list2,2,100.].But you? $\endgroup$ – yode Mar 17 '16 at 22:05
  • $\begingroup$ Why not also show the version for 10.1 and above $\endgroup$ – RunnyKine Mar 17 '16 at 22:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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