I have four variables X1,X2,X3 and X4, which have the condition that in their sum they must always give me 1. That is, each variable represents a percentage of a total of 100%. But this percentage is based on a "step" , if I define my step as for example paso = 0.25
, I have less possible combinations (fewer rows), that if I define a smaller step like paso = 0.01
that will result in more rows.
Image to understand the idea:
In this case, the defined step is step = 0.25 , so as we can see there are 35 possible combinations, therefore 35 rows that can add 1 to me, without its value being repeated.
What I want to do is replicate this excel exercise in python, for which I started by doing the following:
def combinationSum(arr, sum):
ans = []
temp = []
# first do hashing nothing but set{}
# since set does not always sort
# removing the duplicates using Set and
# Sorting the List
arr = sorted(list(set(arr)))
findNumbers(ans, arr, temp, sum, 0)
return ans
def findNumbers(ans, arr, temp, sum, index):
if(sum == 0):
# Adding deep copy of list to ans
ans.append(list(temp))
return
# Iterate from index to len(arr) - 1
for i in range(index, len(arr)):
# checking that sum does not become negative
if(sum - arr[i]) >= 0:
# adding element which can contribute to
# sum
temp.append(arr[i])
findNumbers(ans, arr, temp, sum-arr[i], i)
# removing element from list (backtracking)
temp.remove(arr[i])
# Driver Code
arr = [2, 4, 6, 8]
sum = 8
ans = combinationSum(arr, sum)
# If result is empty, then
if len(ans) <= 0:
print("empty")
# print all combinations stored in ans
for i in range(len(ans)):
print("(", end=' ')
for j in range(len(ans[i])):
print(str(ans[i][j])+" ", end=' ')
print(")", end=' ')
In this code if as input we give:
[2, 4, 6, 8]
The output is:
( 2 2 2 2 ) ( 2 2 4 ) ( 2 6 ) ( 4 4 ) ( 8 )
This helped me to start, but I'm already stuck on how to continue, because all my output must have four values, for example, in the output (2 2 4) it must be like (2 2 4 0), also I need to implement the condition of the step with all the possible combinations based on it and all this in a Pandas dataframe.
Any idea how I could implement this?
Thanks in advance.
The way you're trying to do it seems a bit confusing to me.
This approach is similar but iterates back and forth.
Let's go by parts.
All the functionality of this logic lies in
_iterate_step
. This makes use of recursion to iterate. This function accepts 5 parameters, however 3 of them are solely and exclusively for recursion, so there is little point in leaving them open for use, which is why we have tried to leave them as private (putting the underscore). For this reason, a separate function was created callediterate_step
, which would be the public one and only accepts the parameters that can be modified, thus avoiding errors.This function accepts 3 parameters.
These parameters are passed to the private function. This function has 3 other parameters that only serve for iteration
total
at the beginning of the iteration, since during the iteration, total changes and we must save it to know if it fulfills the functionLet's start with the function
This, as explained in the description of
should_sum
only serves to save the initial total, so it is only used in the first iteration and the Carlo of the total is saved.An array of 0 is created from the amount that was passed in length, for example in 4 the following would be created
[0,0,0,0]
The index of the last element is saved and the last element becomes the total if it
total = 1
would remain[0,0,0,1]
Here it will iterate until the last element is greater than 0.
if the sum of all the elements of a temporary array of
concat
+arr
is equal tototal
then we add it. Since it is the first iteration, we see in the definition thatconcat = []
and we saw before thatarr = [0,0,0,1]
, so the sum of both arrays is[0,0,0,1]
and the sum of the elements in this case is0 + 0 + 0 + 1 = 1
.total = 1
so1 = 1
then we add[0,0,0,1]
.Once this is done, we subtract the last element from the
step
. In the first case1 - 0.75
, leaving the array asarr = [0, 0, 0, 0.75]
If the array has more than 1 element then that is when we enter recursion. To do this we must obtain the new total, that is, how much is missing from the array so that the sum of its elements is equal to the total. as our total is still
1
and our array is[0,0,0,0.75]
we can see what is missing0.25
so that will be our new total.We iterate in the step function: the same
step = 0.25
length: A new onelength
that would belength - 1
. We have that value stored aslast
total: now a new totalnew_total=0.25
, concat: at this moment we pass the array that we cut, in this case[0.75]
+ the part that we had already cut, which is theconcat
, in this case empty, since we had not cut before. should_sum: We pass the original total. prev_data: We pass the original array where we are saving the info so that it continues to save it in the same array.Now we iterate again having
step = 0.25, length = 3, total = 0.25, concat = [0.75], should_sum = 1, prev_data = [[0,0,0,1]]
It no longer applies because it does exist
should sum
Now just create an array of 3 elements
[0,0,0.25]
It iterates again but this time
arr = [0,0,0.25]
andconcat = [0.75]
, so the new array is[0,0,0.25,0.75]
Since the sum of this is equal to 1. So it is added to the array.If you follow that sequence you can understand the recursion it uses.
As for pandas you can simply transform it to a dataframe as follows.
df = pd.DataFrame(combinations)