How to get all possible combinations of n number of data set?
You don't say how you want to assess the pairs of matrices, but if you have your matrices as per the code you showed with those names, then
g <- c("g11", "g12", "g13", "g21", "g22", "g23", "g31", "g32", "g33", "g2")
cmb <- combn(g, 2)
which gives:
> cmb
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] "g11" "g11" "g11" "g11" "g11" "g11" "g11" "g11" "g11" "g12" "g12" "g12"
[2,] "g12" "g13" "g21" "g22" "g23" "g31" "g32" "g33" "g2" "g13" "g21" "g22"
[,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
[1,] "g12" "g12" "g12" "g12" "g12" "g13" "g13" "g13" "g13" "g13" "g13" "g13"
[2,] "g23" "g31" "g32" "g33" "g2" "g21" "g22" "g23" "g31" "g32" "g33" "g2"
[,25] [,26] [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36]
[1,] "g21" "g21" "g21" "g21" "g21" "g21" "g22" "g22" "g22" "g22" "g22" "g23"
[2,] "g22" "g23" "g31" "g32" "g33" "g2" "g23" "g31" "g32" "g33" "g2" "g31"
[,37] [,38] [,39] [,40] [,41] [,42] [,43] [,44] [,45]
[1,] "g23" "g23" "g23" "g31" "g31" "g31" "g32" "g32" "g33"
[2,] "g32" "g33" "g2" "g32" "g33" "g2" "g33" "g2" "g2"
are the set of combinations of your matrices taken 2 at a time.
Then iterate over the columns of cmb
doing your assessment, e.g.:
FUN <- function(g, ...) {
## get the objects for the current pair
g1 <- get(g[1])
g2 <- get(g[2])
## bind together
dat <- rbind(g1, g2)
## something here to assess this combination
cpr2(dat)
}
assess <- apply(cmb, 2, FUN = FUN, ....)
Creating a list of all possible combinations from a set of items for n combination sizes
A recursion can do the job. The idea is to choose a letter, print it as a possibility and combine it with all letters after it:
#include <bits/stdc++.h>
using namespace std;
string letters[] = {"A", "B", "C", "D", "E"};
int alphabetSize = 5;
int combSizeLim = 3;
void gen(int index = 0, int combSize = 0, string comb = ""){
if(combSize > combSizeLim) return;
cout<<comb<<endl;
for(int i = index; i < alphabetSize; i++){
gen(i + 1, combSize + 1, comb + letters[i]);
}
}
int main(){
gen();
return 0;
}
OUTPUT:
A
AB
ABC
ABD
ABE
AC
ACD
ACE
AD
ADE
AE
B
BC
BCD
BCE
BD
BDE
BE
C
CD
CDE
CE
D
DE
E
Finding all possible combinations of numbers to reach a given sum
This problem can be solved with a recursive combinations of all possible sums filtering out those that reach the target. Here is the algorithm in Python:
def subset_sum(numbers, target, partial=[]):
s = sum(partial)
# check if the partial sum is equals to target
if s == target:
print "sum(%s)=%s" % (partial, target)
if s >= target:
return # if we reach the number why bother to continue
for i in range(len(numbers)):
n = numbers[i]
remaining = numbers[i+1:]
subset_sum(remaining, target, partial + [n])
if __name__ == "__main__":
subset_sum([3,9,8,4,5,7,10],15)
#Outputs:
#sum([3, 8, 4])=15
#sum([3, 5, 7])=15
#sum([8, 7])=15
#sum([5, 10])=15
This type of algorithms are very well explained in the following Stanford's Abstract Programming lecture - this video is very recommendable to understand how recursion works to generate permutations of solutions.
Edit
The above as a generator function, making it a bit more useful. Requires Python 3.3+ because of yield from
.
def subset_sum(numbers, target, partial=[], partial_sum=0):
if partial_sum == target:
yield partial
if partial_sum >= target:
return
for i, n in enumerate(numbers):
remaining = numbers[i + 1:]
yield from subset_sum(remaining, target, partial + [n], partial_sum + n)
Here is the Java version of the same algorithm:
package tmp;
import java.util.ArrayList;
import java.util.Arrays;
class SumSet {
static void sum_up_recursive(ArrayList<Integer> numbers, int target, ArrayList<Integer> partial) {
int s = 0;
for (int x: partial) s += x;
if (s == target)
System.out.println("sum("+Arrays.toString(partial.toArray())+")="+target);
if (s >= target)
return;
for(int i=0;i<numbers.size();i++) {
ArrayList<Integer> remaining = new ArrayList<Integer>();
int n = numbers.get(i);
for (int j=i+1; j<numbers.size();j++) remaining.add(numbers.get(j));
ArrayList<Integer> partial_rec = new ArrayList<Integer>(partial);
partial_rec.add(n);
sum_up_recursive(remaining,target,partial_rec);
}
}
static void sum_up(ArrayList<Integer> numbers, int target) {
sum_up_recursive(numbers,target,new ArrayList<Integer>());
}
public static void main(String args[]) {
Integer[] numbers = {3,9,8,4,5,7,10};
int target = 15;
sum_up(new ArrayList<Integer>(Arrays.asList(numbers)),target);
}
}
It is exactly the same heuristic. My Java is a bit rusty but I think is easy to understand.
C# conversion of Java solution: (by @JeremyThompson)
public static void Main(string[] args)
{
List<int> numbers = new List<int>() { 3, 9, 8, 4, 5, 7, 10 };
int target = 15;
sum_up(numbers, target);
}
private static void sum_up(List<int> numbers, int target)
{
sum_up_recursive(numbers, target, new List<int>());
}
private static void sum_up_recursive(List<int> numbers, int target, List<int> partial)
{
int s = 0;
foreach (int x in partial) s += x;
if (s == target)
Console.WriteLine("sum(" + string.Join(",", partial.ToArray()) + ")=" + target);
if (s >= target)
return;
for (int i = 0; i < numbers.Count; i++)
{
List<int> remaining = new List<int>();
int n = numbers[i];
for (int j = i + 1; j < numbers.Count; j++) remaining.Add(numbers[j]);
List<int> partial_rec = new List<int>(partial);
partial_rec.Add(n);
sum_up_recursive(remaining, target, partial_rec);
}
}
Ruby solution: (by @emaillenin)
def subset_sum(numbers, target, partial=[])
s = partial.inject 0, :+
# check if the partial sum is equals to target
puts "sum(#{partial})=#{target}" if s == target
return if s >= target # if we reach the number why bother to continue
(0..(numbers.length - 1)).each do |i|
n = numbers[i]
remaining = numbers.drop(i+1)
subset_sum(remaining, target, partial + [n])
end
end
subset_sum([3,9,8,4,5,7,10],15)
Edit: complexity discussion
As others mention this is an NP-hard problem. It can be solved in exponential time O(2^n), for instance for n=10 there will be 1024 possible solutions. If the targets you are trying to reach are in a low range then this algorithm works. So for instance:
subset_sum([1,2,3,4,5,6,7,8,9,10],100000)
generates 1024 branches because the target never gets to filter out possible solutions.
On the other hand subset_sum([1,2,3,4,5,6,7,8,9,10],10)
generates only 175 branches, because the target to reach 10
gets to filter out many combinations.
If N
and Target
are big numbers one should move into an approximate version of the solution.
How Do I Generate All Possible Combinations of the Variables In A Model In R?
use the step
function. This should give you the best model:
step(lm(h~., df),direction = 'both', trace = 0)
Call:
lm(formula = h ~ b + e + f, data = df)
Coefficients:
(Intercept) b e f
4.3494 -0.8705 -0.3266 1.2877
This model has the lowest AIC
. You can change trace = 1
, to look at the intermediate models that were run
How to get all possible combinations of a list’s elements?
Have a look at itertools.combinations:
itertools.combinations(iterable, r)
Return r length subsequences of elements from
the input iterable.Combinations are emitted in lexicographic sort order. So, if the
input iterable is sorted, the
combination tuples will be produced in
sorted order.
Since 2.6, batteries are included!
generate ALL possible combinations from a number of lists
If I understand your requirements correctly you don't have to pre-calculate the number of permutations. Instead you can use the "odometer" approach, keeping an array of indexes into your list of input lists, and incrementing the "odometer" at each iteration.
List<List<String>> input = new ArrayList<>();
input.add(Arrays.asList(new String[] {"S1", "S2", "S3"}));
input.add(Arrays.asList(new String[] {"S4", "S5"}));
input.add(Arrays.asList(new String[] {"S6", "S7"}));
int[] idx = new int[input.size()];
List<String> base = new ArrayList<>();
for(List<String> sl : input) base.add(sl.get(0));
List<List<String>> allCombinations = new ArrayList<>();
while(true)
{
allCombinations.add(new ArrayList<>(base));
int k=idx.length-1;
for(; k>=0; k--)
{
idx[k] += 1;
if(idx[k] < input.get(k).size())
{
base.set(k, input.get(k).get(idx[k]));
break;
}
idx[k] = 0;
base.set(k, input.get(k).get(idx[k]));
}
if(k < 0) break;
}
for(List<String> combo : allCombinations)
System.out.println(combo);
Output:
[S1, S4, S6]
[S1, S4, S7]
[S1, S5, S6]
[S1, S5, S7]
[S2, S4, S6]
[S2, S4, S7]
[S2, S5, S6]
[S2, S5, S7]
[S3, S4, S6]
[S3, S4, S7]
[S3, S5, S6]
[S3, S5, S7]
Get all possible combinations in a time-series data with variable daily readings
We could filter
where the 'record' is greater than 1, group_split
by 'row_number' and 'date', then bind the rows with the filter
ed data where the 'record' is 1
library(dplyr)
library(purrr)
out <- consumption %>%
filter(n > 1) %>%
group_split(date, rn = row_number()) %>%
map(~ bind_rows(consumption %>%
filter(n == 1), .x %>%
select(-rn)) %>%
arrange(date))
-output
> out
[[1]]
# A tibble: 4 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 31 3 1
4 2020-06-04 40 1 1
[[2]]
# A tibble: 4 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 32 3 2
4 2020-06-04 40 1 1
[[3]]
# A tibble: 4 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 33 3 3
4 2020-06-04 40 1 1
With the updated data, we create the row_number()
, then split
it by 'date' column (as in @ThomasIsCoding solution), use crossing
(from purrr
) to expand the data, and loop over the rows with pmap
, slice
the rows of the original data based on the row index
library(tidyr)
library(tibble)
consumption %>%
transmute(date, rn = row_number()) %>%
deframe %>%
split(names(.)) %>%
invoke(crossing, .) %>%
pmap(~ consumption %>%
slice(c(...))) %>%
unname
-output
[[1]]
# A tibble: 5 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 31 3 1
4 2020-06-04 40 1 1
5 2020-06-05 51 2 1
[[2]]
# A tibble: 5 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 31 3 1
4 2020-06-04 40 1 1
5 2020-06-05 52 2 2
[[3]]
# A tibble: 5 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 32 3 2
4 2020-06-04 40 1 1
5 2020-06-05 51 2 1
[[4]]
# A tibble: 5 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 32 3 2
4 2020-06-04 40 1 1
5 2020-06-05 52 2 2
[[5]]
# A tibble: 5 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 33 3 3
4 2020-06-04 40 1 1
5 2020-06-05 51 2 1
[[6]]
# A tibble: 5 x 4
date val n record
<date> <dbl> <int> <int>
1 2020-06-01 10 1 1
2 2020-06-02 20 1 1
3 2020-06-03 33 3 3
4 2020-06-04 40 1 1
5 2020-06-05 52 2 2
Related Topics
How to Install/Locate R.H and Rmath.H Header Files
Error in Xj[I]: Invalid Subscript Type 'List'
Netlogo - Misalignment with Imported Gis Shapefiles
Generating Split-Color Rectangles from Ggplot2 Geom_Raster()
How to Plot Grid Plots on a Same Page
R: How to Prompt The User for Input from The Console
Tidyr Separate Column Values into Character and Numeric Using Regex
Make a Column with Duplicated Values Unique in a Dataframe
Segfault in R Using Reshape2 Package and Dcast
Force Ggplot to Evaluate Counter Variable
How to Use Stat_Function by Group
Use Endpoints Function to Get Start Points Instead
How to Programmatically Create Binary Columns Based on a Categorical Variable in Data.Table
R Find Overlap Among Time Periods