-
Notifications
You must be signed in to change notification settings - Fork 0
/
knapsackProblem.py
116 lines (82 loc) · 2.99 KB
/
knapsackProblem.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# coding=utf-8
from simpleai.search import SearchProblem
from simpleai.search.local import *
import random
numberOfItems = int(input("Enter number of items: "))
knapsackCapacity = int(input("Enter knapsack capacity: "))
weight = []
for i in range(numberOfItems):
print("Enter of %d. weight : " % (i + 1), end="")
weight.append(int(input()))
value = []
for i in range(numberOfItems):
print("Enter of %d. value : " % (i + 1), end="")
value.append(int(input()))
bag = []
for i in range(numberOfItems):
bag.append(0)
# print(len(bag))
print("# items: ", numberOfItems)
print("Capacity: ", knapsackCapacity)
print("Weights: ", weight)
print("Values: ", value)
def listToString(s):
str1 = ""
for i in range(len(s)):
str1 += str(s[i])
return str1
def stringToList(s):
list1 = []
for i in range(len(s)):
list1.append(int(s[i]))
return list1
class knapsackProblem(SearchProblem):
def actions(self, state):
return listToString(range(len(state)))
def result(self, state, action):
if (state[int(action)]) == '0':
return state[:int(action)] + '1' + state[int(action) + 1:]
else:
return state[:int(action)] + '0' + state[int(action) + 1:]
def value(self, state):
totalWeight = 0
for i in range(len(state)):
totalWeight += int(state[i]) * weight[i]
if (totalWeight > knapsackCapacity):
return 0
totalValue = 0
for i in range(len(state)):
totalValue += int(state[i]) * value[i]
#print(totalValue)
return totalValue
def generate_random_state(self):
temp = []
for i in range(numberOfItems):
temp.append(random.choice('01'))
return listToString(temp)
def crossover(self, state1, state2):
cut_point = random.randint(0, numberOfItems)
child = state1[:cut_point] + state2[cut_point:]
return child
def mutate(self, state):
mutation = random.choice(' 01')
mutation_point = random.randint(0, numberOfItems)
mutated = ''.join([state[i] if i != mutation_point else mutation
for i in range(len(state))])
return mutated
problem = knapsackProblem(initial_state=listToString(bag))
result = genetic(problem, population_size=numberOfItems, mutation_chance=0.1,
iterations_limit=0, viewer=None)
#result = hill_climbing(problem, iterations_limit=0, viewer=None)
#restarts_limit = int(input("Enter a restarts limit: "))
#result = hill_climbing_random_restarts(problem, restarts_limit, iterations_limit=0, viewer=None)
totalWeight = 0
for i in range(len(result.state)):
totalWeight += int(result.state[i]) * weight[i]
print("Total weight of the selected items: %d " %totalWeight)
totalValue = 0
for i in range(len(result.state)):
totalValue += int(result.state[i]) * value[i]
print("Total profit of the selected items: %d" %totalValue)
print(result.state)
print("The list of items selected:", result.path())