Skip to content

Commit be35813

Browse files
authored
Adding Two Algorithms (#102)
* Fractional Knapsack Algorithm * Longest Palindrome Substring Algorithm
1 parent f1d3088 commit be35813

2 files changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# https://en.wikipedia.org/wiki/Continuous_knapsack_problem
2+
# https://www.guru99.com/fractional-knapsack-problem-greedy.html
3+
# https://medium.com/walkinthecode/greedy-algorithm-fractional-knapsack-problem-9aba1daecc93
4+
5+
"""
6+
Author : Anubhav Sharma
7+
This is a pure Python implementation of Dynamic Programming solution to the Fractional Knapsack of a given items and weights.
8+
The problem is :
9+
Given N items and weights, to find the max weight of item to put in fractional knapsack in that given knapsack and
10+
return it.
11+
Example: Weight of knapsack to carry, Items and there weights as input will return
12+
Items in fraction to put in the knapsack as per weight as output
13+
"""
14+
15+
def fractional_knapsack(value: list[int], weight: list[int], capacity: int) -> tuple[int, list[int]]:
16+
"""
17+
>>> value = [1, 3, 5, 7, 9]
18+
>>> weight = [0.9, 0.7, 0.5, 0.3, 0.1]
19+
>>> fractional_knapsack(value, weight, 5)
20+
(25, [1, 1, 1, 1, 1])
21+
>>> fractional_knapsack(value, weight, 15)
22+
(25, [1, 1, 1, 1, 1])
23+
>>> fractional_knapsack(value, weight, 25)
24+
(25, [1, 1, 1, 1, 1])
25+
>>> fractional_knapsack(value, weight, 26)
26+
(25, [1, 1, 1, 1, 1])
27+
>>> fractional_knapsack(value, weight, -1)
28+
(-90.0, [0, 0, 0, 0, -10.0])
29+
>>> fractional_knapsack([1, 3, 5, 7], weight, 30)
30+
(16, [1, 1, 1, 1])
31+
>>> fractional_knapsack(value, [0.9, 0.7, 0.5, 0.3, 0.1], 30)
32+
(25, [1, 1, 1, 1, 1])
33+
>>> fractional_knapsack([], [], 30)
34+
(0, [])
35+
"""
36+
index = list(range(len(value)))
37+
ratio = [v / w for v, w in zip(value, weight)]
38+
index.sort(key=lambda i: ratio[i], reverse=True)
39+
40+
max_value = 0
41+
fractions = [0] * len(value)
42+
for i in index:
43+
if weight[i] <= capacity:
44+
fractions[i] = 1
45+
max_value += value[i]
46+
capacity -= weight[i]
47+
else:
48+
fractions[i] = capacity / weight[i]
49+
max_value += value[i] * capacity / weight[i]
50+
break
51+
52+
return max_value, fractions
53+
54+
55+
if __name__ == "__main__":
56+
n = int(input("Enter number of items: "))
57+
value = input(f"Enter the values of the {n} item(s) in order: ").split()
58+
value = [int(v) for v in value]
59+
weight = input(f"Enter the positive weights of the {n} item(s) in order: ".split())
60+
weight = [int(w) for w in weight]
61+
capacity = int(input("Enter maximum weight: "))
62+
63+
max_value, fractions = fractional_knapsack(value, weight, capacity)
64+
print("The maximum value of items that can be carried:", max_value)
65+
print("The fractions in which the items should be taken:", fractions)
66+
67+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""
2+
Author : Anubhav Sharma
3+
This is a pure Python implementation of Dynamic Programming solution to the longest
4+
palindrome substring of a given string.
5+
I use Manacher Algorithm which is amazing algorithm and find solution in linear time complexity.
6+
The problem is :
7+
Given a string, to find the longest palindrome sub-string in that given string and
8+
return it.
9+
Example: aabbabbaababa as input will return
10+
aabbabbaa as output
11+
"""
12+
def manacher_algo_lps(s,n):
13+
"""
14+
PARAMETER
15+
--------------
16+
s = string
17+
n = string_len (int)
18+
manacher Algorithm is the fastest technique to find the longest palindrome substring in any given string.
19+
RETURN
20+
---------------
21+
Longest Palindrome String(String)
22+
"""
23+
# variables to use
24+
p = [0] * n
25+
c = 0
26+
r = 0
27+
maxlen = 0
28+
29+
# Main Algorithm
30+
for i in range(n):
31+
mirror = 2*c-i # Finding the Mirror(i.e. Pivort to break) of the string
32+
if i < r:
33+
p[i] = (r - i) if (r - i) < p[mirror] else p[mirror]
34+
a = i + (1 + p[i])
35+
b = i - (1 + p[i])
36+
37+
# Attempt to expand palindrome centered at currentRightPosition i
38+
# Here for odd positions, we compare characters and
39+
# if match then increment LPS Length by ONE
40+
# If even position, we just increment LPS by ONE without
41+
# any character comparison
42+
while a<n and b>=0 and s[a] == s[b]:
43+
p[i] += 1
44+
a += 1
45+
b -= 1
46+
if (i + p[i]) > r:
47+
c = i
48+
r = i + p[i]
49+
if p[i] > maxlen: # Track maxLPSLength
50+
maxlen = p[i]
51+
i = p.index(maxlen)
52+
return s[i-maxlen:maxlen+i][1::2]
53+
54+
def longest_palindrome(s: str) -> str:
55+
s = '#'.join(s)
56+
s = '#'+s+'#'
57+
58+
# Calling Manacher Algorithm
59+
return manacher_algo_lps(s,len(s))
60+
61+
def main():
62+
63+
# Input to enter
64+
input_string = "abbbacdcaacdca"
65+
66+
# Calling the longest palindrome algorithm
67+
s = longest_palindrome(input_string)
68+
print("LPS Using Manacher Algorithm {}".format(s))
69+
70+
# Calling Main Function
71+
if __name__ == "__main__":
72+
73+
main()
74+
75+

0 commit comments

Comments
 (0)