How to generate and filter efficiently all combinations of a list of list productHow do I check if a list is empty?How do I sort a list of dictionaries by a value of the dictionary?How to randomly select an item from a list?How do you split a list into evenly sized chunks?How to make a flat list out of list of listsHow do I get the number of elements in a list?How do I concatenate two lists in Python?How to clone or copy a list?How do I list all files of a directory?How to read a file line-by-line into a list?
I asked for a graduate student position from a professor. He replied "welcome". What does that mean?
What is and what isn't ullage in rocket science?
Were Roman public roads build by private companies?
Real mode flat model
Planar regular languages
Parallel resistance in electric circuits
Why did it become so much more expensive to start a university?
POSIX compatible way to get user name associated with a user ID
Newly created XFS filesystem shows 78 GB used
Relocation error involving libgnutls.so.30, error code (127) after last updates
How are unbalanced coaxial cables used for broadcasting TV signals without any problems?
Does my opponent need to prove his creature has morph?
Why do sellers care about down payments?
How are aircraft depainted?
Why did they ever make smaller than full-frame sensors?
Cannot find Database Mail feature in SQL Server Express 2012 SP1
2000s space film where an alien species has almost wiped out the human race in a war
What was the ultimate objective of The Party in 1984?
Diffraction of a wave passing through double slits
Can you add polynomial terms to multiple linear regression?
What is my breathable atmosphere composed of?
Will the UK home office know about 5 previous visa rejections in other countries?
getting syntax error in simple bash script
Telling my mother that I have anorexia without panicking her
How to generate and filter efficiently all combinations of a list of list product
How do I check if a list is empty?How do I sort a list of dictionaries by a value of the dictionary?How to randomly select an item from a list?How do you split a list into evenly sized chunks?How to make a flat list out of list of listsHow do I get the number of elements in a list?How do I concatenate two lists in Python?How to clone or copy a list?How do I list all files of a directory?How to read a file line-by-line into a list?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Hello guys here is the problem. I have something like this in input [[1,2,3],[4,5,6],[7,8,9]]...etc
And i want to generate all possible combination of product of those list and then multiply each elements of the resulting combination beetween them to finally filter the result in a interval.
So first input a n list [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]...etc
Which will then give (1,4,7,10)
(1,4,7,11)
(1,4,7,12)
and so on
Then combination of those result for k in n like (1,4,7)(1,4,10)(1,7,10) for the first row
The multiplication of x as 1*4*7 = 28, 1*4*10 = 40, 1*7*10 = 70
And from this get only the unique combination and the result need in the interval choosed beforehand : if x > 50 and x < 100 i will get (1,7,10) : 70
I did try
def mult(lst): #A function mult i'm using later
r = 1
for element in lst:
r *= element
return round(r)
s = [] #Where i add my list of list
for i in range(int(input1)):
b = input("This is line %s : " % (i+1)).split()
for i in range(len(b)):
b[i] = float(b[i])
s.append(b)
low_result = input("Expected low_result : ")
high_result = input("Expected high_result : ")
combine = []
my_list = []
for element in itertools.product(*s):
l= [float(x) for x in element]
comb = itertools.combinations([*l], int(input2))
for i in list(comb):
combine.append(i)
res = mult(i)
if res >= int(low_result) and res <= int(high_result):
my_list.append(res)
f = open("list_result.txt","a+")
f.write("%s : result is %sn" % (i, res))
f.close()
And it always result in memory error cause there is too many variation with what i'm seeking.
What i would like is a way to generate from a list of list of 20 elements or more all the product and resulting combination of k in n for the result(interval) that i need.
python python-3.x
|
show 1 more comment
Hello guys here is the problem. I have something like this in input [[1,2,3],[4,5,6],[7,8,9]]...etc
And i want to generate all possible combination of product of those list and then multiply each elements of the resulting combination beetween them to finally filter the result in a interval.
So first input a n list [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]...etc
Which will then give (1,4,7,10)
(1,4,7,11)
(1,4,7,12)
and so on
Then combination of those result for k in n like (1,4,7)(1,4,10)(1,7,10) for the first row
The multiplication of x as 1*4*7 = 28, 1*4*10 = 40, 1*7*10 = 70
And from this get only the unique combination and the result need in the interval choosed beforehand : if x > 50 and x < 100 i will get (1,7,10) : 70
I did try
def mult(lst): #A function mult i'm using later
r = 1
for element in lst:
r *= element
return round(r)
s = [] #Where i add my list of list
for i in range(int(input1)):
b = input("This is line %s : " % (i+1)).split()
for i in range(len(b)):
b[i] = float(b[i])
s.append(b)
low_result = input("Expected low_result : ")
high_result = input("Expected high_result : ")
combine = []
my_list = []
for element in itertools.product(*s):
l= [float(x) for x in element]
comb = itertools.combinations([*l], int(input2))
for i in list(comb):
combine.append(i)
res = mult(i)
if res >= int(low_result) and res <= int(high_result):
my_list.append(res)
f = open("list_result.txt","a+")
f.write("%s : result is %sn" % (i, res))
f.close()
And it always result in memory error cause there is too many variation with what i'm seeking.
What i would like is a way to generate from a list of list of 20 elements or more all the product and resulting combination of k in n for the result(interval) that i need.
python python-3.x
If you are looking for the AXBXCX... And then trying to take a subset dim = n-1 , might as well start with choosing (n-1) spaces? Or am I missing something ?
– Born Tbe Wasted
Mar 28 at 10:33
Try to replace the lists by generators, replace [] by () they will save you some memory
– geckos
Mar 28 at 10:41
Also [*l] is the same as l if l is a list
– geckos
Mar 28 at 10:42
And I think numpy will help you with some performance. But I'm not the Python numbers guy
– geckos
Mar 28 at 10:43
If i replace [] by () it won't do with the combination because it will give it too much argument no ?
– Exramas
Mar 28 at 11:50
|
show 1 more comment
Hello guys here is the problem. I have something like this in input [[1,2,3],[4,5,6],[7,8,9]]...etc
And i want to generate all possible combination of product of those list and then multiply each elements of the resulting combination beetween them to finally filter the result in a interval.
So first input a n list [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]...etc
Which will then give (1,4,7,10)
(1,4,7,11)
(1,4,7,12)
and so on
Then combination of those result for k in n like (1,4,7)(1,4,10)(1,7,10) for the first row
The multiplication of x as 1*4*7 = 28, 1*4*10 = 40, 1*7*10 = 70
And from this get only the unique combination and the result need in the interval choosed beforehand : if x > 50 and x < 100 i will get (1,7,10) : 70
I did try
def mult(lst): #A function mult i'm using later
r = 1
for element in lst:
r *= element
return round(r)
s = [] #Where i add my list of list
for i in range(int(input1)):
b = input("This is line %s : " % (i+1)).split()
for i in range(len(b)):
b[i] = float(b[i])
s.append(b)
low_result = input("Expected low_result : ")
high_result = input("Expected high_result : ")
combine = []
my_list = []
for element in itertools.product(*s):
l= [float(x) for x in element]
comb = itertools.combinations([*l], int(input2))
for i in list(comb):
combine.append(i)
res = mult(i)
if res >= int(low_result) and res <= int(high_result):
my_list.append(res)
f = open("list_result.txt","a+")
f.write("%s : result is %sn" % (i, res))
f.close()
And it always result in memory error cause there is too many variation with what i'm seeking.
What i would like is a way to generate from a list of list of 20 elements or more all the product and resulting combination of k in n for the result(interval) that i need.
python python-3.x
Hello guys here is the problem. I have something like this in input [[1,2,3],[4,5,6],[7,8,9]]...etc
And i want to generate all possible combination of product of those list and then multiply each elements of the resulting combination beetween them to finally filter the result in a interval.
So first input a n list [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]...etc
Which will then give (1,4,7,10)
(1,4,7,11)
(1,4,7,12)
and so on
Then combination of those result for k in n like (1,4,7)(1,4,10)(1,7,10) for the first row
The multiplication of x as 1*4*7 = 28, 1*4*10 = 40, 1*7*10 = 70
And from this get only the unique combination and the result need in the interval choosed beforehand : if x > 50 and x < 100 i will get (1,7,10) : 70
I did try
def mult(lst): #A function mult i'm using later
r = 1
for element in lst:
r *= element
return round(r)
s = [] #Where i add my list of list
for i in range(int(input1)):
b = input("This is line %s : " % (i+1)).split()
for i in range(len(b)):
b[i] = float(b[i])
s.append(b)
low_result = input("Expected low_result : ")
high_result = input("Expected high_result : ")
combine = []
my_list = []
for element in itertools.product(*s):
l= [float(x) for x in element]
comb = itertools.combinations([*l], int(input2))
for i in list(comb):
combine.append(i)
res = mult(i)
if res >= int(low_result) and res <= int(high_result):
my_list.append(res)
f = open("list_result.txt","a+")
f.write("%s : result is %sn" % (i, res))
f.close()
And it always result in memory error cause there is too many variation with what i'm seeking.
What i would like is a way to generate from a list of list of 20 elements or more all the product and resulting combination of k in n for the result(interval) that i need.
python python-3.x
python python-3.x
edited Mar 28 at 10:26
Aran-Fey
20.8k5 gold badges45 silver badges84 bronze badges
20.8k5 gold badges45 silver badges84 bronze badges
asked Mar 28 at 10:26
ExramasExramas
32 bronze badges
32 bronze badges
If you are looking for the AXBXCX... And then trying to take a subset dim = n-1 , might as well start with choosing (n-1) spaces? Or am I missing something ?
– Born Tbe Wasted
Mar 28 at 10:33
Try to replace the lists by generators, replace [] by () they will save you some memory
– geckos
Mar 28 at 10:41
Also [*l] is the same as l if l is a list
– geckos
Mar 28 at 10:42
And I think numpy will help you with some performance. But I'm not the Python numbers guy
– geckos
Mar 28 at 10:43
If i replace [] by () it won't do with the combination because it will give it too much argument no ?
– Exramas
Mar 28 at 11:50
|
show 1 more comment
If you are looking for the AXBXCX... And then trying to take a subset dim = n-1 , might as well start with choosing (n-1) spaces? Or am I missing something ?
– Born Tbe Wasted
Mar 28 at 10:33
Try to replace the lists by generators, replace [] by () they will save you some memory
– geckos
Mar 28 at 10:41
Also [*l] is the same as l if l is a list
– geckos
Mar 28 at 10:42
And I think numpy will help you with some performance. But I'm not the Python numbers guy
– geckos
Mar 28 at 10:43
If i replace [] by () it won't do with the combination because it will give it too much argument no ?
– Exramas
Mar 28 at 11:50
If you are looking for the AXBXCX... And then trying to take a subset dim = n-1 , might as well start with choosing (n-1) spaces? Or am I missing something ?
– Born Tbe Wasted
Mar 28 at 10:33
If you are looking for the AXBXCX... And then trying to take a subset dim = n-1 , might as well start with choosing (n-1) spaces? Or am I missing something ?
– Born Tbe Wasted
Mar 28 at 10:33
Try to replace the lists by generators, replace [] by () they will save you some memory
– geckos
Mar 28 at 10:41
Try to replace the lists by generators, replace [] by () they will save you some memory
– geckos
Mar 28 at 10:41
Also [*l] is the same as l if l is a list
– geckos
Mar 28 at 10:42
Also [*l] is the same as l if l is a list
– geckos
Mar 28 at 10:42
And I think numpy will help you with some performance. But I'm not the Python numbers guy
– geckos
Mar 28 at 10:43
And I think numpy will help you with some performance. But I'm not the Python numbers guy
– geckos
Mar 28 at 10:43
If i replace [] by () it won't do with the combination because it will give it too much argument no ?
– Exramas
Mar 28 at 11:50
If i replace [] by () it won't do with the combination because it will give it too much argument no ?
– Exramas
Mar 28 at 11:50
|
show 1 more comment
1 Answer
1
active
oldest
votes
As suggested above, I think this can be done without exploding your memory by never holding an array in memory at any time. But the main issue is then runtime.
The maths
As written we are:
- Producing every combination of
m
rows ofn
itemsn ** m
- Then taking a choice of
c
items from thosem
valuesC(m, c)
This is very large. If we have m=25
rows, of n=3
items each and pick c=3
items in them we get:
= n ** m * C(m, c)
= 3 ** 25 * 2300
- n Choose r calculator= 1.948763802×10¹⁵
If instead we:
- Choose
c
rows from them
rows:C(m, c)
as before - Then pick every combination of
n
items from thesec
rows:n ** c
With m=25
rows, of n=3
items each and pick c=3
items in them we get:
- =
n ** c * C(m, c)
- =
3 ** 3 * 2300
- =
20700
This is now a solvable problem.
The code
from itertools import product, combinations
def mult(values, min_value, max_value):
"""
Multiply together the values, but return None if we get too big or too
small
"""
output = 1
for value in values:
output *= value
# Early return if we go too big
if output > max_value:
return None
# Early return if we goto zero (from which we never return)
if output == 0 and min_value != 0:
return None
if output < min_value:
return None
return output
def yield_valid_combos(values, choose, min_value, max_value):
# No doubt an even fancier list compression would get this too
for rows in combinations(values, choose):
for combos in product(*rows):
value = mult(combos, min_value, max_value)
if value is not None:
yield combos, value
values = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
with open('list_result.txt', 'w') as fh:
for selection, value in yield_valid_combos(
values, choose=3, min_value=50, max_value=100):
fh.write(': result is n'.format(selection, value))
This solution also returns no duplicate answers (unless the same value appears in multiple rows).
As an optimisation the multiplication method attempts to return early if we detect the result will be too big or small. We also only open the file once and then keep adding rows to it as they come.
Further optimisation
You can also optimise your set of values ahead of time by screening out values which cannot contribute to a solution. But for smaller values of c
, you may find this is not even necessary.
The smallest possible combination of values is c
items from the set of the smallest values in each row. If we take the c - 1
smallest items from the set of smallest values, mutliply them together and then divide the maximum by this number, it gives us an upper bound for the largest value which can be in a solution. We can then then screen out all values above this value (cutting down on permutations)
Sadly the values does not lokk like these more like [[1.16,6.3,12],[1.27,5.5,9],[2.42,3.3,2.85],[1.3,5.4,9.5],[2.78,3.35,2.32],[2.45,2,1.88]] up to maybe 25 element or more. That's why i'm really curious about the way you present at the end of your answer cause the time need for treating all those combination look near infinite no ?
– Exramas
Mar 28 at 12:50
It's possible to generalise the logic above for arbitrary values. If we collect the set of the smallest values from each set, we can create an upper bound for the largest value that can be a part of our solution by: removing the largest value from this set, multiplying the rest together, dividing our maximum by that value. We can then remove values from sets which are above this value. This will speed up the process as it cuts on permutations, but if we find any particular set is empty, we also know there is no solution before we start.
– Jon Betts
Mar 28 at 13:31
Ahh... sorry it's actually take thechoose - 1
smallest values from the set of smallest values, then divide the max by that.
– Jon Betts
Mar 28 at 13:39
I think I've cracked it, the product and the choice should be the other way around... I'll update the answer.
– Jon Betts
Mar 28 at 14:03
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55395280%2fhow-to-generate-and-filter-efficiently-all-combinations-of-a-list-of-list-produc%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
As suggested above, I think this can be done without exploding your memory by never holding an array in memory at any time. But the main issue is then runtime.
The maths
As written we are:
- Producing every combination of
m
rows ofn
itemsn ** m
- Then taking a choice of
c
items from thosem
valuesC(m, c)
This is very large. If we have m=25
rows, of n=3
items each and pick c=3
items in them we get:
= n ** m * C(m, c)
= 3 ** 25 * 2300
- n Choose r calculator= 1.948763802×10¹⁵
If instead we:
- Choose
c
rows from them
rows:C(m, c)
as before - Then pick every combination of
n
items from thesec
rows:n ** c
With m=25
rows, of n=3
items each and pick c=3
items in them we get:
- =
n ** c * C(m, c)
- =
3 ** 3 * 2300
- =
20700
This is now a solvable problem.
The code
from itertools import product, combinations
def mult(values, min_value, max_value):
"""
Multiply together the values, but return None if we get too big or too
small
"""
output = 1
for value in values:
output *= value
# Early return if we go too big
if output > max_value:
return None
# Early return if we goto zero (from which we never return)
if output == 0 and min_value != 0:
return None
if output < min_value:
return None
return output
def yield_valid_combos(values, choose, min_value, max_value):
# No doubt an even fancier list compression would get this too
for rows in combinations(values, choose):
for combos in product(*rows):
value = mult(combos, min_value, max_value)
if value is not None:
yield combos, value
values = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
with open('list_result.txt', 'w') as fh:
for selection, value in yield_valid_combos(
values, choose=3, min_value=50, max_value=100):
fh.write(': result is n'.format(selection, value))
This solution also returns no duplicate answers (unless the same value appears in multiple rows).
As an optimisation the multiplication method attempts to return early if we detect the result will be too big or small. We also only open the file once and then keep adding rows to it as they come.
Further optimisation
You can also optimise your set of values ahead of time by screening out values which cannot contribute to a solution. But for smaller values of c
, you may find this is not even necessary.
The smallest possible combination of values is c
items from the set of the smallest values in each row. If we take the c - 1
smallest items from the set of smallest values, mutliply them together and then divide the maximum by this number, it gives us an upper bound for the largest value which can be in a solution. We can then then screen out all values above this value (cutting down on permutations)
Sadly the values does not lokk like these more like [[1.16,6.3,12],[1.27,5.5,9],[2.42,3.3,2.85],[1.3,5.4,9.5],[2.78,3.35,2.32],[2.45,2,1.88]] up to maybe 25 element or more. That's why i'm really curious about the way you present at the end of your answer cause the time need for treating all those combination look near infinite no ?
– Exramas
Mar 28 at 12:50
It's possible to generalise the logic above for arbitrary values. If we collect the set of the smallest values from each set, we can create an upper bound for the largest value that can be a part of our solution by: removing the largest value from this set, multiplying the rest together, dividing our maximum by that value. We can then remove values from sets which are above this value. This will speed up the process as it cuts on permutations, but if we find any particular set is empty, we also know there is no solution before we start.
– Jon Betts
Mar 28 at 13:31
Ahh... sorry it's actually take thechoose - 1
smallest values from the set of smallest values, then divide the max by that.
– Jon Betts
Mar 28 at 13:39
I think I've cracked it, the product and the choice should be the other way around... I'll update the answer.
– Jon Betts
Mar 28 at 14:03
add a comment
|
As suggested above, I think this can be done without exploding your memory by never holding an array in memory at any time. But the main issue is then runtime.
The maths
As written we are:
- Producing every combination of
m
rows ofn
itemsn ** m
- Then taking a choice of
c
items from thosem
valuesC(m, c)
This is very large. If we have m=25
rows, of n=3
items each and pick c=3
items in them we get:
= n ** m * C(m, c)
= 3 ** 25 * 2300
- n Choose r calculator= 1.948763802×10¹⁵
If instead we:
- Choose
c
rows from them
rows:C(m, c)
as before - Then pick every combination of
n
items from thesec
rows:n ** c
With m=25
rows, of n=3
items each and pick c=3
items in them we get:
- =
n ** c * C(m, c)
- =
3 ** 3 * 2300
- =
20700
This is now a solvable problem.
The code
from itertools import product, combinations
def mult(values, min_value, max_value):
"""
Multiply together the values, but return None if we get too big or too
small
"""
output = 1
for value in values:
output *= value
# Early return if we go too big
if output > max_value:
return None
# Early return if we goto zero (from which we never return)
if output == 0 and min_value != 0:
return None
if output < min_value:
return None
return output
def yield_valid_combos(values, choose, min_value, max_value):
# No doubt an even fancier list compression would get this too
for rows in combinations(values, choose):
for combos in product(*rows):
value = mult(combos, min_value, max_value)
if value is not None:
yield combos, value
values = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
with open('list_result.txt', 'w') as fh:
for selection, value in yield_valid_combos(
values, choose=3, min_value=50, max_value=100):
fh.write(': result is n'.format(selection, value))
This solution also returns no duplicate answers (unless the same value appears in multiple rows).
As an optimisation the multiplication method attempts to return early if we detect the result will be too big or small. We also only open the file once and then keep adding rows to it as they come.
Further optimisation
You can also optimise your set of values ahead of time by screening out values which cannot contribute to a solution. But for smaller values of c
, you may find this is not even necessary.
The smallest possible combination of values is c
items from the set of the smallest values in each row. If we take the c - 1
smallest items from the set of smallest values, mutliply them together and then divide the maximum by this number, it gives us an upper bound for the largest value which can be in a solution. We can then then screen out all values above this value (cutting down on permutations)
Sadly the values does not lokk like these more like [[1.16,6.3,12],[1.27,5.5,9],[2.42,3.3,2.85],[1.3,5.4,9.5],[2.78,3.35,2.32],[2.45,2,1.88]] up to maybe 25 element or more. That's why i'm really curious about the way you present at the end of your answer cause the time need for treating all those combination look near infinite no ?
– Exramas
Mar 28 at 12:50
It's possible to generalise the logic above for arbitrary values. If we collect the set of the smallest values from each set, we can create an upper bound for the largest value that can be a part of our solution by: removing the largest value from this set, multiplying the rest together, dividing our maximum by that value. We can then remove values from sets which are above this value. This will speed up the process as it cuts on permutations, but if we find any particular set is empty, we also know there is no solution before we start.
– Jon Betts
Mar 28 at 13:31
Ahh... sorry it's actually take thechoose - 1
smallest values from the set of smallest values, then divide the max by that.
– Jon Betts
Mar 28 at 13:39
I think I've cracked it, the product and the choice should be the other way around... I'll update the answer.
– Jon Betts
Mar 28 at 14:03
add a comment
|
As suggested above, I think this can be done without exploding your memory by never holding an array in memory at any time. But the main issue is then runtime.
The maths
As written we are:
- Producing every combination of
m
rows ofn
itemsn ** m
- Then taking a choice of
c
items from thosem
valuesC(m, c)
This is very large. If we have m=25
rows, of n=3
items each and pick c=3
items in them we get:
= n ** m * C(m, c)
= 3 ** 25 * 2300
- n Choose r calculator= 1.948763802×10¹⁵
If instead we:
- Choose
c
rows from them
rows:C(m, c)
as before - Then pick every combination of
n
items from thesec
rows:n ** c
With m=25
rows, of n=3
items each and pick c=3
items in them we get:
- =
n ** c * C(m, c)
- =
3 ** 3 * 2300
- =
20700
This is now a solvable problem.
The code
from itertools import product, combinations
def mult(values, min_value, max_value):
"""
Multiply together the values, but return None if we get too big or too
small
"""
output = 1
for value in values:
output *= value
# Early return if we go too big
if output > max_value:
return None
# Early return if we goto zero (from which we never return)
if output == 0 and min_value != 0:
return None
if output < min_value:
return None
return output
def yield_valid_combos(values, choose, min_value, max_value):
# No doubt an even fancier list compression would get this too
for rows in combinations(values, choose):
for combos in product(*rows):
value = mult(combos, min_value, max_value)
if value is not None:
yield combos, value
values = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
with open('list_result.txt', 'w') as fh:
for selection, value in yield_valid_combos(
values, choose=3, min_value=50, max_value=100):
fh.write(': result is n'.format(selection, value))
This solution also returns no duplicate answers (unless the same value appears in multiple rows).
As an optimisation the multiplication method attempts to return early if we detect the result will be too big or small. We also only open the file once and then keep adding rows to it as they come.
Further optimisation
You can also optimise your set of values ahead of time by screening out values which cannot contribute to a solution. But for smaller values of c
, you may find this is not even necessary.
The smallest possible combination of values is c
items from the set of the smallest values in each row. If we take the c - 1
smallest items from the set of smallest values, mutliply them together and then divide the maximum by this number, it gives us an upper bound for the largest value which can be in a solution. We can then then screen out all values above this value (cutting down on permutations)
As suggested above, I think this can be done without exploding your memory by never holding an array in memory at any time. But the main issue is then runtime.
The maths
As written we are:
- Producing every combination of
m
rows ofn
itemsn ** m
- Then taking a choice of
c
items from thosem
valuesC(m, c)
This is very large. If we have m=25
rows, of n=3
items each and pick c=3
items in them we get:
= n ** m * C(m, c)
= 3 ** 25 * 2300
- n Choose r calculator= 1.948763802×10¹⁵
If instead we:
- Choose
c
rows from them
rows:C(m, c)
as before - Then pick every combination of
n
items from thesec
rows:n ** c
With m=25
rows, of n=3
items each and pick c=3
items in them we get:
- =
n ** c * C(m, c)
- =
3 ** 3 * 2300
- =
20700
This is now a solvable problem.
The code
from itertools import product, combinations
def mult(values, min_value, max_value):
"""
Multiply together the values, but return None if we get too big or too
small
"""
output = 1
for value in values:
output *= value
# Early return if we go too big
if output > max_value:
return None
# Early return if we goto zero (from which we never return)
if output == 0 and min_value != 0:
return None
if output < min_value:
return None
return output
def yield_valid_combos(values, choose, min_value, max_value):
# No doubt an even fancier list compression would get this too
for rows in combinations(values, choose):
for combos in product(*rows):
value = mult(combos, min_value, max_value)
if value is not None:
yield combos, value
values = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
with open('list_result.txt', 'w') as fh:
for selection, value in yield_valid_combos(
values, choose=3, min_value=50, max_value=100):
fh.write(': result is n'.format(selection, value))
This solution also returns no duplicate answers (unless the same value appears in multiple rows).
As an optimisation the multiplication method attempts to return early if we detect the result will be too big or small. We also only open the file once and then keep adding rows to it as they come.
Further optimisation
You can also optimise your set of values ahead of time by screening out values which cannot contribute to a solution. But for smaller values of c
, you may find this is not even necessary.
The smallest possible combination of values is c
items from the set of the smallest values in each row. If we take the c - 1
smallest items from the set of smallest values, mutliply them together and then divide the maximum by this number, it gives us an upper bound for the largest value which can be in a solution. We can then then screen out all values above this value (cutting down on permutations)
edited Mar 28 at 14:23
answered Mar 28 at 12:00
Jon BettsJon Betts
1,5987 silver badges9 bronze badges
1,5987 silver badges9 bronze badges
Sadly the values does not lokk like these more like [[1.16,6.3,12],[1.27,5.5,9],[2.42,3.3,2.85],[1.3,5.4,9.5],[2.78,3.35,2.32],[2.45,2,1.88]] up to maybe 25 element or more. That's why i'm really curious about the way you present at the end of your answer cause the time need for treating all those combination look near infinite no ?
– Exramas
Mar 28 at 12:50
It's possible to generalise the logic above for arbitrary values. If we collect the set of the smallest values from each set, we can create an upper bound for the largest value that can be a part of our solution by: removing the largest value from this set, multiplying the rest together, dividing our maximum by that value. We can then remove values from sets which are above this value. This will speed up the process as it cuts on permutations, but if we find any particular set is empty, we also know there is no solution before we start.
– Jon Betts
Mar 28 at 13:31
Ahh... sorry it's actually take thechoose - 1
smallest values from the set of smallest values, then divide the max by that.
– Jon Betts
Mar 28 at 13:39
I think I've cracked it, the product and the choice should be the other way around... I'll update the answer.
– Jon Betts
Mar 28 at 14:03
add a comment
|
Sadly the values does not lokk like these more like [[1.16,6.3,12],[1.27,5.5,9],[2.42,3.3,2.85],[1.3,5.4,9.5],[2.78,3.35,2.32],[2.45,2,1.88]] up to maybe 25 element or more. That's why i'm really curious about the way you present at the end of your answer cause the time need for treating all those combination look near infinite no ?
– Exramas
Mar 28 at 12:50
It's possible to generalise the logic above for arbitrary values. If we collect the set of the smallest values from each set, we can create an upper bound for the largest value that can be a part of our solution by: removing the largest value from this set, multiplying the rest together, dividing our maximum by that value. We can then remove values from sets which are above this value. This will speed up the process as it cuts on permutations, but if we find any particular set is empty, we also know there is no solution before we start.
– Jon Betts
Mar 28 at 13:31
Ahh... sorry it's actually take thechoose - 1
smallest values from the set of smallest values, then divide the max by that.
– Jon Betts
Mar 28 at 13:39
I think I've cracked it, the product and the choice should be the other way around... I'll update the answer.
– Jon Betts
Mar 28 at 14:03
Sadly the values does not lokk like these more like [[1.16,6.3,12],[1.27,5.5,9],[2.42,3.3,2.85],[1.3,5.4,9.5],[2.78,3.35,2.32],[2.45,2,1.88]] up to maybe 25 element or more. That's why i'm really curious about the way you present at the end of your answer cause the time need for treating all those combination look near infinite no ?
– Exramas
Mar 28 at 12:50
Sadly the values does not lokk like these more like [[1.16,6.3,12],[1.27,5.5,9],[2.42,3.3,2.85],[1.3,5.4,9.5],[2.78,3.35,2.32],[2.45,2,1.88]] up to maybe 25 element or more. That's why i'm really curious about the way you present at the end of your answer cause the time need for treating all those combination look near infinite no ?
– Exramas
Mar 28 at 12:50
It's possible to generalise the logic above for arbitrary values. If we collect the set of the smallest values from each set, we can create an upper bound for the largest value that can be a part of our solution by: removing the largest value from this set, multiplying the rest together, dividing our maximum by that value. We can then remove values from sets which are above this value. This will speed up the process as it cuts on permutations, but if we find any particular set is empty, we also know there is no solution before we start.
– Jon Betts
Mar 28 at 13:31
It's possible to generalise the logic above for arbitrary values. If we collect the set of the smallest values from each set, we can create an upper bound for the largest value that can be a part of our solution by: removing the largest value from this set, multiplying the rest together, dividing our maximum by that value. We can then remove values from sets which are above this value. This will speed up the process as it cuts on permutations, but if we find any particular set is empty, we also know there is no solution before we start.
– Jon Betts
Mar 28 at 13:31
Ahh... sorry it's actually take the
choose - 1
smallest values from the set of smallest values, then divide the max by that.– Jon Betts
Mar 28 at 13:39
Ahh... sorry it's actually take the
choose - 1
smallest values from the set of smallest values, then divide the max by that.– Jon Betts
Mar 28 at 13:39
I think I've cracked it, the product and the choice should be the other way around... I'll update the answer.
– Jon Betts
Mar 28 at 14:03
I think I've cracked it, the product and the choice should be the other way around... I'll update the answer.
– Jon Betts
Mar 28 at 14:03
add a comment
|
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55395280%2fhow-to-generate-and-filter-efficiently-all-combinations-of-a-list-of-list-produc%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
If you are looking for the AXBXCX... And then trying to take a subset dim = n-1 , might as well start with choosing (n-1) spaces? Or am I missing something ?
– Born Tbe Wasted
Mar 28 at 10:33
Try to replace the lists by generators, replace [] by () they will save you some memory
– geckos
Mar 28 at 10:41
Also [*l] is the same as l if l is a list
– geckos
Mar 28 at 10:42
And I think numpy will help you with some performance. But I'm not the Python numbers guy
– geckos
Mar 28 at 10:43
If i replace [] by () it won't do with the combination because it will give it too much argument no ?
– Exramas
Mar 28 at 11:50