আমি একটি সাধারণ গাছ নির্মাণের চেষ্টা করছি।
পাইথনে এটি প্রয়োগের জন্য কোনও বিল্ট-ইন ডেটা স্ট্রাকচার রয়েছে কি?
আমি একটি সাধারণ গাছ নির্মাণের চেষ্টা করছি।
পাইথনে এটি প্রয়োগের জন্য কোনও বিল্ট-ইন ডেটা স্ট্রাকচার রয়েছে কি?
উত্তর:
আমি https://pypi.python.org/pypi/anytree (আমি লেখক) প্রস্তাব দিচ্ছি
from anytree import Node, RenderTree
udo = Node("Udo")
marc = Node("Marc", parent=udo)
lian = Node("Lian", parent=marc)
dan = Node("Dan", parent=udo)
jet = Node("Jet", parent=dan)
jan = Node("Jan", parent=dan)
joe = Node("Joe", parent=dan)
print(udo)
Node('/Udo')
print(joe)
Node('/Udo/Dan/Joe')
for pre, fill, node in RenderTree(udo):
print("%s%s" % (pre, node.name))
Udo
├── Marc
│ └── Lian
└── Dan
├── Jet
├── Jan
└── Joe
print(dan.children)
(Node('/Udo/Dan/Jet'), Node('/Udo/Dan/Jan'), Node('/Udo/Dan/Joe'))
যে কোনও সাথে এর একটি শক্তিশালী এপিআই রয়েছে:
anytree
সম্ভবত একটি দুর্দান্ত গ্রন্থাগার হলেও এটি একটি অজগর প্রশ্ন, নোড.জেএস প্রশ্ন নয়।
জাভা যেমন পাইথনের "বিল্ট-ইন" ডেটা স্ট্রাকচারের বিস্তৃত বিস্তৃত পরিধি রাখেনি। তবে পাইথন গতিশীল হওয়ার কারণে একটি সাধারণ গাছ তৈরি করা সহজ। উদাহরণস্বরূপ, একটি বাইনারি গাছ হতে পারে:
class Tree:
def __init__(self):
self.left = None
self.right = None
self.data = None
আপনি এটি এর মতো ব্যবহার করতে পারেন:
root = Tree()
root.data = "root"
root.left = Tree()
root.left.data = "left"
root.right = Tree()
root.right.data = "right"
class Tree
বস্তু থেকে
object
হ'ল মাঝে মাঝে কেবল একটি গাইডলাইন: কোনও শ্রেণি যদি অন্য কোনও বেস শ্রেণীর থেকে উত্তরাধিকার সূত্রে আসে তবে স্পষ্টভাবে বস্তু থেকে উত্তরাধিকার সূত্রে প্রাপ্ত। এটি নেস্টেড ক্লাসগুলিতেও প্রযোজ্য। দেখুন গুগল পাইথন স্টাইল গাইড
জেনেরিক ট্রি হ'ল শূন্য বা ততোধিক শিশু সহ একটি নোড, প্রত্যেকে একটি যথাযথ (বৃক্ষ) নোড। এটি বাইনারি গাছের মতো নয়, তারা বিভিন্ন ডেটা স্ট্রাকচার, যদিও উভয়ই কিছু পরিভাষা ভাগ করে।
পাইথনে জেনেরিক গাছগুলির জন্য কোনও বিল্টিন ডেটা কাঠামো নেই তবে এটি ক্লাসগুলির সাথে সহজেই প্রয়োগ করা হয়েছে।
class Tree(object):
"Generic tree node."
def __init__(self, name='root', children=None):
self.name = name
self.children = []
if children is not None:
for child in children:
self.add_child(child)
def __repr__(self):
return self.name
def add_child(self, node):
assert isinstance(node, Tree)
self.children.append(node)
# *
# /|\
# 1 2 +
# / \
# 3 4
t = Tree('*', [Tree('1'),
Tree('2'),
Tree('+', [Tree('3'),
Tree('4')])])
আপনি চেষ্টা করতে পারেন:
from collections import defaultdict
def tree(): return defaultdict(tree)
users = tree()
users['harold']['username'] = 'hrldcpr'
users['handler']['username'] = 'matthandlersux'
এখানে প্রস্তাবিত হিসাবে: https://gist.github.com/2012250
class Node:
"""
Class Node
"""
def __init__(self, value):
self.left = None
self.data = value
self.right = None
class Tree:
"""
Class tree will provide a tree as well as utility functions.
"""
def createNode(self, data):
"""
Utility function to create a node.
"""
return Node(data)
def insert(self, node , data):
"""
Insert function will insert a node into tree.
Duplicate keys are not allowed.
"""
#if tree is empty , return a root node
if node is None:
return self.createNode(data)
# if data is smaller than parent , insert it into left side
if data < node.data:
node.left = self.insert(node.left, data)
elif data > node.data:
node.right = self.insert(node.right, data)
return node
def search(self, node, data):
"""
Search function will search a node into tree.
"""
# if root is None or root is the search data.
if node is None or node.data == data:
return node
if node.data < data:
return self.search(node.right, data)
else:
return self.search(node.left, data)
def deleteNode(self,node,data):
"""
Delete function will delete a node into tree.
Not complete , may need some more scenarion that we can handle
Now it is handling only leaf.
"""
# Check if tree is empty.
if node is None:
return None
# searching key into BST.
if data < node.data:
node.left = self.deleteNode(node.left, data)
elif data > node.data:
node.right = self.deleteNode(node.right, data)
else: # reach to the node that need to delete from BST.
if node.left is None and node.right is None:
del node
if node.left == None:
temp = node.right
del node
return temp
elif node.right == None:
temp = node.left
del node
return temp
return node
def traverseInorder(self, root):
"""
traverse function will print all the node in the tree.
"""
if root is not None:
self.traverseInorder(root.left)
print root.data
self.traverseInorder(root.right)
def traversePreorder(self, root):
"""
traverse function will print all the node in the tree.
"""
if root is not None:
print root.data
self.traversePreorder(root.left)
self.traversePreorder(root.right)
def traversePostorder(self, root):
"""
traverse function will print all the node in the tree.
"""
if root is not None:
self.traversePostorder(root.left)
self.traversePostorder(root.right)
print root.data
def main():
root = None
tree = Tree()
root = tree.insert(root, 10)
print root
tree.insert(root, 20)
tree.insert(root, 30)
tree.insert(root, 40)
tree.insert(root, 70)
tree.insert(root, 60)
tree.insert(root, 80)
print "Traverse Inorder"
tree.traverseInorder(root)
print "Traverse Preorder"
tree.traversePreorder(root)
print "Traverse Postorder"
tree.traversePostorder(root)
if __name__ == "__main__":
main()
গাছগুলি এখানে অন্তর্নির্মিত নেই, তবে আপনি তালিকা থেকে নোড প্রকারের সাবক্লাসিং করে এবং ট্র্যাভারসাল পদ্ধতিগুলি লিখে সহজেই একটি তৈরি করতে পারেন। আপনি যদি এটি করেন তবে আমি বাইসেক্টকে দরকারী বলে মনে করেছি ।
পাইপিতে এমন অনেকগুলি বাস্তবায়ন রয়েছে যা আপনি ব্রাউজ করতে পারেন।
যদি আমি সঠিকভাবে মনে রাখি, পাইথন স্ট্যান্ডার্ড লাইব .NET বেস ক্লাস লাইব্রেরি না করায় একই কারণে ট্রি ডেটা স্ট্রাকচারকে অন্তর্ভুক্ত করে না: মেমরির লোকালটি হ্রাস করা হয়, ফলে আরও ক্যাশে মিস হয় না। আধুনিক প্রসেসরগুলিতে ক্যাশে মেমরির একটি বৃহত অংশ আনার জন্য এটি সাধারণত দ্রুত হয় এবং "পয়েন্টার সমৃদ্ধ" ডেটা স্ট্রাকচারগুলি সুবিধাটিকে উপেক্ষা করে।
আমি একটি অভিধান হিসাবে একটি মূলী গাছ বাস্তবায়িত {child:parent}
। সুতরাং রুট নোডের সাথে উদাহরণস্বরূপ 0
, একটি গাছ এর মতো দেখতে পাওয়া যাবে:
tree={1:0, 2:0, 3:1, 4:2, 5:3}
এই কাঠামোটি যে কোনও নোড থেকে মূলের দিকে যাওয়ার পথ ধরে toর্ধ্বমুখী হওয়া বেশ সহজ করে দিয়েছিল, যা আমি কাজ করে যাচ্ছিলাম সমস্যার জন্য প্রাসঙ্গিক।
{parent:[leftchild,rightchild]}
।
গ্রেগ হিউগিলের উত্তর দুর্দান্ত তবে আপনার যদি প্রতিটি স্তরের অধিক নোডের প্রয়োজন হয় তবে সেগুলি তৈরি করতে আপনি একটি তালিকা | অভিধান ব্যবহার করতে পারেন: এবং তারপরে নাম বা আদেশের মাধ্যমে এগুলি অ্যাক্সেসের জন্য পদ্ধতিটি ব্যবহার করুন (আইডির মতো)
class node(object):
def __init__(self):
self.name=None
self.node=[]
self.otherInfo = None
self.prev=None
def nex(self,child):
"Gets a node by number"
return self.node[child]
def prev(self):
return self.prev
def goto(self,data):
"Gets the node by name"
for child in range(0,len(self.node)):
if(self.node[child].name==data):
return self.node[child]
def add(self):
node1=node()
self.node.append(node1)
node1.prev=self
return node1
এখন কেবল একটি মূল তৈরি করুন এবং এটি তৈরি করুন: প্রাক্তন:
tree=node() #create a node
tree.name="root" #name it root
tree.otherInfo="blue" #or what ever
tree=tree.add() #add a node to the root
tree.name="node1" #name it
root
/
child1
tree=tree.add()
tree.name="grandchild1"
root
/
child1
/
grandchild1
tree=tree.prev()
tree=tree.add()
tree.name="gchild2"
root
/
child1
/ \
grandchild1 gchild2
tree=tree.prev()
tree=tree.prev()
tree=tree.add()
tree=tree.name="child2"
root
/ \
child1 child2
/ \
grandchild1 gchild2
tree=tree.prev()
tree=tree.goto("child1") or tree=tree.nex(0)
tree.name="changed"
root
/ \
changed child2
/ \
grandchild1 gchild2
এই কাজটি কীভাবে করা যায় তা নির্ধারণ করা আপনার পক্ষে যথেষ্ট হবে be
class Tree(dict):
"""A tree implementation using python's autovivification feature."""
def __missing__(self, key):
value = self[key] = type(self)()
return value
#cast a (nested) dict to a (nested) Tree class
def __init__(self, data={}):
for k, data in data.items():
if isinstance(data, dict):
self[k] = type(self)(data)
else:
self[k] = data
অভিধান হিসাবে কাজ করে, তবে যতটা নেস্টেড ডিক্টস আপনি চান তা সরবরাহ করে। নিম্নলিখিত চেষ্টা করুন:
your_tree = Tree()
your_tree['a']['1']['x'] = '@'
your_tree['a']['1']['y'] = '#'
your_tree['a']['2']['x'] = '$'
your_tree['a']['3'] = '%'
your_tree['b'] = '*'
একটি নেস্টেড ডিক্স প্রদান করবে ... যা আসলে গাছ হিসাবে কাজ করে।
{'a': {'1': {'x': '@', 'y': '#'}, '2': {'x': '$'}, '3': '%'}, 'b': '*'}
... আপনার যদি ইতিমধ্যে ডিক থাকে তবে এটি প্রতিটি স্তরে একটি গাছে ফেলে দেবে:
d = {'foo': {'amy': {'what': 'runs'} } }
tree = Tree(d)
print(d['foo']['amy']['what']) # returns 'runs'
d['foo']['amy']['when'] = 'now' # add new branch
এইভাবে, আপনি প্রতিটি ইচ্ছে মতো স্তর সম্পাদনা / যুক্ত / মুছে ফেলতে পারেন। ট্র্যাভারসাল ইত্যাদির জন্য সমস্ত ডিক পদ্ধতিগুলি এখনও প্রয়োগ হয়।
dict
পরিবর্তে আপনি প্রসারিত করার জন্য কেন কোনও কারণ আছে defaultdict
? আমার পরীক্ষাগুলি থেকে defaultdict
ডিকের পরিবর্তে প্রসারিত করা এবং তারপরে আর ডি self.default_factory = type(self)
শীর্ষে যুক্ত করা একইভাবে কাজ করা উচিত।
আমি নেস্টেড ডিক্টস ব্যবহার করে গাছ প্রয়োগ করেছি। এটি করা বেশ সহজ এবং এটি আমার জন্য বেশ বড় ডেটা সেট সহ কাজ করেছে। আমি নীচে একটি নমুনা পোস্ট করেছি এবং আপনি গুগল কোডে আরও দেখতে পারেন
def addBallotToTree(self, tree, ballotIndex, ballot=""):
"""Add one ballot to the tree.
The root of the tree is a dictionary that has as keys the indicies of all
continuing and winning candidates. For each candidate, the value is also
a dictionary, and the keys of that dictionary include "n" and "bi".
tree[c]["n"] is the number of ballots that rank candidate c first.
tree[c]["bi"] is a list of ballot indices where the ballots rank c first.
If candidate c is a winning candidate, then that portion of the tree is
expanded to indicate the breakdown of the subsequently ranked candidates.
In this situation, additional keys are added to the tree[c] dictionary
corresponding to subsequently ranked candidates.
tree[c]["n"] is the number of ballots that rank candidate c first.
tree[c]["bi"] is a list of ballot indices where the ballots rank c first.
tree[c][d]["n"] is the number of ballots that rank c first and d second.
tree[c][d]["bi"] is a list of the corresponding ballot indices.
Where the second ranked candidates is also a winner, then the tree is
expanded to the next level.
Losing candidates are ignored and treated as if they do not appear on the
ballots. For example, tree[c][d]["n"] is the total number of ballots
where candidate c is the first non-losing candidate, c is a winner, and
d is the next non-losing candidate. This will include the following
ballots, where x represents a losing candidate:
[c d]
[x c d]
[c x d]
[x c x x d]
During the count, the tree is dynamically updated as candidates change
their status. The parameter "tree" to this method may be the root of the
tree or may be a sub-tree.
"""
if ballot == "":
# Add the complete ballot to the tree
weight, ballot = self.b.getWeightedBallot(ballotIndex)
else:
# When ballot is not "", we are adding a truncated ballot to the tree,
# because a higher-ranked candidate is a winner.
weight = self.b.getWeight(ballotIndex)
# Get the top choice among candidates still in the running
# Note that we can't use Ballots.getTopChoiceFromWeightedBallot since
# we are looking for the top choice over a truncated ballot.
for c in ballot:
if c in self.continuing | self.winners:
break # c is the top choice so stop
else:
c = None # no candidates left on this ballot
if c is None:
# This will happen if the ballot contains only winning and losing
# candidates. The ballot index will not need to be transferred
# again so it can be thrown away.
return
# Create space if necessary.
if not tree.has_key(c):
tree[c] = {}
tree[c]["n"] = 0
tree[c]["bi"] = []
tree[c]["n"] += weight
if c in self.winners:
# Because candidate is a winner, a portion of the ballot goes to
# the next candidate. Pass on a truncated ballot so that the same
# candidate doesn't get counted twice.
i = ballot.index(c)
ballot2 = ballot[i+1:]
self.addBallotToTree(tree[c], ballotIndex, ballot2)
else:
# Candidate is in continuing so we stop here.
tree[c]["bi"].append(ballotIndex)
আমি আমার সাইটে একটি পাইথন [3] ট্রি বাস্তবায়ন প্রকাশ করেছি: http://www.quesucede.com/page/show/id/python_3_tree_implementation ।
আশা করি এটি কার্যকর হবে,
ঠিক আছে, এখানে কোড:
import uuid
def sanitize_id(id):
return id.strip().replace(" ", "")
(_ADD, _DELETE, _INSERT) = range(3)
(_ROOT, _DEPTH, _WIDTH) = range(3)
class Node:
def __init__(self, name, identifier=None, expanded=True):
self.__identifier = (str(uuid.uuid1()) if identifier is None else
sanitize_id(str(identifier)))
self.name = name
self.expanded = expanded
self.__bpointer = None
self.__fpointer = []
@property
def identifier(self):
return self.__identifier
@property
def bpointer(self):
return self.__bpointer
@bpointer.setter
def bpointer(self, value):
if value is not None:
self.__bpointer = sanitize_id(value)
@property
def fpointer(self):
return self.__fpointer
def update_fpointer(self, identifier, mode=_ADD):
if mode is _ADD:
self.__fpointer.append(sanitize_id(identifier))
elif mode is _DELETE:
self.__fpointer.remove(sanitize_id(identifier))
elif mode is _INSERT:
self.__fpointer = [sanitize_id(identifier)]
class Tree:
def __init__(self):
self.nodes = []
def get_index(self, position):
for index, node in enumerate(self.nodes):
if node.identifier == position:
break
return index
def create_node(self, name, identifier=None, parent=None):
node = Node(name, identifier)
self.nodes.append(node)
self.__update_fpointer(parent, node.identifier, _ADD)
node.bpointer = parent
return node
def show(self, position, level=_ROOT):
queue = self[position].fpointer
if level == _ROOT:
print("{0} [{1}]".format(self[position].name,
self[position].identifier))
else:
print("\t"*level, "{0} [{1}]".format(self[position].name,
self[position].identifier))
if self[position].expanded:
level += 1
for element in queue:
self.show(element, level) # recursive call
def expand_tree(self, position, mode=_DEPTH):
# Python generator. Loosly based on an algorithm from 'Essential LISP' by
# John R. Anderson, Albert T. Corbett, and Brian J. Reiser, page 239-241
yield position
queue = self[position].fpointer
while queue:
yield queue[0]
expansion = self[queue[0]].fpointer
if mode is _DEPTH:
queue = expansion + queue[1:] # depth-first
elif mode is _WIDTH:
queue = queue[1:] + expansion # width-first
def is_branch(self, position):
return self[position].fpointer
def __update_fpointer(self, position, identifier, mode):
if position is None:
return
else:
self[position].update_fpointer(identifier, mode)
def __update_bpointer(self, position, identifier):
self[position].bpointer = identifier
def __getitem__(self, key):
return self.nodes[self.get_index(key)]
def __setitem__(self, key, item):
self.nodes[self.get_index(key)] = item
def __len__(self):
return len(self.nodes)
def __contains__(self, identifier):
return [node.identifier for node in self.nodes
if node.identifier is identifier]
if __name__ == "__main__":
tree = Tree()
tree.create_node("Harry", "harry") # root node
tree.create_node("Jane", "jane", parent = "harry")
tree.create_node("Bill", "bill", parent = "harry")
tree.create_node("Joe", "joe", parent = "jane")
tree.create_node("Diane", "diane", parent = "jane")
tree.create_node("George", "george", parent = "diane")
tree.create_node("Mary", "mary", parent = "diane")
tree.create_node("Jill", "jill", parent = "george")
tree.create_node("Carol", "carol", parent = "jill")
tree.create_node("Grace", "grace", parent = "bill")
tree.create_node("Mark", "mark", parent = "jane")
print("="*80)
tree.show("harry")
print("="*80)
for node in tree.expand_tree("harry", mode=_WIDTH):
print(node)
print("="*80)
কারও যদি এটি করার সহজতর উপায়ের প্রয়োজন হয় তবে একটি গাছ কেবল পুনরাবৃত্তভাবে নেস্টেড তালিকা হয় (যেহেতু সেটটি হ্যাশযোগ্য নয়):
[root, [child_1, [[child_11, []], [child_12, []]], [child_2, []]]]
যেখানে প্রতিটি শাখা একটি জোড়া: [ object, [children] ]
এবং প্রতিটি পাতার একটি জোড়া:[ object, [] ]
তবে আপনার যদি পদ্ধতিগুলি সহ কোনও শ্রেণীর প্রয়োজন হয় তবে আপনি যে কোনও জায়গায় ব্যবহার করতে পারেন।
আপনার কোন অপারেশন দরকার? পাইথনে প্রায়শই ডিক বা বাইসেক্ট মডিউল সহ একটি তালিকা ব্যবহার করে একটি ভাল সমাধান পাওয়া যায়।
পিপিআইতে প্রচুর, অনেক গাছ বাস্তবায়ন রয়েছে এবং খাঁটি পাইথনটিতে নিজেকে প্রয়োগ করার জন্য অনেক গাছের ধরণের প্রায় তুচ্ছ। তবে এটি খুব কমই প্রয়োজন।
ব্রুনোর জবাবের ভিত্তিতে আলগাভাবে আরও একটি গাছ প্রয়োগ :
class Node:
def __init__(self):
self.name: str = ''
self.children: List[Node] = []
self.parent: Node = self
def __getitem__(self, i: int) -> 'Node':
return self.children[i]
def add_child(self):
child = Node()
self.children.append(child)
child.parent = self
return child
def __str__(self) -> str:
def _get_character(x, left, right) -> str:
if x < left:
return '/'
elif x >= right:
return '\\'
else:
return '|'
if len(self.children):
children_lines: Sequence[List[str]] = list(map(lambda child: str(child).split('\n'), self.children))
widths: Sequence[int] = list(map(lambda child_lines: len(child_lines[0]), children_lines))
max_height: int = max(map(len, children_lines))
total_width: int = sum(widths) + len(widths) - 1
left: int = (total_width - len(self.name) + 1) // 2
right: int = left + len(self.name)
return '\n'.join((
self.name.center(total_width),
' '.join(map(lambda width, position: _get_character(position - width // 2, left, right).center(width),
widths, accumulate(widths, add))),
*map(
lambda row: ' '.join(map(
lambda child_lines: child_lines[row] if row < len(child_lines) else ' ' * len(child_lines[0]),
children_lines)),
range(max_height))))
else:
return self.name
এবং এটি কীভাবে ব্যবহার করবেন তার একটি উদাহরণ:
tree = Node()
tree.name = 'Root node'
tree.add_child()
tree[0].name = 'Child node 0'
tree.add_child()
tree[1].name = 'Child node 1'
tree.add_child()
tree[2].name = 'Child node 2'
tree[1].add_child()
tree[1][0].name = 'Grandchild 1.0'
tree[2].add_child()
tree[2][0].name = 'Grandchild 2.0'
tree[2].add_child()
tree[2][1].name = 'Grandchild 2.1'
print(tree)
যা আউটপুট করা উচিত:
রুট নোড / / \ চাইল্ড নোড 0 চাইল্ড নোড 1 চাইল্ড নোড 2 | / গ্র্যান্ডচাইল্ড 1.0 গ্র্যান্ডচাইল্ড 2.0 গ্র্যান্ডচাইল্ড ২.১
আমি নেটওয়ার্কএক্স লাইব্রেরির পরামর্শ দিই ।
নেটওয়ার্কএক্স জটিল নেটওয়ার্কগুলির গঠন, গতিবিদ্যা এবং ফাংশনগুলির গবেষণা, কারসাজি এবং অধ্যয়নের জন্য পাইথন প্যাকেজ।
গাছ তৈরির উদাহরণ:
import networkx as nx
G = nx.Graph()
G.add_edge('A', 'B')
G.add_edge('B', 'C')
G.add_edge('B', 'D')
G.add_edge('A', 'E')
G.add_edge('E', 'F')
" জেনারেল ট্রি" বলতে আপনার অর্থ কী তা আমি নিশ্চিত নই ,
তবে পাঠাগারটি প্রতিটি নোডকে যে কোনও হ্যাশযোগ্য বস্তু হিসাবে সক্ষম করে এবং প্রতিটি নোডের বাচ্চার সংখ্যার কোনও বাধা নেই।
গ্রন্থাগারটি গাছ এবং দৃশ্য ধারণার সাথে সম্পর্কিত গ্রাফ অ্যালগরিদমও সরবরাহ করে।
আপনি যদি কোনও ট্রি ডেটা কাঠামো তৈরি করতে চান তবে প্রথমে আপনাকে ট্রি-এলিমেন্ট অবজেক্ট তৈরি করতে হবে। আপনি যদি ট্রি ট্রিটমেন্ট অবজেক্ট তৈরি করেন তবে আপনার গাছটি কী আচরণ করে তা আপনি সিদ্ধান্ত নিতে পারেন।
এটি করার জন্য ট্রি ট্রিটমেন্ট ক্লাসটি রয়েছে:
class TreeElement (object):
def __init__(self):
self.elementName = None
self.element = []
self.previous = None
self.elementScore = None
self.elementParent = None
self.elementPath = []
self.treeLevel = 0
def goto(self, data):
for child in range(0, len(self.element)):
if (self.element[child].elementName == data):
return self.element[child]
def add(self):
single_element = TreeElement()
single_element.elementName = self.elementName
single_element.previous = self.elementParent
single_element.elementScore = self.elementScore
single_element.elementPath = self.elementPath
single_element.treeLevel = self.treeLevel
self.element.append(single_element)
return single_element
এখন, গাছ তৈরি করতে আমাদের এই উপাদানটি ব্যবহার করতে হবে, আমি উদাহরণ হিসাবে এ * ট্রি ব্যবহার করছি।
class AStarAgent(Agent):
# Initialization Function: Called one time when the game starts
def registerInitialState(self, state):
return;
# GetAction Function: Called with every frame
def getAction(self, state):
# Sorting function for the queue
def sortByHeuristic(each_element):
if each_element.elementScore:
individual_score = each_element.elementScore[0][0] + each_element.treeLevel
else:
individual_score = admissibleHeuristic(each_element)
return individual_score
# check the game is over or not
if state.isWin():
print('Job is done')
return Directions.STOP
elif state.isLose():
print('you lost')
return Directions.STOP
# Create empty list for the next states
astar_queue = []
astar_leaf_queue = []
astar_tree_level = 0
parent_tree_level = 0
# Create Tree from the give node element
astar_tree = TreeElement()
astar_tree.elementName = state
astar_tree.treeLevel = astar_tree_level
astar_tree = astar_tree.add()
# Add first element into the queue
astar_queue.append(astar_tree)
# Traverse all the elements of the queue
while astar_queue:
# Sort the element from the queue
if len(astar_queue) > 1:
astar_queue.sort(key=lambda x: sortByHeuristic(x))
# Get the first node from the queue
astar_child_object = astar_queue.pop(0)
astar_child_state = astar_child_object.elementName
# get all legal actions for the current node
current_actions = astar_child_state.getLegalPacmanActions()
if current_actions:
# get all the successor state for these actions
for action in current_actions:
# Get the successor of the current node
next_state = astar_child_state.generatePacmanSuccessor(action)
if next_state:
# evaluate the successor states using scoreEvaluation heuristic
element_scored = [(admissibleHeuristic(next_state), action)]
# Increase the level for the child
parent_tree_level = astar_tree.goto(astar_child_state)
if parent_tree_level:
astar_tree_level = parent_tree_level.treeLevel + 1
else:
astar_tree_level += 1
# create tree for the finding the data
astar_tree.elementName = next_state
astar_tree.elementParent = astar_child_state
astar_tree.elementScore = element_scored
astar_tree.elementPath.append(astar_child_state)
astar_tree.treeLevel = astar_tree_level
astar_object = astar_tree.add()
# If the state exists then add that to the queue
astar_queue.append(astar_object)
else:
# Update the value leaf into the queue
astar_leaf_state = astar_tree.goto(astar_child_state)
astar_leaf_queue.append(astar_leaf_state)
আপনি অবজেক্ট থেকে যে কোনও উপাদান যুক্ত / সরিয়ে ফেলতে পারেন, তবে কাঠামোটিকে আন্তঃসংযোগ তৈরি করতে পারেন।
def iterative_bfs(graph, start):
'''iterative breadth first search from start'''
bfs_tree = {start: {"parents":[], "children":[], "level":0}}
q = [start]
while q:
current = q.pop(0)
for v in graph[current]:
if not v in bfs_tree:
bfs_tree[v]={"parents":[current], "children":[], "level": bfs_tree[current]["level"] + 1}
bfs_tree[current]["children"].append(v)
q.append(v)
else:
if bfs_tree[v]["level"] > bfs_tree[current]["level"]:
bfs_tree[current]["children"].append(v)
bfs_tree[v]["parents"].append(current)