Started to implement Knapsack.
parent
fd8ce084e6
commit
cf4cef7726
|
@ -1,4 +1,13 @@
|
|||
{
|
||||
"build_systems":
|
||||
[
|
||||
{
|
||||
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
|
||||
"name": "Anaconda Python Builder",
|
||||
"selector": "source.python",
|
||||
"shell_cmd": "\"python\" -u \"$file\""
|
||||
}
|
||||
],
|
||||
"folders":
|
||||
[
|
||||
{
|
||||
|
|
|
@ -62,8 +62,58 @@ def solve_knapsack_dynamic(knapsack):
|
|||
|
||||
|
||||
def solve_knapsack_depth_first_search(knapsack):
|
||||
objective = 0
|
||||
pass
|
||||
knapsack.items.sort(key=lambda item: item.value / item.weight,
|
||||
reverse=True)
|
||||
num_items = len(knapsack.items)
|
||||
result = {"objective": 0,
|
||||
"path": []}
|
||||
|
||||
def get_max_value(from_index, capacity):
|
||||
value = 0
|
||||
for item in knapsack.items[from_index:]:
|
||||
if item.weight <= capacity:
|
||||
value += item.value
|
||||
capacity -= item.weight
|
||||
else:
|
||||
value += int((item.weight / capacity) * item.value) + 1
|
||||
return value
|
||||
return value
|
||||
|
||||
return sum([i.value for i in knapsack.items[from_index:]])
|
||||
|
||||
def search(index, capacity, value, path, result):
|
||||
|
||||
if capacity < 0:
|
||||
return
|
||||
|
||||
if value > result["objective"]:
|
||||
result["objective"] = value
|
||||
result["path"] = path
|
||||
|
||||
# Take current item.
|
||||
if value + get_max_value(index, capacity) > result["objective"]:
|
||||
item = knapsack.items[index]
|
||||
new_index = index + 1
|
||||
new_path = path + [1]
|
||||
new_capacity = capacity - item.weight
|
||||
new_value = value + item.value
|
||||
search(new_index, new_capacity, new_value, new_path, result)
|
||||
|
||||
# Do not take current item.
|
||||
new_index = index + 1
|
||||
if value + get_max_value(new_index, capacity) > result["objective"]:
|
||||
new_path = path + [0]
|
||||
search(new_index, capacity, value, new_path, result)
|
||||
|
||||
def correct_path(path):
|
||||
path = path + [0] * (num_items - len(path))
|
||||
values = zip(path, knapsack.items)
|
||||
path = [v[0] for v in sorted(values, key=lambda value: value[1].index)]
|
||||
return path
|
||||
|
||||
search(0, knapsack.capacity, 0, [], result)
|
||||
|
||||
return Result(result["objective"], 1, correct_path(result["path"]))
|
||||
|
||||
|
||||
def input_data_to_knapsack(input_data):
|
||||
|
@ -74,7 +124,7 @@ def input_data_to_knapsack(input_data):
|
|||
for i in range(1, item_count + 1):
|
||||
line = lines[i]
|
||||
value, weight = map(int, line.split())
|
||||
items.append(Item(i-1, value, weight))
|
||||
items.append(Item(i - 1, value, weight))
|
||||
|
||||
k = Knapsack(item_count, capacity, items)
|
||||
return k
|
||||
|
@ -87,3 +137,10 @@ def result_to_output_data(result):
|
|||
return output_data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
file_location = "./data/ks_60_0"
|
||||
with open(file_location, 'r') as input_data_file:
|
||||
input_data = input_data_file.read()
|
||||
k = input_data_to_knapsack(input_data)
|
||||
print(result_to_output_data(solve_knapsack_dynamic(k)))
|
||||
print(result_to_output_data(solve_knapsack_depth_first_search(k)))
|
||||
|
|
|
@ -25,4 +25,3 @@ if __name__ == '__main__':
|
|||
print("This test requires an input file. "
|
||||
"Please select one from the data directory. "
|
||||
"(i.e. python solver.py ./data/ks_4_0)")
|
||||
|
||||
|
|
Loading…
Reference in New Issue