title: How to select a subset of least resembling combinations of a common vector?
body: <p>I need to select 10 times different combinations of 15 items from a common set of 30 items, with several constraints.</p>
  
  <p>First constraint: for each of the 10 combinations, I need to remove three items that should not be present in that specific combination. Let's say wf01, wf02 and wf03 for the first combination; wf04, wf05 and wf06 for the second combination and so on.</p>
  
  <p>Second constraint: over the ten combinations, each item should be present the same number of times (5).</p>
  
  <p>Third constraint: the ten combinations should be as different as possible from one another (i.e. they should avoid sharing common items as much as possible).</p>
  
  <p>I am currently doing that in Excel, but I guess there should be a more efficient way in R!</p>
  
  <p>Here is my coding so far:</p>
  
  <pre><code># Data: 30 items (pictures to choose from)
  
  PictureNames &lt;- c("wf01", "wf02", "wf03", "wf04", "wf05", "wf06", "wf07", "wf08", "wf09", "wf10", "wf11", "wf12", "wf13", "wf14", "wf15", "wf16", "wf17", "wf18", "wf19", "wf20", "wf21", "wf22", "wf23", "wf24", "wf25", "wf26", "wf27", "wf28", "wf29", "wf30")
  
  set.seed(10)
  
  sample01 &lt;- sample(PictureNames[4:30], 15)
  sample02 &lt;- sample(PictureNames[c(1:3, 7:30)], 15)
  sample03 &lt;- sample(PictureNames[c(1:6, 10:30)], 15)
  sample04 &lt;- sample(PictureNames[c(1:9, 13:30)], 15)
  sample05 &lt;- sample(PictureNames[c(1:12, 16:30)], 15)
  sample06 &lt;- sample(PictureNames[c(1:15, 19:30)], 15)
  sample07 &lt;- sample(PictureNames[c(1:18, 22:30)], 15)
  sample08 &lt;- sample(PictureNames[c(1:21, 25:30)], 15)
  sample09 &lt;- sample(PictureNames[c(1:24, 28:30)], 15)
  sample10 &lt;- sample(PictureNames[c(1:27)], 15)
  </code></pre>
  
  <p>Up to now, I implemented the constraints manually in Excel (I know…). First, I ensured that each item was present only 5 times across the 10 different combinations. Then, I created a matrix with the name of the picture as row and column. Each cell counted how many times a pair of pictures was present in the same combination across the 10 combinations. The value ranges from 0 (pictures never together) to 5 (pictures always together). Then, by manually shifting pictures between combinations, I managed to avoid the presence of 0s and 5s in this matrix. Afterwards, I implemented an optimisation task, where each picture should be associated with as many different pictures as possible, while respecting the previous constraints. To do so, for each picture I calculate the standard deviation of its column (or row) values. Then, I calculated the standard deviation of these standard deviations. Any shift that reduces this value while respecting the other constraints is retained. I managed to arrive to a standard deviation of 0.036, but I have no idea whether this is the best result I can get. Any help would be greatly appreciated!!!</p>
  
  <p>Thanks in advance!</p>
  
  <h3>EDIT</h3>
  
  <p>After @roman-luštrik's remark, here is my new version of the code. Still horrible, and not so close from optimising the matrix, but slowly getting there!</p>
  
  <pre><code># Data: 30 items (pictures to choose from)
  
  PictureNames &lt;- data.frame(Names = c("wf01", "wf02", "wf03", "wf04", "wf05",
                "wf06", "wf07", "wf08", "wf09", "wf10", "wf11", "wf12", "wf13",
                "wf14", "wf15", "wf16", "wf17", "wf18", "wf19", "wf20", "wf21",
                "wf22", "wf23", "wf24", "wf25", "wf26", "wf27", "wf28", "wf29",
                "wf30"), stringsAsFactors = FALSE)
  
  library(dplyr)
  
  set.seed(10)
  
  sample01 &lt;- data.frame(Names = sort(sample(PictureNames$Names[c(4:30)], 15)))
  sample02 &lt;- anti_join(PictureNames, sample01)
  sample03 &lt;- data.frame(Names = sort(sample(PictureNames$Names[c(1:6, 10:30)], 15)))
  sample04 &lt;- anti_join(PictureNames, sample03)
  sample05 &lt;- data.frame(Names = sort(sample(PictureNames$Names[c(1:12, 16:30)], 15)))
  sample06 &lt;- anti_join(PictureNames, sample05)
  sample07 &lt;- data.frame(Names = sort(sample(PictureNames$Names[c(1:18, 22:30)], 15)))
  sample08 &lt;- anti_join(PictureNames, sample07)
  sample09 &lt;- data.frame(Names = sort(sample(PictureNames$Names[c(1:24, 28:30)], 15)))
  sample10 &lt;- anti_join(PictureNames, sample09)
  
  AllSamples &lt;- data.frame(sample01, sample02, sample03, sample04, sample05,
                       sample06, sample07, sample08, sample09, sample10)
  
  colnames(AllSamples) &lt;- c("sA", "sB", "sC", "sD", "sE", "sF", "sG", "sH", "sI", "sJ")
  
  CoOccurMat &lt;- matrix(nrow = length(PictureNames$Names), ncol = length(PictureNames$Names),
                   dimnames = c(PictureNames, PictureNames))
  
  for(j in 1:length(PictureNames$Names)){
    for(i in 1:length(PictureNames$Names)){
  CoOccurMat[i,j] &lt;- sum(ifelse(sapply(PictureNames,
                         function(x)colSums(xor(AllSamples == PictureNames$Names[j],
                         AllSamples == PictureNames$Names[i]))) == 2, 1, 0))
  ColSd &lt;- apply(CoOccurMat, 2, sd)
  OverallSd &lt;- sd(ColSd)
    }
  }
  
  CoOccurMat
  ColSd
  OverallSd
  </code></pre>