Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- #required for GiocoScopa
- from copy import deepcopy
- #the subset sum problem
- #find the possible combination of integer list that sums up to a given n
- #a brute force algorithm to find the subset sum
- #more then 10 elements in the list get slower
- #tested only if the list of element does not contain a repeated element
- class Node:
- def __init__ (self, value = None):
- self.card = value #holds the value
- self.nodes = [] #holds the nodes
- def add_node(self, node):
- self.nodes.append(node)
- def get_card(self):
- return self.card
- def value(self):
- return self.card.number
- def __str__(self):
- #print the node with this format
- #id:0x10049f7e8 value: 5 childs: 0
- s = 'id:'+ str(hex(id(self))) + ' card: ' + str(self.card) + " childs: " + str(len(self.nodes))
- return s
- class SumTree:
- def __init__(self, deck, target = None):
- self.root = Node() #first node has value 0
- #two option one build the entire tree which is n*n or more big
- #the other build the tree only until a known target
- if target == None: "fool you forgot the target"
- self.build_from_list_opt(self.root, deck, target)
- def build_from_list_opt(self, node, deck, target):
- #populate the tree
- for i , card in enumerate(deck.cards):
- if card.number <= target:
- child = Node(card)
- node.add_node(child) #add the node to the parent
- #the list is copied to an other list without the first element
- #already stored in in the node child
- copy_deck = deepcopy(deck)
- copy_deck.cards = copy_deck.cards[i+1:]
- #the list get smaller and smaller until it has no elements
- #and the recursion stops
- if not (len(copy_deck.cards) == 0):
- self.build_from_list_opt(child, copy_deck, target)
- def find_sum_node(self, node, sum, path, r_count, res_path, target):
- #return the numbers (path) that composed that target
- #argument list:
- # node: the actual node
- # sum: sum until the actual node
- # path: list containing the values of the nodes summing up to the actual node
- # r_count: recursion count needed to reset the path
- # res_path: stores the values that sums up to target
- # target: given integer
- if not r_count == 0: sum += node.value()
- r_count += 1
- path.append(node.get_card())
- if (sum == target):
- res_path.append(path[1:]) #the root is not appended in the list
- elif (sum > target):
- pass
- else:
- for child in node.nodes:
- #reset the path until the switch
- path = path[:r_count]
- self.find_sum_node(child, sum, path, r_count, res_path, target)
- def find_sum(self, target):
- res_path, tmp_path = [], []
- sum, r_count = 0, 0
- self.find_sum_node(self.root, sum, tmp_path, r_count, res_path, target)
- return res_path
- def print_node(self,node, s, count):
- s = " |"*count + str(node)+ "\n"
- count += 1
- for child in node.nodes:
- s += self.print_node(child, s, count)
- return s
- def __str__(self):
- return self.print_node(self.root, "", 0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement