RFID Tree Algorithm 樹演算法for RFID Tag Anti-Collision
import tkinter as tk
from tkinter import simpledialog
class RFIDTreeApp:
def __init__(self, master):
self.master = master
master.title("RFID Tree Algorithm Visualizer")
# --- Configuration ---
self.canvas_width = 800
self.canvas_height = 600
self.node_radius = 8
self.highlight_color = "red"
self.normal_color = "blue"
self.tag_size = 4 # The depth of the tree (4-bit tags)
# Structure to hold node coordinates and IDs
self.nodes = {}
self.lines = {}
self.labels = {}
self.tag_boxes = {}
self.tag_text_items = {}
# --- UI Elements ---
self.canvas = tk.Canvas(master, width=self.canvas_width, height=self.canvas_height, bg="lightyellow")
self.canvas.pack()
self.input_frame = tk.Frame(master)
self.input_frame.pack(pady=10)
self.input_label = tk.Label(self.input_frame, text="Enter 4-bit Tag (e.g., 0101):")
self.input_label.pack(side=tk.LEFT, padx=5)
self.tag_entry = tk.Entry(self.input_frame, width=10)
self.tag_entry.pack(side=tk.LEFT, padx=5)
self.tag_entry.insert(0, "0101") # Default value
self.draw_button = tk.Button(self.input_frame, text="Show Path", command=self.highlight_path)
self.draw_button.pack(side=tk.LEFT, padx=5)
self.clear_button = tk.Button(self.input_frame, text="Clear Path", command=self.clear_highlight)
self.clear_button.pack(side=tk.LEFT, padx=5)
# --- Initial Drawing ---
self.draw_tree()
def draw_tree(self):
"""Draws the complete 4-bit binary tree structure."""
self.canvas.delete("all")
self.nodes.clear()
self.lines.clear()
self.labels.clear()
self.tag_boxes.clear()
self.tag_text_items.clear()
# Coordinates for the root node
root_x = self.canvas_width / 2
root_y = 50
# Recursively draw the tree
self._recursive_draw(root_x, root_y, 0, self.canvas_width / 4, "")
# Draw the title
self.canvas.create_text(
self.canvas_width / 2, 20,
text="RFID Tree Algorithm",
font=("Times New Roman", 20, "bold"),
fill="darkblue"
)
self.canvas.create_line(100, 35, self.canvas_width - 100, 35, fill="red", width=2)
def _recursive_draw(self, x, y, depth, x_offset, current_path):
"""
Recursively draws nodes, edges, and labels.
Args:
x (float): X-coordinate of the current node.
y (float): Y-coordinate of the current node.
depth (int): Current depth in the tree (0 is root).
x_offset (float): Horizontal space for child nodes.
current_path (str): Binary string path to the current node.
"""
node_id = current_path
# 1. Draw the current node (Yellow circle)
node_obj = self.canvas.create_oval(
x - self.node_radius, y - self.node_radius,
x + self.node_radius, y + self.node_radius,
fill="yellow", outline=self.normal_color
)
self.nodes[node_id] = node_obj
if depth < self.tag_size:
# Calculate child coordinates
y_child = y + 80
x_left = x - x_offset
x_right = x + x_offset
# 2. Draw Left Child (Bit 0)
# Draw Line
line_left = self.canvas.create_line(x, y + self.node_radius, x_left, y_child - self.node_radius, fill=self.normal_color, width=2)
self.lines[node_id + "0"] = line_left
# Draw Label (Box)
label_x = x - x_offset / 2
label_y = y + 30
rect_left = self.canvas.create_rectangle(label_x - 15, label_y - 15, label_x + 15, label_y + 15, outline=self.normal_color, fill="white")
text_left = self.canvas.create_text(label_x, label_y, text="0", fill="black", font=("Arial", 10))
self.labels[node_id + "0_rect"] = rect_left
self.labels[node_id + "0_text"] = text_left
# Recurse
self._recursive_draw(x_left, y_child, depth + 1, x_offset / 2, current_path + "0")
# 3. Draw Right Child (Bit 1)
# Draw Line
line_right = self.canvas.create_line(x, y + self.node_radius, x_right, y_child - self.node_radius, fill=self.normal_color, width=2)
self.lines[node_id + "1"] = line_right
# Draw Label (Box)
label_x = x + x_offset / 2
label_y = y + 30
rect_right = self.canvas.create_rectangle(label_x - 15, label_y - 15, label_x + 15, label_y + 15, outline=self.normal_color, fill="white")
text_right = self.canvas.create_text(label_x, label_y, text="1", fill="black", font=("Arial", 10))
self.labels[node_id + "1_rect"] = rect_right
self.labels[node_id + "1_text"] = text_right
# Recurse
self._recursive_draw(x_right, y_child, depth + 1, x_offset / 2, current_path + "1")
else:
# 4. Draw the RFID tag box at the leaf level
tag_y = y + 60
box_width = 45
box_height = 20
tag_box = self.canvas.create_rectangle(
x - box_width, tag_y - box_height,
x + box_width, tag_y + box_height,
outline="black", fill="white"
)
tag_text = self.canvas.create_text(x, tag_y, text=current_path, fill="black", font=("Arial", 12, "bold"))
self.tag_boxes[node_id] = tag_box
self.tag_text_items[node_id] = tag_text
def clear_highlight(self):
"""Resets all colors to the default 'blue'."""
# Reset nodes (circles)
for node_id, item_id in self.nodes.items():
self.canvas.itemconfig(item_id, outline=self.normal_color)
# Reset lines (edges)
for line_id, item_id in self.lines.items():
self.canvas.itemconfig(item_id, fill=self.normal_color)
# Reset labels (0/1 boxes and text) - Boxes only
for label_id, item_id in self.labels.items():
if label_id.endswith("_rect"):
self.canvas.itemconfig(item_id, outline=self.normal_color)
elif label_id.endswith("_text"):
self.canvas.itemconfig(item_id, fill="black")
# Reset tag boxes
for tag_id, item_id in self.tag_boxes.items():
self.canvas.itemconfig(item_id, outline="black")
def highlight_path(self):
"""Highlights the path in the tree corresponding to the entered tag."""
self.clear_highlight() # Start by resetting
tag_value = self.tag_entry.get().strip()
# --- Input Validation ---
if not tag_value or len(tag_value) != self.tag_size or not all(c in '01' for c in tag_value):
tk.messagebox.showerror("Invalid Input", f"Please enter a valid {self.tag_size}-bit binary value (e.g., 0101).")
return
current_path = ""
# Highlight the root node
if "" in self.nodes:
self.canvas.itemconfig(self.nodes[""], outline=self.highlight_color, width=3)
# Iterate through each bit of the tag
for i, bit in enumerate(tag_value):
prev_path = current_path
current_path += bit
# Highlight the line (edge)
line_key = current_path
if line_key in self.lines:
self.canvas.itemconfig(self.lines[line_key], fill=self.highlight_color, width=3)
# Highlight the label (0/1 box)
rect_key = line_key + "_rect"
text_key = line_key + "_text"
if rect_key in self.labels:
self.canvas.itemconfig(self.labels[rect_key], outline=self.highlight_color, width=2)
if text_key in self.labels:
self.canvas.itemconfig(self.labels[text_key], fill=self.highlight_color)
# Highlight the node (circle)
if current_path in self.nodes:
self.canvas.itemconfig(self.nodes[current_path], outline=self.highlight_color, width=3)
# Highlight the final RFID tag box
if current_path in self.tag_boxes:
self.canvas.itemconfig(self.tag_boxes[current_path], outline=self.highlight_color, width=3)
self.canvas.itemconfig(self.tag_text_items[current_path], fill=self.highlight_color)
# --- Run the application ---
if __name__ == "__main__":
root = tk.Tk()
app = RFIDTreeApp(root)
root.mainloop()

沒有留言:
張貼留言