Find lowest sum value of all possible sum combinations

Jasperverdam

New Member
Joined
Jan 21, 2016
Messages
9
Hi All,

I have a list of values, both positives and negatives and I would like to find the lowest point that can be obtained by summing any of the possible sum combinations of that list. However they do have to stay in sequence. For example:

A1: -3
A2: 5
A3: -4
A4: -1
A5: 2

Adding -3, -4 and -1 is not correct as they are not in sequence (it would be +2 before it reaches cell A3 (-3+5))

In this case -5 would be the lowest point, but my lists are rather large so I am looking for a quicker way to do it rather than observing. It pretty much is a MAX function of (A1,A2,A3,A4,A5;SUM(A1:A2) up to SUM(A1:A5), but also SUM(A2:A3) up to SUM(A2:A5) all the way up to SUM(A4:A5).

Hope this makes sence!

BR,
Jasper Verdam
 

Excel Facts

Spell Check in Excel
Press F7 to start spell check in Excel. Be careful, by default, Excel does not check Capitalized Werds (whoops)
Many thanks for the quick response.

It does seem to work but not perfectly yet, as individual cells also have to be included. In the example if I change A3 to -1 now it will give me -2 as a result (-1 + -1) but actually -3 is than the lowest. How can I add this?

And going forward and using this in my own data, do I always use 15,6 in the beginning? And the array in your formula I change to, if I have 1000 cells, A1:A999+A2:A1000?
 
Upvote 0
Do you want the lowest sum of 2 cells, or the lowest 1 cell ?
Or give the lowest of both ?
=MIN(MIN(A1:A5),AGGREGATE(15,6,A1:A4+A2:A5,1))

The 15 tells aggregate to do the SMALL function (small is pretty much the same as min)
The 6 tells aggregate to ignore errors

Yes, you use 2 ranges offset by 1 row.
 
Last edited:
Upvote 0
Ah sorry, it can actually be the lowest sum of any number of cells, so it could be 1 cell, but it could also be 20. And it's not only negatives in a row. It could be -5, 2, -5 in which case the outcome should be -8.
 
Upvote 0
That's getting pretty intense with exponential possible sums to check.
Definitely outside my wheelhouse. Maybe something under the What If analysis tool on the Data Tab can help.
 
Upvote 0
It's called the maximum subarray problem, and Kadane's algorithm solves it in linear time.

https://en.wikipedia.org/wiki/Maximum_subarray_problem#Kadane's_algorithm_(Algorithm_3:_Dynamic_Programming)
 
Last edited:
Upvote 0
A​
B​
C​
D​
E​
F​
G​
1​
-1​
-10​
13​
17​
C1:E1: {=Kadane(-A1:A20, TRUE) * {-1,1,1}}
2​
2​
3​
5​
4​
3​
5​
1​
6​
5​
7​
-1​
8​
-2​
9​
2​
10​
2​
11​
0​
12​
2​
13​
-1​
14​
-3​
15​
-2​
16​
1​
17​
-5​
18​
3​
19​
1​
20​
4​

The result in C1/D1/E1 says that the max negative sum is -10, which is the sum of values from row 13 to row 17.

Code:
Function avKadane(ad() As Double, Optional bAsArray As Boolean = True) As Variant
  ' shg 2016
  ' VBA only

  ' https://en.wikipedia.org/wiki/Maximum_subarray_problem

  ' Returns the maximum (positive) sum of a subarray within 1D, 1-based array ad.
  ' If asArray is True, returns an array containing the max, and the (1-based)
  ' start and end indices that delimit it.

  Dim i             As Long
  Dim dCum          As Double
  Dim dMax          As Double
  Dim iBeg          As Long
  Dim iBegSav       As Long
  Dim iEndSav       As Long

  dCum = ad(1)
  dMax = dCum
  iBeg = 1

  For i = 2 To UBound(ad)
    If dCum <= 0 Then
      dCum = ad(i)
      iBeg = i
    Else
      dCum = dCum + ad(i)
    End If

    If dCum > dMax Then
      dMax = dCum
      iBegSav = iBeg
      iEndSav = i
    End If
  Next i

  If bAsArray Then
    avKadane = Array(dMax, iBegSav, iEndSav)
  Else
    avKadane = dMax
  End If
End Function

Function Kadane(avd As Variant, Optional bAsArray As Boolean = False) As Variant
  ' shg 2016, 2017
  ' UDF wrapper for avKadane

  ' If you want the maximum negative sum of a range, use
  ' = -Kadane(-rng)

  ' If you want the maximum negative sum of a range and extended stats, use
  ' {= Kadane(-rng, true) * {-1,1,1}}

  Kadane = avKadane(adMake1D(avd, 1), bAsArray)
End Function

Function adMake1D(V As Variant, Optional iBase As Long = 0) As Double()
  ' shg 2014-0917

  ' Returns a 1D iBase-based array of the values in v, which can be a
  ' column or row vector range, a 1D or 2D array, or a scalar

  Dim adOut()       As Double
  Dim rArea         As Range
  Dim cell          As Range
  Dim nOut          As Long
  Dim i             As Long

  If IsArray(V) Then
    If TypeOf V Is Range Then
      ReDim adOut(iBase To V.Cells.Count - 1 + iBase)

      For Each rArea In V.Areas
        For Each cell In rArea.Cells
          If VarType(cell.Value2) = vbDouble Then
            adOut(nOut + iBase) = CDbl(cell.Value2)
            nOut = nOut + 1
          Else
            Err.Raise CVErr(xlErrValue)
          End If
        Next cell
      Next rArea
      adMake1D = adOut
      Exit Function

    Else
      On Error GoTo OneD
      i = LBound(V, 2)

TwoD:        ' it's a 2D array - must have a single row or a single column
      If UBound(V, 1) - LBound(V, 1) = 0 Then       ' it's a 2D row vector
        ReDim adOut(iBase To UBound(V, 2) - LBound(V, 2) + iBase)

        For i = LBound(V, 2) To UBound(V, 2)
          Select Case VarType(V(LBound(V, 1), i))
            Case vbInteger, vbLong, vbSingle, vbDouble, vbCurrency, vbDate, vbByte
              adOut(nOut + iBase) = CDbl(V(LBound(V, 1), i))
            Case Else
              Err.Raise CVErr(xlErrValue)
          End Select
          nOut = nOut + 1
        Next i
        adMake1D = adOut
        Exit Function
        adMake1D = adOut
        Exit Function

      ElseIf UBound(V, 2) - LBound(V, 2) = 0 Then   ' it's a 2D column vector
        ReDim adOut(iBase To UBound(V, 1) - LBound(V, 1) + iBase)

        For i = LBound(V, 1) To UBound(V, 1)
          Select Case VarType(V(i, LBound(V, 2)))
            Case vbInteger, vbLong, vbSingle, vbDouble, vbCurrency, vbDate, vbByte
              adOut(nOut + iBase) = CDbl(V(i, LBound(V, 2)))
            Case Else
              Err.Raise CVErr(xlErrValue)
          End Select
          nOut = nOut + 1
        Next i
        adMake1D = adOut
        Exit Function

      Else  ' it's really 2D -- that's bad
        Err.Raise CVErr(xlErrValue)
        Exit Function
      End If

OneD:        ' it's a 1D array
      ReDim adOut(iBase To UBound(V) - LBound(V) + iBase)
      For i = LBound(V, 1) To UBound(V, 1)
        Select Case VarType(V(i))
          Case vbInteger, vbLong, vbSingle, vbDouble, vbCurrency, vbDate, vbByte
            adOut(nOut + iBase) = CDbl(V(i))
          Case Else
            Err.Raise CVErr(xlErrValue)
        End Select
        nOut = nOut + 1
      Next i
      adMake1D = adOut
      Exit Function
    End If

  Else  'it's a scalar
    ReDim adOut(iBase To iBase)
    Select Case VarType(V)
      Case vbInteger, vbLong, vbSingle, vbDouble, vbCurrency, vbDate, vbByte
        adOut(iBase) = CDbl(V)
        adMake1D = adOut
      Case Else
        Err.Raise CVErr(xlErrValue)
    End Select
  End If
End Function
 
Upvote 0

Forum statistics

Threads
1,217,383
Messages
6,136,260
Members
450,001
Latest member
KWeekley08

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top