A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
1
Task/Greatest-subsequential-sum/0DESCRIPTION
Normal file
1
Task/Greatest-subsequential-sum/0DESCRIPTION
Normal file
|
|
@ -0,0 +1 @@
|
|||
Given a sequence of integers, find a continuous subsequence which maximizes the sum of its elements, that is, the elements of no other single subsequence add up to a value larger than this one. An empty subsequence is considered to have the sum 0; thus if all elements are negative, the result must be the empty sequence.
|
||||
3
Task/Greatest-subsequential-sum/1META.yaml
Normal file
3
Task/Greatest-subsequential-sum/1META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
category:
|
||||
- Arithmetic operations
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
main:
|
||||
(
|
||||
[]INT a = (-1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1);
|
||||
|
||||
INT begin max, end max, max sum, sum;
|
||||
|
||||
sum := 0;
|
||||
begin max := 0;
|
||||
end max := -1;
|
||||
max sum := 0;
|
||||
|
||||
|
||||
FOR begin FROM LWB a TO UPB a DO
|
||||
sum := 0;
|
||||
FOR end FROM begin TO UPB a DO
|
||||
sum +:= a[end];
|
||||
IF sum > max sum THEN
|
||||
max sum := sum;
|
||||
begin max := begin;
|
||||
end max := end
|
||||
FI
|
||||
OD
|
||||
OD;
|
||||
|
||||
FOR i FROM begin max TO end max DO
|
||||
print(a[i])
|
||||
OD
|
||||
|
||||
)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Finds the subsequence of ary[1] to ary[len] with the greatest sum.
|
||||
# Sets subseq[1] to subseq[n] and returns n. Also sets subseq["sum"].
|
||||
# An empty subsequence has sum 0.
|
||||
function maxsubseq(subseq, ary, len, b, bp, bs, c, cp, i) {
|
||||
b = 0 # best sum
|
||||
c = 0 # current sum
|
||||
bp = 0 # position of best subsequence
|
||||
bn = 0 # length of best subsequence
|
||||
cp = 1 # position of current subsequence
|
||||
|
||||
for (i = 1; i <= len; i++) {
|
||||
c += ary[i]
|
||||
if (c < 0) {
|
||||
c = 0
|
||||
cp = i + 1
|
||||
}
|
||||
if (c > b) {
|
||||
b = c
|
||||
bp = cp
|
||||
bn = i + 1 - cp
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i <= bn; i++)
|
||||
subseq[i] = ary[bp + i - 1]
|
||||
subseq["sum"] = b
|
||||
return bn
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# Joins the elements ary[1] to ary[len] in a string.
|
||||
function join(ary, len, i, s) {
|
||||
s = "["
|
||||
for (i = 1; i <= len; i++) {
|
||||
s = s ary[i]
|
||||
if (i < len)
|
||||
s = s ", "
|
||||
}
|
||||
s = s "]"
|
||||
return s
|
||||
}
|
||||
|
||||
# Demonstrates maxsubseq().
|
||||
function try(str, ary, len, max, maxlen) {
|
||||
len = split(str, ary)
|
||||
print "Array: " join(ary, len)
|
||||
maxlen = maxsubseq(max, ary, len)
|
||||
print " Maximal subsequence: " \
|
||||
join(max, maxlen) ", sum " max["sum"]
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
try("-1 -2 -3 -4 -5")
|
||||
try("0 1 2 -3 3 -1 0 -4 0 -1 -4 2")
|
||||
try("-1 -2 3 5 6 -2 -1 4 -4 2 -1")
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
with Ada.Text_Io; use Ada.Text_Io;
|
||||
|
||||
procedure Max_Subarray is
|
||||
type Int_Array is array (Positive range <>) of Integer;
|
||||
Empty_Error : Exception;
|
||||
function Max(Item : Int_Array) return Int_Array is
|
||||
Start : Positive;
|
||||
Finis : Positive;
|
||||
Max_Sum : Integer := Integer'First;
|
||||
Sum : Integer;
|
||||
begin
|
||||
if Item'Length = 0 then
|
||||
raise Empty_Error;
|
||||
end if;
|
||||
|
||||
for I in Item'range loop
|
||||
Sum := 0;
|
||||
for J in I..Item'Last loop
|
||||
Sum := Sum + Item(J);
|
||||
if Sum > Max_Sum then
|
||||
Max_Sum := Sum;
|
||||
Start := I;
|
||||
Finis := J;
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
return Item(Start..Finis);
|
||||
end Max;
|
||||
A : Int_Array := (-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1);
|
||||
B : Int_Array := Max(A);
|
||||
begin
|
||||
for I in B'range loop
|
||||
Put_Line(Integer'Image(B(I)));
|
||||
end loop;
|
||||
exception
|
||||
when Empty_Error =>
|
||||
Put_Line("Array being analyzed has no elements.");
|
||||
end Max_Subarray;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
seq = -1,-2,3,5,6,-2,-1,4,-4,2,-1
|
||||
max := sum := start := 0
|
||||
Loop Parse, seq, `,
|
||||
If (max < sum+=A_LoopField)
|
||||
max := sum, a := start, b := A_Index
|
||||
Else If sum <= 0
|
||||
sum := 0, start := A_Index
|
||||
; read out the best subsequence
|
||||
Loop Parse, seq, `,
|
||||
s .= A_Index > a && A_Index <= b ? A_LoopField "," : ""
|
||||
MsgBox % "Max = " max "`n[" SubStr(s,1,-1) "]"
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
Local $iArray[11] = [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]
|
||||
GREAT_SUB($iArray)
|
||||
Local $iArray[5] = [-1, -2, -3, -4, -5]
|
||||
GREAT_SUB($iArray)
|
||||
Local $iArray[15] = [7, -6, -8, 5, -2, -6, 7, 4, 8, -9, -3, 2, 6, -4, -6]
|
||||
GREAT_SUB($iArray)
|
||||
|
||||
Func GREAT_SUB($iArray)
|
||||
Local $iSUM = 0, $iBEGIN_MAX = 0, $iEND_MAX = -1, $iMAX_SUM = 0
|
||||
For $i = 0 To UBound($iArray) - 1
|
||||
$iSUM = 0
|
||||
For $k = $i To UBound($iArray) - 1
|
||||
$iSUM += $iArray[$k]
|
||||
If $iSUM > $iMAX_SUM Then
|
||||
$iMAX_SUM = $iSUM
|
||||
$iEND_MAX = $k
|
||||
$iBEGIN_MAX = $i
|
||||
EndIf
|
||||
Next
|
||||
Next
|
||||
ConsoleWrite("> Array: [")
|
||||
For $i = 0 To UBound($iArray) - 1
|
||||
If $iArray[$i] > 0 Then ConsoleWrite("+")
|
||||
ConsoleWrite($iArray[$i])
|
||||
If $i <> UBound($iArray) - 1 Then ConsoleWrite(",")
|
||||
Next
|
||||
ConsoleWrite("]" & @CRLF & "+>Maximal subsequence: [")
|
||||
$iSUM = 0
|
||||
For $i = $iBEGIN_MAX To $iEND_MAX
|
||||
$iSUM += $iArray[$i]
|
||||
If $iArray[$i] > 0 Then ConsoleWrite("+")
|
||||
ConsoleWrite($iArray[$i])
|
||||
If $i <> $iEND_MAX Then ConsoleWrite(",")
|
||||
Next
|
||||
ConsoleWrite("]" & @CRLF & "!>SUM of subsequence: " & $iSUM & @CRLF)
|
||||
EndFunc ;==>GREAT_SUB
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
DIM A%(11) : A%() = 0, 1, 2, -3, 3, -1, 0, -4, 0, -1, -4, 2
|
||||
PRINT FNshowarray(A%()) " -> " FNmaxsubsequence(A%())
|
||||
DIM B%(10) : B%() = -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1
|
||||
PRINT FNshowarray(B%()) " -> " FNmaxsubsequence(B%())
|
||||
DIM C%(4) : C%() = -1, -2, -3, -4, -5
|
||||
PRINT FNshowarray(C%()) " -> " FNmaxsubsequence(C%())
|
||||
END
|
||||
|
||||
DEF FNmaxsubsequence(a%())
|
||||
LOCAL a%, b%, i%, j%, m%, s%, a$
|
||||
a% = 1
|
||||
FOR i% = 0 TO DIM(a%(),1)
|
||||
s% = 0
|
||||
FOR j% = i% TO DIM(a%(),1)
|
||||
s% += a%(j%)
|
||||
IF s% > m% THEN
|
||||
m% = s%
|
||||
a% = i%
|
||||
b% = j%
|
||||
ENDIF
|
||||
NEXT
|
||||
NEXT i%
|
||||
IF a% > b% THEN = "[]"
|
||||
a$ = "["
|
||||
FOR i% = a% TO b%
|
||||
a$ += STR$(a%(i%)) + ", "
|
||||
NEXT
|
||||
= LEFT$(LEFT$(a$)) + "]"
|
||||
|
||||
DEF FNshowarray(a%())
|
||||
LOCAL i%, a$
|
||||
a$ = "["
|
||||
FOR i% = 0 TO DIM(a%(),1)
|
||||
a$ += STR$(a%(i%)) + ", "
|
||||
NEXT
|
||||
= LEFT$(LEFT$(a$)) + "]"
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
( 0:?max
|
||||
& :?seq
|
||||
& -1 -2 3 5 6 -2 -1 4 -4 2 -1
|
||||
: ?
|
||||
[%( (
|
||||
= s sum
|
||||
. ( sum
|
||||
= A
|
||||
. !arg:%?A ?arg&!A+sum$!arg
|
||||
| 0
|
||||
)
|
||||
& ( sum$!sjt:>!max:?max
|
||||
& !sjt:?seq
|
||||
|
|
||||
)
|
||||
)
|
||||
$
|
||||
& ~
|
||||
)
|
||||
?
|
||||
| !seq
|
||||
)
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
#include <utility> // for std::pair
|
||||
#include <iterator> // for std::iterator_traits
|
||||
#include <iostream> // for std::cout
|
||||
#include <ostream> // for output operator and std::endl
|
||||
#include <algorithm> // for std::copy
|
||||
#include <iterator> // for std::output_iterator
|
||||
|
||||
// Function template max_subseq
|
||||
//
|
||||
// Given a sequence of integers, find a subsequence which maximizes
|
||||
// the sum of its elements, that is, the elements of no other single
|
||||
// subsequence add up to a value larger than this one.
|
||||
//
|
||||
// Requirements:
|
||||
// * ForwardIterator is a forward iterator
|
||||
// * ForwardIterator's value_type is less-than comparable and addable
|
||||
// * default-construction of value_type gives the neutral element
|
||||
// (zero)
|
||||
// * operator+ and operator< are compatible (i.e. if a>zero and
|
||||
// b>zero, then a+b>zero, and if a<zero and b<zero, then a+b<zero)
|
||||
// * [begin,end) is a valid range
|
||||
//
|
||||
// Returns:
|
||||
// a pair of iterators describing the begin and end of the
|
||||
// subsequence
|
||||
template<typename ForwardIterator>
|
||||
std::pair<ForwardIterator, ForwardIterator>
|
||||
max_subseq(ForwardIterator begin, ForwardIterator end)
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type
|
||||
value_type;
|
||||
|
||||
ForwardIterator seq_begin = begin, seq_end = seq_begin;
|
||||
value_type seq_sum = value_type();
|
||||
ForwardIterator current_begin = begin;
|
||||
value_type current_sum = value_type();
|
||||
|
||||
value_type zero = value_type();
|
||||
|
||||
for (ForwardIterator iter = begin; iter != end; ++iter)
|
||||
{
|
||||
value_type value = *iter;
|
||||
if (zero < value)
|
||||
{
|
||||
if (current_sum < zero)
|
||||
{
|
||||
current_sum = zero;
|
||||
current_begin = iter;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (seq_sum < current_sum)
|
||||
{
|
||||
seq_begin = current_begin;
|
||||
seq_end = iter;
|
||||
seq_sum = current_sum;
|
||||
}
|
||||
}
|
||||
current_sum += value;
|
||||
}
|
||||
|
||||
if (seq_sum < current_sum)
|
||||
{
|
||||
seq_begin = current_begin;
|
||||
seq_end = end;
|
||||
seq_sum = current_sum;
|
||||
}
|
||||
|
||||
return std::make_pair(seq_begin, seq_end);
|
||||
}
|
||||
|
||||
// the test array
|
||||
int array[] = { -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1 };
|
||||
|
||||
// function template to find the one-past-end pointer to the array
|
||||
template<typename T, int N> int* end(T (&arr)[N]) { return arr+N; }
|
||||
|
||||
int main()
|
||||
{
|
||||
// find the subsequence
|
||||
std::pair<int*, int*> seq = max_subseq(array, end(array));
|
||||
|
||||
// output it
|
||||
std::copy(seq.first, seq.second, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#include "stdio.h"
|
||||
|
||||
typedef struct Range {
|
||||
int start, end, sum;
|
||||
} Range;
|
||||
|
||||
Range maxSubseq(const int sequence[], const int len) {
|
||||
int maxSum = 0, thisSum = 0, i = 0;
|
||||
int start = 0, end = -1, j;
|
||||
|
||||
for (j = 0; j < len; j++) {
|
||||
thisSum += sequence[j];
|
||||
if (thisSum < 0) {
|
||||
i = j + 1;
|
||||
thisSum = 0;
|
||||
} else if (thisSum > maxSum) {
|
||||
maxSum = thisSum;
|
||||
start = i;
|
||||
end = j;
|
||||
}
|
||||
}
|
||||
|
||||
Range r;
|
||||
if (start <= end && start >= 0 && end >= 0) {
|
||||
r.start = start;
|
||||
r.end = end + 1;
|
||||
r.sum = maxSum;
|
||||
} else {
|
||||
r.start = 0;
|
||||
r.end = 0;
|
||||
r.sum = 0;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int a[] = {-1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1};
|
||||
int alength = sizeof(a)/sizeof(a[0]);
|
||||
|
||||
Range r = maxSubseq(a, alength);
|
||||
printf("Max sum = %d\n", r.sum);
|
||||
int i;
|
||||
for (i = r.start; i < r.end; i++)
|
||||
printf("%d ", a[i]);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(defn max-subseq-sum [coll]
|
||||
(->> (take-while seq (iterate rest coll)) ; tails
|
||||
(mapcat #(reductions conj [] %)) ; inits
|
||||
(apply max-key #(reduce + %)))) ; max sum
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
user> (max-subseq-sum [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1])
|
||||
[3 5 6 -2 -1 4]
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
max_sum_seq = (sequence) ->
|
||||
# This runs in linear time.
|
||||
[sum_start, sum, max_sum, max_start, max_end] = [0, 0, 0, 0, 0]
|
||||
for n, i in sequence
|
||||
sum += n
|
||||
if sum > max_sum
|
||||
max_sum = sum
|
||||
max_start = sum_start
|
||||
max_end = i + 1
|
||||
if sum < 0 # start new sequence
|
||||
sum = 0
|
||||
sum_start = i + 1
|
||||
sequence[max_start...max_end]
|
||||
|
||||
# tests
|
||||
console.log max_sum_seq [-1, 0, 15, 3, -9, 12, -4]
|
||||
console.log max_sum_seq [-1]
|
||||
console.log max_sum_seq [4, -10, 3]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
(defun max-subseq (list)
|
||||
(let ((best-sum 0) (current-sum 0) (end 0))
|
||||
;; determine the best sum, and the end of the max subsequence
|
||||
(do ((list list (rest list))
|
||||
(i 0 (1+ i)))
|
||||
((endp list))
|
||||
(setf current-sum (max 0 (+ current-sum (first list))))
|
||||
(when (> current-sum best-sum)
|
||||
(setf end i
|
||||
best-sum current-sum)))
|
||||
;; take the subsequence of list ending at end, and remove elements
|
||||
;; from the beginning until the subsequence sums to best-sum.
|
||||
(let* ((sublist (subseq list 0 (1+ end)))
|
||||
(sum (reduce #'+ sublist)))
|
||||
(do ((start 0 (1+ start))
|
||||
(sublist sublist (rest sublist))
|
||||
(sum sum (- sum (first sublist))))
|
||||
((or (endp sublist) (eql sum best-sum))
|
||||
(values best-sum sublist start (1+ end)))))))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(defun max-subseq (seq)
|
||||
(loop for subsequence in (mapcon (lambda (x) (maplist #'reverse (reverse x))) seq)
|
||||
for sum = (reduce #'+ subsequence :initial-value 0)
|
||||
with max-subsequence
|
||||
maximizing sum into max
|
||||
if (= sum max) do (setf max-subsequence subsequence)
|
||||
finally (return max-subsequence))))
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import std.stdio;
|
||||
|
||||
inout(T[]) maxSubseq(T)(inout T[] sequence) pure nothrow {
|
||||
int maxSum, thisSum, i, start, end = -1;
|
||||
|
||||
foreach (j, x; sequence) {
|
||||
thisSum += x;
|
||||
if (thisSum < 0) {
|
||||
i = j + 1;
|
||||
thisSum = 0;
|
||||
} else if (thisSum > maxSum) {
|
||||
maxSum = thisSum;
|
||||
start = i;
|
||||
end = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (start <= end && start >= 0 && end >= 0)
|
||||
return sequence[start .. end + 1];
|
||||
else
|
||||
return [];
|
||||
}
|
||||
|
||||
void main() {
|
||||
const a1 = [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1];
|
||||
writeln("Maximal subsequence: ", maxSubseq(a1));
|
||||
|
||||
const a2 = [-1, -2, -3, -5, -6, -2, -1, -4, -4, -2, -1];
|
||||
writeln("Maximal subsequence: ", maxSubseq(a2));
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
pragma.enable("accumulator")
|
||||
|
||||
def maxSubseq(seq) {
|
||||
def size := seq.size()
|
||||
|
||||
# Collect all intervals of indexes whose values are positive
|
||||
def intervals := {
|
||||
var intervals := []
|
||||
var first := 0
|
||||
while (first < size) {
|
||||
var next := first
|
||||
def seeing := seq[first] > 0
|
||||
while (next < size && (seq[next] > 0) == seeing) {
|
||||
next += 1
|
||||
}
|
||||
if (seeing) { # record every positive interval
|
||||
intervals with= first..!next
|
||||
}
|
||||
first := next
|
||||
}
|
||||
intervals
|
||||
}
|
||||
|
||||
# For recording the best result found
|
||||
var maxValue := 0
|
||||
var maxInterval := 0..!0
|
||||
|
||||
# Try all subsequences beginning and ending with such intervals.
|
||||
for firstIntervalIx => firstInterval in intervals {
|
||||
for lastInterval in intervals(firstIntervalIx) {
|
||||
def interval :=
|
||||
(firstInterval.getOptStart())..!(lastInterval.getOptBound())
|
||||
def value :=
|
||||
accum 0 for i in interval { _ + seq[i] }
|
||||
if (value > maxValue) {
|
||||
maxValue := value
|
||||
maxInterval := interval
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ["value" => maxValue,
|
||||
"indexes" => maxInterval]
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
def seq := [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]
|
||||
def [=> value, => indexes] := maxSubseq(seq)
|
||||
println(`$\
|
||||
Sequence: $seq
|
||||
Maximum subsequence sum: $value
|
||||
Indexes: ${indexes.getOptStart()}..${indexes.getOptBound().previous()}
|
||||
Subsequence: ${seq(indexes.getOptStart(), indexes.getOptBound())}
|
||||
`)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
>function %maxsubs (v,n) ...
|
||||
$if n==1 then
|
||||
$ if (v[1]<0) then return {zeros(1,0),zeros(1,0)}
|
||||
$ else return {v,v};
|
||||
$ endif;
|
||||
$endif;
|
||||
${v1,v2}=%maxsubs(v[1:n-1],n-1);
|
||||
$m1=sum(v1); m2=sum(v2); m3=m2+v[n];
|
||||
$if m3>0 then v3=v2|v[n]; else v3=zeros(1,0); endif;
|
||||
$if m3>m1 then return {v2|v[n],v3};
|
||||
$else return {v1,v3};
|
||||
$endif;
|
||||
$endfunction
|
||||
>function maxsubs (v) ...
|
||||
${v1,v2}=%maxsubs(v,cols(v));
|
||||
$return v1
|
||||
$endfunction
|
||||
>maxsubs([0, 1, 2, -3, 3, -1, 0, -4, 0, -1, -4])
|
||||
[ 0 1 2 ]
|
||||
>maxsubs([-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1])
|
||||
[ 3 5 6 -2 -1 4 ]
|
||||
>maxsubs([-1, -2, -3, -4, -5])
|
||||
Empty matrix of size 1x0
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
>function maxsubsbrute (v) ...
|
||||
$ n=cols(v);
|
||||
$ A=zeros(n*(n-1),n);
|
||||
$ k=1;
|
||||
$ for i=1 to n-1;
|
||||
$ for j=i to n;
|
||||
$ A[k,i:j]=1;
|
||||
$ k=k+1;
|
||||
$ end;
|
||||
$ end;
|
||||
$ k1=extrema((A.v')')[4];
|
||||
$ return v[nonzeros(A[k1])];
|
||||
$ endfunction
|
||||
>maxsubsbrute([0, 1, 2, -3, 3, -1, 0, -4, 0, -1, -4])
|
||||
[ 0 1 2 ]
|
||||
>maxsubsbrute([-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1])
|
||||
[ 3 5 6 -2 -1 4 ]
|
||||
>maxsubsbrute([-1, -2, -3, -4, -5])
|
||||
Empty matrix of size 1x0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
>function test ...
|
||||
$ loop 1 to 10000000
|
||||
$ v=intrandom(1,intrandom(6)+6,20)-10;
|
||||
$ if sum(maxsubs(v))!=sum(maxsubsbrute(v)) then
|
||||
$ v, error("Found a wrong test example");
|
||||
$ endif;
|
||||
$ endfunction
|
||||
>test
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
function maxSubseq(sequence s)
|
||||
integer sum, maxsum, first, last
|
||||
maxsum = 0
|
||||
first = 1
|
||||
last = 0
|
||||
for i = 1 to length(s) do
|
||||
sum = 0
|
||||
for j = i to length(s) do
|
||||
sum += s[j]
|
||||
if sum > maxsum then
|
||||
maxsum = sum
|
||||
first = i
|
||||
last = j
|
||||
end if
|
||||
end for
|
||||
end for
|
||||
return s[first..last]
|
||||
end function
|
||||
|
||||
? maxSubseq({-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1})
|
||||
? maxSubseq({})
|
||||
? maxSubseq({-1, -5, -3})
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
USING: kernel locals math math.order sequences ;
|
||||
|
||||
:: max-with-index ( elt0 ind0 elt1 ind1 -- elt ind )
|
||||
elt0 elt1 < [ elt1 ind1 ] [ elt0 ind0 ] if ;
|
||||
: last-of-max ( accseq -- ind ) -1 swap -1 [ max-with-index ] reduce-index nip ;
|
||||
|
||||
: max-subseq ( seq -- subseq )
|
||||
dup 0 [ + 0 max ] accumulate swap suffix last-of-max head
|
||||
dup 0 [ + ] accumulate swap suffix [ neg ] map last-of-max tail ;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
( scratchpad ) { -1 -2 3 5 6 -2 -1 4 -4 2 -1 } max-subseq dup sum swap . .
|
||||
{ 3 5 6 -2 -1 4 }
|
||||
15
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
2variable best
|
||||
variable best-sum
|
||||
|
||||
: sum ( array len -- sum )
|
||||
0 -rot cells over + swap do i @ + cell +loop ;
|
||||
|
||||
: max-sub ( array len -- sub len )
|
||||
over 0 best 2! 0 best-sum !
|
||||
dup 1 do \ foreach length
|
||||
2dup i - cells over + swap do \ foreach start
|
||||
i j sum
|
||||
dup best-sum @ > if
|
||||
best-sum !
|
||||
i j best 2!
|
||||
else drop then
|
||||
cell +loop
|
||||
loop
|
||||
2drop best 2@ ;
|
||||
|
||||
: .array ." [" dup 0 ?do over i cells + @ . loop ." ] = " sum . ;
|
||||
|
||||
create test -1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1 ,
|
||||
|
||||
test 11 max-sub .array \ [3 5 6 -2 -1 4 ] = 15
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
program MaxSubSeq
|
||||
implicit none
|
||||
|
||||
integer, parameter :: an = 11
|
||||
integer, dimension(an) :: a = (/ -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1 /)
|
||||
|
||||
integer, dimension(an,an) :: mix
|
||||
integer :: i, j
|
||||
integer, dimension(2) :: m
|
||||
|
||||
forall(i=1:an,j=1:an) mix(i,j) = sum(a(i:j))
|
||||
m = maxloc(mix)
|
||||
! a(m(1):m(2)) is the wanted subsequence
|
||||
print *, a(m(1):m(2))
|
||||
|
||||
end program MaxSubSeq
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func gss(s []int) ([]int, int) {
|
||||
var best, start, end, sum, sumStart int
|
||||
for i, x := range s {
|
||||
sum += x
|
||||
switch {
|
||||
case sum > best:
|
||||
best = sum
|
||||
start = sumStart
|
||||
end = i + 1
|
||||
case sum < 0:
|
||||
sum = 0
|
||||
sumStart = i + 1
|
||||
}
|
||||
}
|
||||
return s[start:end], best
|
||||
}
|
||||
|
||||
var testCases = [][]int{
|
||||
{-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1},
|
||||
{-1, 1, 2, -5, -6},
|
||||
{},
|
||||
{-1, -2, -1},
|
||||
}
|
||||
|
||||
func main() {
|
||||
for _, c := range testCases {
|
||||
fmt.Println("Input: ", c)
|
||||
subSeq, sum := gss(c)
|
||||
fmt.Println("Sub seq:", subSeq)
|
||||
fmt.Println("Sum: ", sum, "\n")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import Data.List (inits, tails, maximumBy)
|
||||
import Data.Ord (comparing)
|
||||
|
||||
subseqs :: [a] -> [[a]]
|
||||
subseqs = concatMap inits . tails
|
||||
|
||||
maxsubseq :: (Ord a, Num a) => [a] -> [a]
|
||||
maxsubseq = maximumBy (comparing sum) . subseqs
|
||||
|
||||
main = print $ maxsubseq [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
maxsubseq = mss_ (0,[]) (0,[]) where
|
||||
mss_ _ x [] = x
|
||||
mss_ here sofar (x:xs) = mss a b xs where
|
||||
a = max (0,[]) (fst here + x, snd here ++ [x])
|
||||
b = max sofar a
|
||||
|
||||
main = print $ maxsubseq [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
procedure main()
|
||||
L1 := [-1,-2,3,5,6,-2,-1,4,-4,2,-1] # sample list
|
||||
L := [-1,1,2,3,4,-11]|||L1 # prepend a local maximum into the mix
|
||||
write(ximage(maxsubseq(L)))
|
||||
end
|
||||
|
||||
link ximage # to show lists
|
||||
|
||||
procedure maxsubseq(L) #: return the subsequence of L with maximum positive sum
|
||||
local i,maxglobal,maxglobalI,maxlocal,maxlocalI
|
||||
|
||||
maxglobal := maxlocal := 0 # global and local maxima
|
||||
|
||||
every i := 1 to *L do {
|
||||
if (maxlocal := max(maxlocal +L[i],0)) > 0 then
|
||||
if /maxlocalI then maxlocalI := [i,i] else maxlocalI[2] := i # local maxima subscripts
|
||||
else maxlocalI := &null # reset subsequence
|
||||
if maxglobal <:= maxlocal then # global maxima
|
||||
maxglobalI := copy(maxlocalI)
|
||||
}
|
||||
return L[(\maxglobalI)[1]:maxglobalI[2]] | [] # return sub-sequence or empty list
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
maxss=: monad define
|
||||
AS =. 0,; <:/~@i.&.> #\y
|
||||
MX =. (= >./) AS +/ . * y
|
||||
y #~ {. MX#AS
|
||||
)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
maxss _1 _2 3 5 6 _2 _1 4 _4 2 _1
|
||||
3 5 6 _2 _1 4
|
||||
|
|
@ -0,0 +1 @@
|
|||
maxs=: [:>./(0>.+)/\.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
maxs _1 _2 3 5 6 _2 _1 4 _4 2 _1
|
||||
15
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
maxSS=:monad define
|
||||
sums=: (0>.+)/\. y
|
||||
start=: sums i. max=: >./ sums
|
||||
max (] {.~ #@] |&>: (= +/\) i. 1:) y}.~start
|
||||
)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
maxSS2=:monad define
|
||||
start=. (i. >./) (0>.+)/\. y
|
||||
({.~ # |&>: [: (i.>./@,&0) +/\) y}.~start
|
||||
)
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import java.util.Scanner;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Sub{
|
||||
private static int[] indices;
|
||||
|
||||
public static void main(String[] args){
|
||||
ArrayList<Long> array= new ArrayList<Long>(); //the main set
|
||||
Scanner in = new Scanner(System.in);
|
||||
while(in.hasNextLong()) array.add(in.nextLong());
|
||||
long highSum= Long.MIN_VALUE;//start the sum at the lowest possible value
|
||||
ArrayList<Long> highSet= new ArrayList<Long>();
|
||||
//loop through all possible subarray sizes including 0
|
||||
for(int subSize= 0;subSize<= array.size();subSize++){
|
||||
indices= new int[subSize];
|
||||
for(int i= 0;i< subSize;i++) indices[i]= i;
|
||||
do{
|
||||
long sum= 0;//this subarray sum variable
|
||||
ArrayList<Long> temp= new ArrayList<Long>();//this subarray
|
||||
//sum it and save it
|
||||
for(long index:indices) {sum+= array.get(index); temp.add(array.get(index));}
|
||||
if(sum > highSum){//if we found a higher sum
|
||||
highSet= temp; //keep track of it
|
||||
highSum= sum;
|
||||
}
|
||||
}while(nextIndices(array));//while we haven't tested all subarrays
|
||||
}
|
||||
System.out.println("Sum: " + highSum + "\nSet: " +
|
||||
highSet);
|
||||
}
|
||||
/**
|
||||
* Computes the next set of choices from the previous. The
|
||||
* algorithm tries to increment the index of the final choice
|
||||
* first. Should that fail (index goes out of bounds), it
|
||||
* tries to increment the next-to-the-last index, and resets
|
||||
* the last index to one more than the next-to-the-last.
|
||||
* Should this fail the algorithm keeps starting at an earlier
|
||||
* choice until it runs off the start of the choice list without
|
||||
* Finding a legal set of indices for all the choices.
|
||||
*
|
||||
* @return true unless all choice sets have been exhausted.
|
||||
* @author James Heliotis
|
||||
*/
|
||||
|
||||
private static boolean nextIndices(ArrayList<Long> a) {
|
||||
for(int i= indices.length-1;i >= 0;--i){
|
||||
indices[i]++;
|
||||
for(int j=i+1;j < indices.length;++j){
|
||||
indices[j]= indices[j - 1] + 1;//reset the last failed try
|
||||
}
|
||||
if(indices[indices.length - 1] < a.size()){//if this try went out of bounds
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
private static int BiggestSubsum(int[] t) {
|
||||
int sum = 0;
|
||||
int maxsum = 0;
|
||||
|
||||
for (int i : t) {
|
||||
sum += i;
|
||||
if (sum < 0)
|
||||
sum = 0;
|
||||
maxsum = sum > maxsum ? sum : maxsum;
|
||||
}
|
||||
return maxsum;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
function MaximumSubsequence( population ) {
|
||||
var maxValue = 0;
|
||||
var subsequence = [];
|
||||
|
||||
for( var i=0, len=population.length; i < len; i++ ) {
|
||||
for( var j=i; j <= len; j++ ) {
|
||||
var subsequence = population.slice(i,j);
|
||||
var value = sumValues(subsequence);
|
||||
if( value > maxValue ) {
|
||||
maxValue = value;
|
||||
greatest = subsequence;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return greatest;
|
||||
}
|
||||
|
||||
function sumValues(arr) {
|
||||
var result = 0;
|
||||
for( var i=0, len=arr.length; i < len; i++) {
|
||||
result += arr[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
'Greatest_subsequential_sum
|
||||
|
||||
N= 20 'number of elements
|
||||
|
||||
randomize 0.52
|
||||
for K = 1 to 5
|
||||
a$ = using("##",int(rnd(1)*12)-5)
|
||||
for i=2 to N
|
||||
a$ = a$ +","+using("##",int(rnd(1)*12)-5)
|
||||
next
|
||||
call maxsumseq a$
|
||||
next K
|
||||
|
||||
sub maxsumseq a$
|
||||
sum=0
|
||||
maxsum=0
|
||||
sumStart=1
|
||||
end1 =0
|
||||
start1 =1
|
||||
|
||||
token$="*"
|
||||
i=0
|
||||
while 1
|
||||
i=i+1
|
||||
token$=word$(a$, i, ",")
|
||||
if token$ ="" then exit while 'end of stream
|
||||
x=val(token$)
|
||||
sum=sum+x
|
||||
if maxsum<sum then
|
||||
maxsum = sum
|
||||
start1 = sumStart
|
||||
end1 = i
|
||||
else
|
||||
if sum <0 then
|
||||
sum=0
|
||||
sumStart = i+1
|
||||
end if
|
||||
end if
|
||||
wend
|
||||
print "sequence: ";a$
|
||||
print " ";
|
||||
for i=1 to start1-1: print " "; :next
|
||||
for i= start1 to end1: print "---"; :next
|
||||
print
|
||||
if end1 >0 then
|
||||
print "Maximum sum subsequense: ";start1 ;" to "; end1
|
||||
else
|
||||
print "Maximum sum subsequense: is empty"
|
||||
end if
|
||||
print "Maximum sum ";maxsum
|
||||
print
|
||||
end sub
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
function sumt(t, start, last) return start <= last and t[start] + sumt(t, start+1, last) or 0 end
|
||||
function maxsub(ary, idx)
|
||||
local idx = idx or 1
|
||||
if not ary[idx] then return {} end
|
||||
local maxsum, last = 0, idx
|
||||
for i = idx, #ary do
|
||||
if sumt(ary, idx, i) > maxsum then maxsum, last = sumt(ary, idx, i), i end
|
||||
end
|
||||
local v = maxsub(ary, idx + 1)
|
||||
if maxsum < sumt(v, 1, #v) then return v end
|
||||
local ret = {}
|
||||
for i = idx, last do ret[#ret+1] = ary[i] end
|
||||
return ret
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
divert(-1)
|
||||
define(`setrange',`ifelse(`$3',`',$2,`define($1[$2],$3)`'setrange($1,
|
||||
incr($2),shift(shift(shift($@))))')')
|
||||
define(`asize',decr(setrange(`a',1,-1,-2,3,5,6,-2,-1,4,-4,2,-1)))
|
||||
define(`get',`defn(`$1[$2]')')
|
||||
define(`for',
|
||||
`ifelse($#,0,``$0'',
|
||||
`ifelse(eval($2<=$3),1,
|
||||
`pushdef(`$1',$2)$4`'popdef(`$1')$0(`$1',incr($2),$3,`$4')')')')
|
||||
define(`maxsum',0)
|
||||
for(`x',1,asize,
|
||||
`define(`sum',0)`'for(`y',x,asize,
|
||||
`define(`sum',eval(sum+get(`a',y)))`'ifelse(eval(sum>maxsum),1,
|
||||
`define(`maxsum',sum)`'define(`xmax',x)`'define(`ymax',y)')')')
|
||||
divert
|
||||
for(`x',xmax,ymax,`get(`a',x) ')
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
Sequences[m_]:=Prepend[Flatten[Table[Partition[Range[m],n,1],{n,m}],1],{}]
|
||||
MaximumSubsequence[x_List]:=Module[{sums},
|
||||
sums={x[[#]],Total[x[[#]]]}&/@Sequences[Length[x]];
|
||||
First[First[sums[[Ordering[sums,-1,#1[[2]]<#2[[2]]&]]]]]
|
||||
]
|
||||
|
|
@ -0,0 +1 @@
|
|||
MaximumSubsequence[x_List]:=Last@SortBy[Flatten[Table[x[[a;;b]], {b,Length[x]}, {a,b}],1],Total]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
MaximumSubsequence[{-1,-2,3,5,6,-2,-1,4,-4,2,-1}]
|
||||
MaximumSubsequence[{2,4,5}]
|
||||
MaximumSubsequence[{2,-4,3}]
|
||||
MaximumSubsequence[{4}]
|
||||
MaximumSubsequence[{}]
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*Special ordered set of type N
|
||||
|
||||
Nigel_Galloway
|
||||
January 26th, 2012
|
||||
*/
|
||||
|
||||
param Lmax;
|
||||
param Lmin;
|
||||
set SOS;
|
||||
param Sx{SOS};
|
||||
var db{Lmin..Lmax,SOS}, binary;
|
||||
|
||||
maximize s : sum{q in (Lmin..Lmax),t in (0..q-1), z in SOS: z > (q-1)} Sx[z-t]*db[q,z];
|
||||
sos1 : sum{t in (Lmin..Lmax),z in SOS: z > (t-1)} db[t,z] = 1;
|
||||
solve;
|
||||
|
||||
for{t in (Lmin..Lmax),z in SOS: db[t,z] == 1} {
|
||||
printf "\nA sub-sequence of length %d sums to %f:\n", t,s;
|
||||
printf{q in (z-t+1)..z} " %f", Sx[q];
|
||||
}
|
||||
printf "\n\n";
|
||||
|
||||
data;
|
||||
param Lmin := 1;
|
||||
param Lmax := 6;
|
||||
param:
|
||||
SOS: Sx :=
|
||||
1 7
|
||||
2 4
|
||||
3 -11
|
||||
4 6
|
||||
5 3
|
||||
6 1
|
||||
;
|
||||
|
||||
end;
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
GLPSOL: GLPK LP/MIP Solver, v4.47
|
||||
Parameter(s) specified in the command line:
|
||||
--math GSS.mod
|
||||
Reading model section from GSS.mod...
|
||||
Reading data section from GSS.mod...
|
||||
38 lines were read
|
||||
Generating s...
|
||||
Generating sos1...
|
||||
Model has been successfully generated
|
||||
GLPK Integer Optimizer, v4.47
|
||||
2 rows, 21 columns, 41 non-zeros
|
||||
21 integer variables, all of which are binary
|
||||
Preprocessing...
|
||||
1 row, 21 columns, 21 non-zeros
|
||||
21 integer variables, all of which are binary
|
||||
Scaling...
|
||||
A: min|aij| = 1.000e+000 max|aij| = 1.000e+000 ratio = 1.000e+000
|
||||
Problem data seem to be well scaled
|
||||
Constructing initial basis...
|
||||
Size of triangular part = 1
|
||||
Solving LP relaxation...
|
||||
GLPK Simplex Optimizer, v4.47
|
||||
1 row, 21 columns, 21 non-zeros
|
||||
* 0: obj = 1.000000000e+001 infeas = 0.000e+000 (0)
|
||||
* 1: obj = 1.100000000e+001 infeas = 0.000e+000 (0)
|
||||
OPTIMAL SOLUTION FOUND
|
||||
Integer optimization begins...
|
||||
+ 1: mip = not found yet <= +inf (1; 0)
|
||||
+ 1: >>>>> 1.100000000e+001 <= 1.100000000e+001 0.0% (1; 0)
|
||||
+ 1: mip = 1.100000000e+001 <= tree is empty 0.0% (0; 1)
|
||||
INTEGER OPTIMAL SOLUTION FOUND
|
||||
Time used: 0.0 secs
|
||||
Memory used: 0.1 Mb (135491 bytes)
|
||||
|
||||
A sub-sequence of length 2 sums to 11.000000:
|
||||
7.000000 4.000000
|
||||
|
||||
Model has been successfully processed
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
function max_sum_seq($sequence) {
|
||||
// This runs in linear time.
|
||||
$sum_start = 0;
|
||||
$sum = 0;
|
||||
$max_sum = 0;
|
||||
$max_start = 0;
|
||||
$max_len = 0;
|
||||
for ($i = 0; $i < count($sequence); $i += 1) {
|
||||
$n = $sequence[$i];
|
||||
$sum += $n;
|
||||
if ($sum > $max_sum) {
|
||||
$max_sum = $sum;
|
||||
$max_start = $sum_start;
|
||||
$max_len = $i + 1 - $max_start;
|
||||
}
|
||||
if ($sum < 0) { # start new sequence
|
||||
$sum = 0;
|
||||
$sum_start = $i + 1;
|
||||
}
|
||||
}
|
||||
return array_slice($sequence, $max_start, $max_len);
|
||||
}
|
||||
|
||||
function print_array($arr) {
|
||||
if (count($arr) > 0) {
|
||||
echo join(" ", $arr);
|
||||
} else {
|
||||
echo "(empty)";
|
||||
}
|
||||
echo '<br>';
|
||||
}
|
||||
// tests
|
||||
print_array(max_sum_seq(array(-1, 0, 15, 3, -9, 12, -4)));
|
||||
print_array(max_sum_seq(array(-1)));
|
||||
print_array(max_sum_seq(array(4, -10, 3)));
|
||||
?>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
0 15 3 -9 12
|
||||
(empty)
|
||||
4
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
use strict;
|
||||
|
||||
sub max_sub(\@) {
|
||||
my ($a, $maxs, $maxe, $s, $sum, $maxsum) = shift;
|
||||
foreach (0 .. $#$a) {
|
||||
my $t = $sum + $a->[$_];
|
||||
($s, $sum) = $t > 0 ? ($s, $t) : ($_ + 1, 0);
|
||||
|
||||
if ($maxsum < $sum) {
|
||||
$maxsum = $sum;
|
||||
($maxs, $maxe) = ($s, $_ + 1)
|
||||
}
|
||||
}
|
||||
@$a[$maxs .. $maxe - 1]
|
||||
}
|
||||
|
||||
my @a = map { int(rand(20) - 10) } 1 .. 10;
|
||||
my @b = (-1) x 10;
|
||||
|
||||
print "seq: @a\nmax: [ @{[max_sub @a]} ]\n";
|
||||
print "seq: @b\nmax: [ @{[max_sub @b]} ]\n";
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
use strict;
|
||||
|
||||
my @a = (-1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1);
|
||||
|
||||
my @maxsubarray;
|
||||
my $maxsum = 0;
|
||||
|
||||
foreach my $begin (0..$#a) {
|
||||
foreach my $end ($begin..$#a) {
|
||||
my $sum = 0;
|
||||
$sum += $_ foreach @a[$begin..$end];
|
||||
if($sum > $maxsum) {
|
||||
$maxsum = $sum;
|
||||
@maxsubarray = @a[$begin..$end];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "@maxsubarray\n";
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(maxi '((L) (apply + L))
|
||||
(mapcon '((L) (maplist reverse (reverse L)))
|
||||
(-1 -2 3 5 6 -2 -1 4 -4 2 -1) ) )
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
:- use_module(library(chr)).
|
||||
|
||||
:- chr_constraint
|
||||
init_chr/2,
|
||||
seq/2,
|
||||
% gss(Deb, Len, TT)
|
||||
gss/3,
|
||||
% gsscur(Deb, Len, TT, IdCur)
|
||||
gsscur/4,
|
||||
memoseq/3,
|
||||
clean/0,
|
||||
greatest_subsequence/0.
|
||||
|
||||
|
||||
greatest_subsequence <=>
|
||||
L = [-1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1],
|
||||
init_chr(1, L),
|
||||
find_chr_constraint(gss(Deb, Len, V)),
|
||||
clean,
|
||||
writeln(L),
|
||||
forall(between(1, Len, I),
|
||||
( J is I+Deb-1, nth1(J, L, N), format('~w ', [N]))),
|
||||
format('==> ~w ~n', [V]).
|
||||
|
||||
% destroy last constraint gss
|
||||
clean \ gss(_,_,_) <=> true.
|
||||
clean <=> true.
|
||||
|
||||
init_chr_end @ init_chr(_, []) <=> gss(0, 0, 0), gsscur(1,0,0,1).
|
||||
|
||||
init_chr_loop @ init_chr(N, [H|T]) <=> seq(N, H), N1 is N+1, init_chr(N1, T).
|
||||
|
||||
% here, we memorize the list
|
||||
gsscur_with_negative @ gsscur(Deb, Len, TT, N), seq(N, V) <=> V =< 0 |
|
||||
memoseq(Deb, Len, TT),
|
||||
TT1 is TT + V,
|
||||
N1 is N+1,
|
||||
% if TT1 becomes negative,
|
||||
% we begin a new subsequence
|
||||
( TT1 < 0 -> gsscur(N1,0,0,N1)
|
||||
; Len1 is Len + 1, gsscur(Deb, Len1, TT1, N1)).
|
||||
|
||||
gsscur_with_positive @ gsscur(Deb, Len, TT, N), seq(N, V) <=> V > 0 |
|
||||
TT1 is TT + V,
|
||||
N1 is N+1,
|
||||
Len1 is Len + 1,
|
||||
gsscur(Deb, Len1, TT1, N1).
|
||||
|
||||
gsscur_end @ gsscur(Deb, Len, TT, _N) <=> memoseq(Deb, Len, TT).
|
||||
|
||||
memoseq(_DC, _LC, TTC), gss(D, L, TT) <=> TTC =< TT |
|
||||
gss(D, L, TT).
|
||||
|
||||
memoseq(DC, LC, TTC), gss(_D, _L, TT) <=> TTC > TT |
|
||||
gss(DC, LC, TTC).
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
def maxsubseq(seq):
|
||||
return max((seq[begin:end] for begin in xrange(len(seq)+1)
|
||||
for end in xrange(begin, len(seq)+1)),
|
||||
key=sum)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
def maxsum(sequence):
|
||||
"""Return maximum sum."""
|
||||
maxsofar, maxendinghere = 0, 0
|
||||
for x in sequence:
|
||||
# invariant: ``maxendinghere`` and ``maxsofar`` are accurate for ``x[0..i-1]``
|
||||
maxendinghere = max(maxendinghere + x, 0)
|
||||
maxsofar = max(maxsofar, maxendinghere)
|
||||
return maxsofar
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
def maxsumseq(sequence):
|
||||
start, end, sum_start = -1, -1, -1
|
||||
maxsum_, sum_ = 0, 0
|
||||
for i, x in enumerate(sequence):
|
||||
sum_ += x
|
||||
if maxsum_ < sum_: # found maximal subsequence so far
|
||||
maxsum_ = sum_
|
||||
start, end = sum_start, i
|
||||
elif sum_ < 0: # start new sequence
|
||||
sum_ = 0
|
||||
sum_start = i
|
||||
assert maxsum_ == maxsum(sequence)
|
||||
assert maxsum_ == sum(sequence[start + 1:end + 1])
|
||||
return sequence[start + 1:end + 1]
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
def maxsumit(iterable):
|
||||
maxseq = seq = []
|
||||
start, end, sum_start = -1, -1, -1
|
||||
maxsum_, sum_ = 0, 0
|
||||
for i, x in enumerate(iterable):
|
||||
seq.append(x); sum_ += x
|
||||
if maxsum_ < sum_:
|
||||
maxseq = seq; maxsum_ = sum_
|
||||
start, end = sum_start, i
|
||||
elif sum_ < 0:
|
||||
seq = []; sum_ = 0
|
||||
sum_start = i
|
||||
assert maxsum_ == sum(maxseq[:end - start])
|
||||
return maxseq[:end - start]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
f = maxsumit
|
||||
assert f([]) == []
|
||||
assert f([-1]) == []
|
||||
assert f([0]) == []
|
||||
assert f([1]) == [1]
|
||||
assert f([1, 0]) == [1]
|
||||
assert f([0, 1]) == [0, 1]
|
||||
assert f([0, 1, 0]) == [0, 1]
|
||||
assert f([2]) == [2]
|
||||
assert f([2, -1]) == [2]
|
||||
assert f([-1, 2]) == [2]
|
||||
assert f([-1, 2, -1]) == [2]
|
||||
assert f([2, -1, 3]) == [2, -1, 3]
|
||||
assert f([2, -1, 3, -1]) == [2, -1, 3]
|
||||
assert f([-1, 2, -1, 3]) == [2, -1, 3]
|
||||
assert f([-1, 2, -1, 3, -1]) == [2, -1, 3]
|
||||
assert f([-1, 1, 2, -5, -6]) == [1,2]
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
max.subseq <- function(x) {
|
||||
cumulative <- cumsum(x)
|
||||
min.cumulative.so.far <- Reduce(min, cumulative, accumulate=TRUE)
|
||||
end <- which.max(cumulative-min.cumulative.so.far)
|
||||
begin <- which.min(c(0, cumulative[1:end]))
|
||||
if (end >= begin) x[begin:end] else x[c()]
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
> max.subseq(c(-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1))
|
||||
[1] 3 5 6 -2 -1 4
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*REXX program finds the shortest greatest continous subsequence sum.*/
|
||||
arg @ /*get the arugment LIST (if any).*/
|
||||
say 'words='words(@) ' list='@ /*show WORDS and LIST to console.*/
|
||||
sum=word(@,1) /*a "starter" sum (of a sequence)*/
|
||||
w=words(@) /*number of words in the list. */
|
||||
at=1 /*where the sequence starts at. */
|
||||
L=0 /*the length of the sequence. */
|
||||
/*process the list. */
|
||||
do j=1 for w; f=word(@,j)
|
||||
do k=j to w; s=f
|
||||
do m=j+1 to k
|
||||
s=s+word(@,m)
|
||||
end /*m*/
|
||||
if s>sum then do; sum=s; at=j; L=k-j+1; end
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
|
||||
seq=subword(@,at,L); if seq=='' then seq="[NULL]"
|
||||
say; say 'sum='word(sum 0,1)/1 " sequence="seq
|
||||
/*stick a fork in it, we're done.*/
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/*REXX program finds the longest greatest continous subsequence sum. */
|
||||
arg @ /*get the arugment LIST (if any).*/
|
||||
say 'words='words(@) ' list='@ /*show WORDS and LIST to console.*/
|
||||
sum=word(@,1) /*a "starter" sum (of a sequence)*/
|
||||
w=words(@) /*number of words in the list. */
|
||||
at=1 /*where the sequence starts at. */
|
||||
L=0 /*the length of the sequence. */
|
||||
/*process the list. */
|
||||
do j=1 for w; f=word(@,j)
|
||||
do k=j to w; s=f
|
||||
do m=j+1 to k
|
||||
s=s+word(@,m)
|
||||
end /*m*/
|
||||
_=k-j+1
|
||||
if (s==sum & _>L) | s>sum then do; sum=s; at=j; L=_; end
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
|
||||
seq=subword(@,at,L); if seq=='' then seq="[NULL]"
|
||||
say; say 'sum='word(sum 0,1)/1 " sequence="seq
|
||||
/*stick a fork in it, we're done.*/
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* REXX ***************************************************************
|
||||
* 09.08.2012 Walter Pachl translated Pascal algorithm to Rexx
|
||||
**********************************************************************/
|
||||
s=' -1 -2 3 5 6 -2 -1 4 -4 2 -1'
|
||||
maxSum = 0
|
||||
seqStart = 0
|
||||
seqEnd = -1
|
||||
do i = 1 To words(s)
|
||||
seqSum = 0
|
||||
Do j = i to words(s)
|
||||
seqSum = seqSum + word(s,j)
|
||||
if seqSum > maxSum then Do
|
||||
maxSum = seqSum
|
||||
seqStart = i
|
||||
seqEnd = j
|
||||
end
|
||||
end
|
||||
end
|
||||
Say 'Sequence:'
|
||||
Say s
|
||||
Say 'Subsequence with greatest sum: '
|
||||
If seqend<seqstart Then
|
||||
Say 'empty'
|
||||
Else Do
|
||||
ol=copies(' ',seqStart-1)
|
||||
Do i = seqStart to seqEnd
|
||||
ol=ol||right(word(s,i),3)
|
||||
End
|
||||
Say ol
|
||||
Say 'Sum:' maxSum
|
||||
End
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(define (max-subseq l)
|
||||
(define-values (_ result _1 max-sum)
|
||||
(for/fold ([seq '()] [max-seq '()] [sum 0] [max-sum 0])
|
||||
([i l])
|
||||
(cond [(> (+ sum i) max-sum)
|
||||
(values (cons i seq) (cons i seq) (+ sum i) (+ sum i))]
|
||||
[(< (+ sum i) 0)
|
||||
(values '() max-seq 0 max-sum)]
|
||||
[else
|
||||
(values (cons i seq) max-seq (+ sum i) max-sum)])))
|
||||
(values (reverse result) max-sum))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
> (max-subseq '(-1 -2 3 5 6 -2 -1 4 -4 2 -1))
|
||||
'(3 5 6 -2 -1 4)
|
||||
15
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
Infinity = 1.0/0
|
||||
def subarray_sum(arr)
|
||||
max, slice = -Infinity, []
|
||||
arr.each_with_index do |n, i|
|
||||
(i...arr.length).each do |j|
|
||||
sum = arr[i..j].inject(0) { |x, sum| sum += x }
|
||||
if sum > max
|
||||
max = sum
|
||||
slice = arr[i..j]
|
||||
end
|
||||
end
|
||||
end
|
||||
[max, slice]
|
||||
end
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# the trick is that at any point
|
||||
# in the iteration if starting a new chain is
|
||||
# better than your current score with this element
|
||||
# added to it, then do so.
|
||||
# the interesting part is proving the math behind it
|
||||
Infinity = 1.0/0
|
||||
def subarray_sum(arr)
|
||||
curr,max = -Infinity,-Infinity
|
||||
first,last= 0,0
|
||||
arr.each_with_index do |e,i|
|
||||
curr = e + curr
|
||||
if(e>curr)
|
||||
curr = e
|
||||
first=i
|
||||
end
|
||||
if(curr > max)
|
||||
max = curr
|
||||
last=i
|
||||
end
|
||||
end
|
||||
return max,arr[first...last+1]
|
||||
end
|
||||
|
||||
input=[1,2,3,4,5,-8,-9,-20,40,25,-5]
|
||||
p subarray_sum(input)
|
||||
=>[65, [40, 25]]
|
||||
|
||||
input=[-3, -1]
|
||||
p subarray_sum(input)
|
||||
=>[-1, [-1]]
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
def maxSubseq(l: List[Int]) = l.scanRight(Nil : List[Int]) {
|
||||
case (el, acc) if acc.sum + el < 0 => Nil
|
||||
case (el, acc) => el :: acc
|
||||
} max Ordering.by((_: List[Int]).sum)
|
||||
|
||||
def biggestMaxSubseq(l: List[Int]) = l.scanRight(Nil : List[Int]) {
|
||||
case (el, acc) if acc.sum + el < 0 => Nil
|
||||
case (el, acc) => el :: acc
|
||||
} max Ordering.by((ss: List[Int]) => (ss.sum, ss.length))
|
||||
|
||||
def biggestMaxSubseq[N](l: List[N])(implicit n: Numeric[N]) = {
|
||||
import n._
|
||||
l.scanRight(Nil : List[N]) {
|
||||
case (el, acc) if acc.sum + el < zero => Nil
|
||||
case (el, acc) => el :: acc
|
||||
} max Ordering.by((ss: List[N]) => (ss.sum, ss.length))
|
||||
}
|
||||
|
||||
def linearBiggestMaxSubseq[N](l: List[N])(implicit n: Numeric[N]) = {
|
||||
import n._
|
||||
l.scanRight((zero, Nil : List[N])) {
|
||||
case (el, (acc, _)) if acc + el < zero => (zero, Nil)
|
||||
case (el, (acc, ss)) => (acc + el, el :: ss)
|
||||
} max Ordering.by((t: (N, List[N])) => (t._1, t._2.length)) _2
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(define (maxsubseq in)
|
||||
(let loop
|
||||
((_sum 0) (_seq (list)) (maxsum 0) (maxseq (list)) (l in))
|
||||
(if (null? l)
|
||||
(cons maxsum (reverse maxseq))
|
||||
(let* ((x (car l)) (sum (+ _sum x)) (seq (cons x _seq)))
|
||||
(if (> sum 0)
|
||||
(if (> sum maxsum)
|
||||
(loop sum seq sum seq (cdr l))
|
||||
(loop sum seq maxsum maxseq (cdr l)))
|
||||
(loop 0 (list) maxsum maxseq (cdr l)))))))
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package require Tcl 8.5
|
||||
set a {-1 -2 3 5 6 -2 -1 4 -4 2 -1}
|
||||
|
||||
# from the Perl solution
|
||||
proc maxsumseq1 {a} {
|
||||
set len [llength $a]
|
||||
set maxsum 0
|
||||
|
||||
for {set start 0} {$start < $len} {incr start} {
|
||||
for {set end $start} {$end < $len} {incr end} {
|
||||
set sum 0
|
||||
incr sum [expr [join [lrange $a $start $end] +]]
|
||||
if {$sum > $maxsum} {
|
||||
set maxsum $sum
|
||||
set maxsumseq [lrange $a $start $end]
|
||||
}
|
||||
}
|
||||
}
|
||||
return $maxsumseq
|
||||
}
|
||||
|
||||
# from the Python solution
|
||||
proc maxsumseq2 {sequence} {
|
||||
set start -1
|
||||
set end -1
|
||||
set maxsum_ 0
|
||||
set sum_ 0
|
||||
for {set i 0} {$i < [llength $sequence]} {incr i} {
|
||||
set x [lindex $sequence $i]
|
||||
incr sum_ $x
|
||||
if {$maxsum_ < $sum_} {
|
||||
set maxsum_ $sum_
|
||||
set end $i
|
||||
} elseif {$sum_ < 0} {
|
||||
set sum_ 0
|
||||
set start $i
|
||||
}
|
||||
}
|
||||
assert {$maxsum_ == [maxsum $sequence]}
|
||||
assert {$maxsum_ == [sum [lrange $sequence [expr {$start + 1}] $end]]}
|
||||
return [lrange $sequence [expr {$start + 1}] $end]
|
||||
}
|
||||
|
||||
proc maxsum {sequence} {
|
||||
set maxsofar 0
|
||||
set maxendinghere 0
|
||||
foreach x $sequence {
|
||||
set maxendinghere [expr {max($maxendinghere + $x, 0)}]
|
||||
set maxsofar [expr {max($maxsofar, $maxendinghere)}]
|
||||
}
|
||||
return $maxsofar
|
||||
}
|
||||
|
||||
proc assert {condition {message "Assertion failed!"}} {
|
||||
if { ! [uplevel 1 [list expr $condition]]} {
|
||||
return -code error $message
|
||||
}
|
||||
}
|
||||
|
||||
proc sum list {
|
||||
expr [join $list +]
|
||||
}
|
||||
|
||||
|
||||
puts "sequence: $a"
|
||||
puts "maxsumseq1: [maxsumseq1 $a]"
|
||||
puts [time {maxsumseq1 $a} 1000]
|
||||
puts "maxsumseq2: [maxsumseq2 $a]"
|
||||
puts [time {maxsumseq2 $a} 1000]
|
||||
Loading…
Add table
Add a link
Reference in a new issue