Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 13891

Optimization problem in Python. Dynamic programming

$
0
0

I have the following task.

There is a list of segments: list[int]. All these segments must be involved. We have the length of the rope and infinite number of ropes. when we make combinations, most often there is a remainder. For example, the length of the rope is 10000, and the segments are [2000, 2000, 2000, 2000, 1500] and here we have a remainder of 500. And when there are more segments, we will use several ropes and each will have a remainder, and this is what needs to be minimized.

Here's the code:

def max_sum_sequence(arr, l) -> tuple:    n = len(arr)    dp = [0] * (l + 1)    for i in range(n):        for j in range(l, arr[i] - 1, -1):            dp[j] = max(dp[j], dp[j - arr[i]] + arr[i])    result = []    current_sum = l    if sum(arr) <= current_sum:        return tuple(item for item in reversed(arr))    for num in reversed(arr):        if current_sum >= num and dp[current_sum - num] + num == dp[current_sum]:            result.append(num)            current_sum -= num    return tuple(result)def update_segments(arr: list, l: int) -> list[list[tuple[int], int]]:    result: list[list[tuple[int], int]] = []    while True:        optimal_sequence: tuple[int] = max_sum_sequence(arr, l)        remainder: int = length - sum(optimal_sequence)        result.append([optimal_sequence, remainder])        for item in optimal_sequence:            arr.remove(item)        if len(arr) == 0:            return resultif __name__ == "__main__":    remainder_summary: int = 0    print("Enter a length:")    length: int = 12000    segments = [1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530,                1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530,                1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530,                1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 3260, 3260, 3260, 3260, 3760, 3760, 1660, 1660,                1660, 1660, 1660, 1660, 3650, 3650, 3650, 1970, 1970, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330,                1330, 1330, 1330, 1330, 1330, 1330, 2410, 2410, 1180, 1180, 1180, 1180, 550, 550, 550, 550]    optimal_values: list = update_segments(segments, length)    for item in optimal_values:        print(f"{item[0]} - {item[1]}")        remainder_summary += item[1]    print(f"Final remainder = {remainder_summary}")

Output:

(550, 550, 550, 550, 1180, 1180, 1180, 2410, 1330, 1970) - 550(1180, 2410, 1330, 1660, 1660, 3760) - 0(1330, 3650, 3760, 3260) - 0(1970, 3650, 1660, 1660, 1530, 1530) - 0(1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330) - 30(1330, 1330, 1660, 3260, 1530, 1530) - 1360(1660, 3260, 3260) - 3820(1530, 1530, 1530, 1530, 1530) - 4350

For some reason, at iteration 7, the algorithm does not take segments that can be included in it in order to reduce the remainder. And this happens in all subsequent iterations.

What is the mistake?

upd 01.27.2024

def max_sum_sequence(arr, l) -> tuple:    n = len(arr)    dp = [0] * (l + 1)    choices = [[] for _ in range(l + 1)]    for i in range(n):        for j in range(l, arr[i] - 1, -1):            if dp[j] < dp[j - arr[i]] + arr[i]:                dp[j] = dp[j - arr[i]] + arr[i]                choices[j] = choices[j - arr[i]] + [arr[i]]    return tuple(choices[l])def update_segments(arr: list, l: int) -> list[list[tuple[int], int]]:    result: list[list[tuple[int], int]] = []    while True:        optimal_sequence: tuple[int] = max_sum_sequence(arr, l)        remainder: int = l - sum(optimal_sequence)        result.append([optimal_sequence, remainder])        for item in optimal_sequence:            arr.remove(item)        if len(arr) == 0:            return resultdef get_optimal(length: int, segments: list[list[int,int]) -> list[list[tuple[int], int]]:    length: int = length    segments: list[int] = modify_segments_list(segments)    optimal_values: list[list[tuple[int], int]] = update_segments(segments, length)    return optimal_values

There is output of this problem

|3840--2605--2605--2940| ==> 10|1840--1840--2430--2940--2940| ==> 10|1840--1840--2430--2940--2940| ==> 10|1840--1840--2430--2940--2940| ==> 10|2430--2940--2840--3780| ==> 10|5365--2840--3780| ==> 15|1840--3370--3370--3370| ==> 50|5020--3370--3545| ==> 65|1840--2840--3545--3545| ==> 230|3840--5020--2840| ==> 300|3840--3840--3840| ==> 480|3840--3780--3780| ==> 600|2840--2840--2840--2840| ==> 640|3780--3780--3545| ==> 895

Viewing all articles
Browse latest Browse all 13891

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>