أمثلة أكواد الذكاء الاصطناعي والروبوتات
مرحباً بك في مكتبة الأكواد من كتاب “رحلة الذكاء الاصطناعي والروبوتات: من الأساسيات إلى الآفاق المستقبلية”! ستجد هنا أمثلة عملية بلغة بايثون وجافا للخوارزميات الأساسية، مفاهيم التعلم الآلي، والتحكم الأساسي بالروبوتات.
الفصل 10: الخوارزميات الأساسية
1. هياكل البيانات الأساسية: القوائم/المصفوفات والقواميس/الخرائط
أمثلة بايثون:
# Python List
my_python_list = [10, "hello", 3.14]
print(my_python_list[1])
# Python Dictionary
my_python_dict = {"name": "R2-D2", "type": "Astromech Droid"}
print(my_python_dict["name"])
hello
R2-D2
أمثلة جافا:
// Java Array
// Note: Arrays in Java have a fixed size and usually a single data type
// To run this, you'd typically put it inside a main method in a class.
/*
public class DataStructuresDemo {
public static void main(String[] args) {
int[] my_java_array = new int[3];
my_java_array[0] = 10;
my_java_array[1] = 20; // Example assignment
my_java_array[2] = 30; // Example assignment
System.out.println(my_java_array[0]);
}
}
*/
// Java ArrayList (flexible list)
import java.util.ArrayList;
/*
public class DataStructuresDemo {
public static void main(String[] args) {
ArrayList<String> my_java_list = new ArrayList<>();
my_java_list.add("hello");
my_java_list.add("world"); // Example assignment
System.out.println(my_java_list.get(0));
}
}
*/
// Java HashMap
import java.util.HashMap;
/*
public class DataStructuresDemo {
public static void main(String[] args) {
HashMap<String, String> my_java_map = new HashMap<>();
my_java_map.put("name", "R2-D2");
my_java_map.put("type", "Astromech Droid");
System.out.println(my_java_map.get("name"));
}
}
*/
hello
R2-D2
*ملاحظة: أمثلة جافا لهياكل البيانات الأساسية مقدمة كمقتطفات توضع عادةً داخل دالة `main` في صنف لتنفيذها.*
2. خوارزميات البحث
أ. البحث الخطي (Linear Search)
كود بايثون:
def linear_search_python(data_list, target):
"""
Searches for 'target' in 'data_list' using linear search.
Returns the index if found, otherwise returns -1.
"""
for i in range(len(data_list)):
if data_list[i] == target:
return i # Element found, return index
return -1 # Element not found
# Test
my_list = [4, 2, 7, 1, 9, 5]
target_item = 7
index = linear_search_python(my_list, target_item)
if index != -1:
print(f"The item {target_item} is found at index {index}")
else:
print(f"The item {target_item} is not in the list")
target_item_not_found = 10
index_not_found = linear_search_python(my_list, target_item_not_found)
if index_not_found != -1:
print(f"The item {target_item_not_found} is found at index {index_not_found}")
else:
print(f"The item {target_item_not_found} is not in the list")
The item 7 is found at index 2
The item 10 is not in the list
كود جافا:
public class LinearSearchJava {
public static int linearSearch(int[] dataArray, int target) {
/**
* Searches for 'target' in 'dataArray' using linear search.
* Returns the index if found, otherwise returns -1.
*/
for (int i = 0; i < dataArray.length; i++) {
if (dataArray[i] == target) {
return i; // Element found, return index
}
}
return -1; // Element not found
}
public static void main(String[] args) {
int[] myArray = {4, 2, 7, 1, 9, 5};
int targetItem = 7;
int index = linearSearch(myArray, targetItem);
if (index != -1) {
System.out.println("The item " + targetItem + " is found at index " + index);
} else {
System.out.println("The item " + targetItem + " is not in the array");
}
int targetItemNotFound = 10;
int indexNotFound = linearSearch(myArray, targetItemNotFound);
if (indexNotFound != -1) {
System.out.println("The item " + targetItemNotFound + " is found at index " + indexNotFound);
} else {
System.out.println("The item " + targetItemNotFound + " is not in the array");
}
}
}
The item 7 is found at index 2
The item 10 is not in the array
ب. البحث الثنائي (Binary Search)
كود بايثون:
def binary_search_python(sorted_data_list, target):
"""
Searches for 'target' in a sorted list 'sorted_data_list' using binary search.
Returns the index if found, otherwise returns -1.
"""
low = 0
high = len(sorted_data_list) - 1
while low <= high:
mid = (low + high) // 2 # Integer division
guess = sorted_data_list[mid]
if guess == target:
return mid
if guess > target: # Guess is too high
high = mid - 1
else: # Guess is too low
low = mid + 1
return -1
# Test
my_sorted_list = [1, 2, 4, 5, 7, 9, 12] # List must be sorted!
target_item = 7
index = binary_search_python(my_sorted_list, target_item)
if index != -1:
print(f"The item {target_item} is found at index {index} (binary search)")
else:
print(f"The item {target_item} is not in the list (binary search)")
target_item_not_found = 3
index_not_found = binary_search_python(my_sorted_list, target_item_not_found)
if index_not_found != -1:
print(f"The item {target_item_not_found} is found at index {index_not_found} (binary search)")
else:
print(f"The item {target_item_not_found} is not in the list (binary search)")
The item 7 is found at index 4 (binary search)
The item 3 is not in the list (binary search)
كود جافا:
import java.util.Arrays; // To use built-in sort for testing
public class BinarySearchJava {
public static int binarySearch(int[] sortedDataArray, int target) {
/**
* Searches for 'target' in a sorted array 'sortedDataArray' using binary search.
* Returns the index if found, otherwise returns -1.
*/
int low = 0;
int high = sortedDataArray.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2; // To avoid overflow when summing large numbers
int guess = sortedDataArray[mid];
if (guess == target) {
return mid;
}
if (guess > target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
public static void main(String[] args) {
int[] myArray = {12, 2, 9, 5, 1, 7, 4};
Arrays.sort(myArray); // Array must be sorted! [1, 2, 4, 5, 7, 9, 12]
System.out.println("Sorted Array: " + Arrays.toString(myArray));
int targetItem = 7;
int index = binarySearch(myArray, targetItem);
if (index != -1) {
System.out.println("The item " + targetItem + " is found at index " + index + " (binary search)");
} else {
System.out.println("The item " + targetItem + " is not in the array (binary search)");
}
int targetItemNotFound = 3;
int indexNotFound = binarySearch(myArray, targetItemNotFound);
if (indexNotFound != -1) {
System.out.println("The item " + targetItemNotFound + " is found at index " + indexNotFound + " (binary search)");
} else {
System.out.println("The item " + targetItemNotFound + " is not in the array (binary search)");
}
}
}
Sorted Array: [1, 2, 4, 5, 7, 9, 12]
The item 7 is found at index 4 (binary search)
The item 3 is not in the array (binary search)
3. خوارزميات الترتيب
أ. ترتيب الفقاعة (Bubble Sort)
كود بايثون:
def bubble_sort_python(data_list):
"""
Sorts 'data_list' in ascending order using Bubble Sort.
"""
n = len(data_list)
for i in range(n - 1):
swapped = False
for j in range(0, n - i - 1):
if data_list[j] > data_list[j + 1]:
# Swap elements
data_list[j], data_list[j + 1] = data_list[j + 1], data_list[j]
swapped = True
if not swapped: # If no two elements were swapped by inner loop, then list is sorted
break
return data_list
# Test
my_list_to_sort = [64, 34, 25, 12, 22, 11, 90]
print(f"Original list: {my_list_to_sort}")
sorted_list = bubble_sort_python(my_list_to_sort.copy()) # Pass a copy to avoid modifying original directly
print(f"Sorted list (Bubble Sort): {sorted_list}")
Original list: [64, 34, 25, 12, 22, 11, 90]
Sorted list (Bubble Sort): [11, 12, 22, 25, 34, 64, 90]
كود جافا:
import java.util.Arrays;
public class BubbleSortJava {
public static void bubbleSort(int[] dataArray) {
/**
* Sorts 'dataArray' in ascending order using Bubble Sort.
*/
int n = dataArray.length;
boolean swapped;
for (int i = 0; i < n - 1; i++) {
swapped = false;
for (int j = 0; j < n - i - 1; j++) {
if (dataArray[j] > dataArray[j + 1]) {
// Swap elements
int temp = dataArray[j];
dataArray[j] = dataArray[j + 1];
dataArray[j + 1] = temp;
swapped = true;
}
}
if (!swapped) { // If no two elements were swapped by inner loop, then array is sorted
break;
}
}
}
public static void main(String[] args) {
int[] myArrayToSort = {64, 34, 25, 12, 22, 11, 90};
System.out.println("Original array: " + Arrays.toString(myArrayToSort));
bubbleSort(myArrayToSort); // Sorts the original array directly
System.out.println("Sorted array (Bubble Sort): " + Arrays.toString(myArrayToSort));
}
}
Original array: [64, 34, 25, 12, 22, 11, 90]
Sorted array (Bubble Sort): [11, 12, 22, 25, 34, 64, 90]
ب. ترتيب التحديد (Selection Sort)
كود بايثون:
def selection_sort_python(data_list):
"""
Sorts 'data_list' in ascending order using Selection Sort.
"""
n = len(data_list)
for i in range(n):
min_idx = i # Assume the current element is the smallest
for j in range(i + 1, n):
if data_list[j] < data_list[min_idx]:
min_idx = j # Found a smaller element, update index
# Swap the current element with the smallest element found in the unsorted part
data_list[i], data_list[min_idx] = data_list[min_idx], data_list[i]
return data_list
# Test
my_list_to_sort_selection = [64, 25, 12, 22, 11]
print(f"Original list (Selection Sort): {my_list_to_sort_selection}")
sorted_list_selection = selection_sort_python(my_list_to_sort_selection.copy())
print(f"Sorted list (Selection Sort): {sorted_list_selection}")
Original list (Selection Sort): [64, 25, 12, 22, 11]
Sorted list (Selection Sort): [11, 12, 22, 25, 64]
كود جافا:
import java.util.Arrays;
public class SelectionSortJava {
public static void selectionSort(int[] dataArray) {
/**
* Sorts 'dataArray' in ascending order using Selection Sort.
*/
int n = dataArray.length;
for (int i = 0; i < n - 1; i++) {
int min_idx = i; // Assume the current element is the smallest
for (int j = i + 1; j < n; j++) {
if (dataArray[j] < dataArray[min_idx]) {
min_idx = j; // Found a smaller element, update index
}
}
// Swap the current element with the smallest element found in the unsorted part
int temp = dataArray[min_idx];
dataArray[min_idx] = dataArray[i];
dataArray[i] = temp;
}
}
public static void main(String[] args) {
int[] myArrayToSortSelection = {64, 25, 12, 22, 11};
System.out.println("Original array (Selection Sort): " + Arrays.toString(myArrayToSortSelection));
selectionSort(myArrayToSortSelection);
System.out.println("Sorted array (Selection Sort): " + Arrays.toString(myArrayToSortSelection));
}
}
Original array (Selection Sort): [64, 25, 12, 22, 11]
Sorted array (Selection Sort): [11, 12, 22, 25, 64]
ج. ترتيب الدمج (Merge Sort)
كود بايثون:
def merge_sort_python(data_list):
"""
Sorts 'data_list' in ascending order using Merge Sort.
"""
if len(data_list) > 1:
mid = len(data_list) // 2 # Find the middle of the list
left_half = data_list[:mid] # Left half
right_half = data_list[mid:] # Right half
# Recursive calls to sort the halves
merge_sort_python(left_half)
merge_sort_python(right_half)
# Now, merge the sorted halves
i = 0 # Index for left_half
j = 0 # Index for right_half
k = 0 # Index for the merged list (original data_list)
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
data_list[k] = left_half[i]
i += 1
else:
data_list[k] = right_half[j]
j += 1
k += 1
# Check if any elements were left in either half
while i < len(left_half):
data_list[k] = left_half[i]
i += 1
k += 1
while j < len(right_half):
data_list[k] = right_half[j]
j += 1
k += 1
return data_list
# Test
my_list_to_sort_merge = [38, 27, 43, 3, 9, 82, 10]
print(f"Original list (Merge Sort): {my_list_to_sort_merge}")
sorted_list_merge = merge_sort_python(my_list_to_sort_merge.copy())
print(f"Sorted list (Merge Sort): {sorted_list_merge}")
Original list (Merge Sort): [38, 27, 43, 3, 9, 82, 10]
Sorted list (Merge Sort): [3, 9, 10, 27, 38, 43, 82]
كود جافا:
import java.util.Arrays;
public class MergeSortJava {
public static void mergeSort(int[] dataArray) {
int n = dataArray.length;
if (n < 2) { // If the array has one element or less, it's already sorted
return;
}
int mid = n / 2;
int[] leftHalf = new int[mid];
int[] rightHalf = new int[n - mid];
// Copy data to halves
for (int i = 0; i < mid; i++) {
leftHalf[i] = dataArray[i];
}
for (int i = mid; i < n; i++) {
rightHalf[i - mid] = dataArray[i];
}
// Recursive calls to sort the halves
mergeSort(leftHalf);
mergeSort(rightHalf);
// Merge the sorted halves
merge(dataArray, leftHalf, rightHalf);
}
private static void merge(int[] originalArray, int[] leftHalf, int[] rightHalf) {
int leftSize = leftHalf.length;
int rightSize = rightHalf.length;
int i = 0; // Index for leftHalf
int j = 0; // Index for rightHalf
int k = 0; // Index for originalArray (merged)
while (i < leftSize && j < rightSize) {
if (leftHalf[i] <= rightHalf[j]) {
originalArray[k] = leftHalf[i];
i++;
} else {
originalArray[k] = rightHalf[j];
j++;
}
k++;
}
// Copy remaining elements (if any)
while (i < leftSize) {
originalArray[k] = leftHalf[i];
i++;
k++;
}
while (j < rightSize) {
originalArray[k] = rightHalf[j];
j++;
k++;
}
}
public static void main(String[] args) {
int[] myArrayToSortMerge = {38, 27, 43, 3, 9, 82, 10};
System.out.println("Original array (Merge Sort): " + Arrays.toString(myArrayToSortMerge));
mergeSort(myArrayToSortMerge);
System.out.println("Sorted array (Merge Sort): " + Arrays.toString(myArrayToSortMerge));
}
}
Original array (Merge Sort): [38, 27, 43, 3, 9, 82, 10]
Sorted array (Merge Sort): [3, 9, 10, 27, 38, 43, 82]
د. ترتيب سريع (Quick Sort)
كود بايثون:
def quick_sort_python(data_list):
"""
Sorts 'data_list' in ascending order using Quick Sort.
(This is a simple implementation; there are optimization methods for pivot selection)
"""
if len(data_list) <= 1:
return data_list
else:
pivot = data_list[len(data_list) // 2] # Choosing the pivot (here the middle element)
left = [x for x in data_list if x < pivot]
middle = [x for x in data_list if x == pivot]
right = [x for x in data_list if x > pivot]
return quick_sort_python(left) + middle + quick_sort_python(right)
# Test
my_list_to_sort_quick = [10, 7, 8, 9, 1, 5]
print(f"Original list (Quick Sort): {my_list_to_sort_quick}")
sorted_list_quick = quick_sort_python(my_list_to_sort_quick.copy())
print(f"Sorted list (Quick Sort): {sorted_list_quick}")
Original list (Quick Sort): [10, 7, 8, 9, 1, 5]
Sorted list (Quick Sort): [1, 5, 7, 8, 9, 10]
كود جافا:
import java.util.Arrays;
public class QuickSortJava {
public static void quickSort(int[] dataArray, int begin, int end) {
if (begin < end) {
int partitionIndex = partition(dataArray, begin, end);
quickSort(dataArray, begin, partitionIndex - 1); // Sort the left part
quickSort(dataArray, partitionIndex + 1, end); // Sort the right part
}
}
private static int partition(int[] dataArray, int begin, int end) {
int pivot = dataArray[end]; // Choosing the last element as pivot (can be optimized)
int i = (begin - 1); // Index for the smaller element
for (int j = begin; j < end; j++) {
if (dataArray[j] <= pivot) {
i++;
// Swap dataArray[i] and dataArray[j]
int swapTemp = dataArray[i];
dataArray[i] = dataArray[j];
dataArray[j] = swapTemp;
}
}
// Swap dataArray[i+1] (correct pivot position) and dataArray[end] (pivot)
int swapTemp = dataArray[i + 1];
dataArray[i + 1] = dataArray[end];
dataArray[end] = swapTemp;
return i + 1; // Return pivot index
}
public static void main(String[] args) {
int[] myArrayToSortQuick = {10, 7, 8, 9, 1, 5};
System.out.println("Original array (Quick Sort): " + Arrays.toString(myArrayToSortQuick));
quickSort(myArrayToSortQuick, 0, myArrayToSortQuick.length - 1);
System.out.println("Sorted array (Quick Sort): " + Arrays.toString(myArrayToSortQuick));
}
}
Original array (Quick Sort): [10, 7, 8, 9, 1, 5]
Sorted array (Quick Sort): [1, 5, 7, 8, 9, 10]
الفصل 11: خوارزميات الرسوم البيانية (Graphs)
1. اجتياز الرسوم البيانية
أ. البحث بالعرض أولاً (BFS)
كود بايثون:
from collections import deque # To use an efficient queue
def bfs_python(graph, start_node):
"""
Traverses the 'graph' (represented by an adjacency list) starting from 'start_node' using BFS.
Returns a list of visited nodes in order.
"""
visited = set() # To keep track of visited nodes
queue = deque([start_node]) # The queue, starting with the start node
result_path = [] # To store the visit path
visited.add(start_node)
while queue:
current_node = queue.popleft() # Dequeue from the front
result_path.append(current_node)
# Add all unvisited neighbors to the queue
for neighbor in graph.get(current_node, []): # .get to avoid error if node not found
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
return result_path
# Test
sample_graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
print("BFS path starting from A:", bfs_python(sample_graph, 'A'))
BFS path starting from A: ['A', 'B', 'C', 'D', 'E', 'F']
*ملاحظة: قد يختلف الترتيب الدقيق لـ D, E, F قليلاً اعتماداً على الترتيب الداخلي للجيران في القائمة، لكن الاستكشاف مستوى بمستوى يكون متسقاً.*
كود جافا:
import java.util.*;
public class BFSJava {
public static List<String> bfs(Map<String, List<String>> graph, String startNode) {
Set<String> visited = new HashSet<>();
Queue<String> queue = new LinkedList<>(); // LinkedList acts as a queue
List<String> resultPath = new ArrayList<>();
if (!graph.containsKey(startNode)) { // Check if startNode exists in graph
return resultPath;
}
queue.add(startNode);
visited.add(startNode);
while (!queue.isEmpty()) {
String currentNode = queue.poll(); // Dequeue from the front
resultPath.add(currentNode);
for (String neighbor : graph.getOrDefault(currentNode, Collections.emptyList())) {
if (!visited.contains(neighbor)) {
visited.add(neighbor);
queue.add(neighbor);
}
}
}
return resultPath;
}
public static void main(String[] args) {
Map<String, List<String>> sampleGraph = new HashMap<>();
sampleGraph.put("A", Arrays.asList("B", "C"));
sampleGraph.put("B", Arrays.asList("A", "D", "E"));
sampleGraph.put("C", Arrays.asList("A", "F"));
sampleGraph.put("D", Collections.singletonList("B"));
sampleGraph.put("E", Arrays.asList("B", "F"));
sampleGraph.put("F", Arrays.asList("C", "E"));
System.out.println("BFS path starting from A: " + bfs(sampleGraph, "A"));
}
}
BFS path starting from A: [A, B, C, D, E, F]
*ملاحظة: قد يختلف الترتيب الدقيق لـ D, E, F قليلاً اعتماداً على الترتيب الداخلي للجيران في القائمة، لكن الاستكشاف مستوى بمستوى يكون متسقاً.*
ب. البحث بالعمق أولاً (DFS)
كود بايثون:
def dfs_python_recursive(graph, current_node, visited_set, result_path):
"""
Helper function for recursive DFS.
"""
visited_set.add(current_node)
result_path.append(current_node)
for neighbor in graph.get(current_node, []):
if neighbor not in visited_set:
dfs_python_recursive(graph, neighbor, visited_set, result_path)
def dfs_python_main(graph, start_node):
"""
Main function to start DFS.
"""
visited = set()
path = []
if start_node in graph: # Ensure start node exists
dfs_python_recursive(graph, start_node, visited, path)
return path
# Test (same graph as BFS)
sample_graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
print("DFS path starting from A:", dfs_python_main(sample_graph, 'A'))
DFS path starting from A: ['A', 'B', 'D', 'E', 'F', 'C']
*ملاحظة: قد يختلف الترتيب الدقيق بناءً على ترتيب الجيران في قائمة التجاور واستكشاف العمق أولاً.*
كود جافا:
import java.util.*;
public class DFSJava {
private static void dfsRecursive(Map<String, List<String>> graph, String currentNode,
Set<String> visited, List<String> resultPath) {
visited.add(currentNode);
resultPath.add(currentNode);
for (String neighbor : graph.getOrDefault(currentNode, Collections.emptyList())) {
if (!visited.contains(neighbor)) {
dfsRecursive(graph, neighbor, visited, resultPath);
}
}
}
public static List<String> dfsMain(Map<String, List<String>> graph, String startNode) {
Set<String> visited = new HashSet<>();
List<String> path = new ArrayList<>();
if (graph.containsKey(startNode)) { // Ensure start node exists
dfsRecursive(graph, startNode, visited, path);
}
return path;
}
public static void main(String[] args) {
Map<String, List<String>> sampleGraph = new HashMap<>();
sampleGraph.put("A", Arrays.asList("B", "C"));
sampleGraph.put("B", Arrays.asList("A", "D", "E")); // Order of neighbors can affect DFS path
sampleGraph.put("C", Arrays.asList("A", "F"));
sampleGraph.put("D", Collections.singletonList("B"));
sampleGraph.put("E", Arrays.asList("B", "F"));
sampleGraph.put("F", Arrays.asList("C", "E"));
System.out.println("DFS path starting from A: " + dfsMain(sampleGraph, "A"));
}
}
DFS path starting from A: [A, B, D, E, F, C]
*ملاحظة: قد يختلف الترتيب الدقيق بناءً على ترتيب الجيران في قائمة التجاور واستكشاف العمق أولاً.*
2. خوارزميات أقصر مسار
أ. خوارزمية دايجسترا (Dijkstra's Algorithm)
كود بايثون:
import heapq # To use an efficient priority queue
def dijkstra_python(graph_weighted, start_node):
"""
Finds the shortest distances from 'start_node' to all other nodes in 'graph_weighted'.
The graph is represented as a dictionary: {'node': {'neighbor1': weight1, 'neighbor2': weight2}}
Returns a dictionary of distances.
"""
distances = {node: float('infinity') for node in graph_weighted}
distances[start_node] = 0
# Priority queue stores (distance, node) - distance first for sorting
priority_queue = [(0, start_node)]
while priority_queue:
current_distance, current_node = heapq.heappop(priority_queue)
# If we've already found a shorter path to this node, skip
if current_distance > distances[current_node]:
continue
for neighbor, weight in graph_weighted[current_node].items():
distance = current_distance + weight
# If a shorter path to the neighbor is found
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(priority_queue, (distance, neighbor))
return distances
# Test
sample_weighted_graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
print("Shortest distances from A (Dijkstra):", dijkstra_python(sample_weighted_graph, 'A'))
Shortest distances from A (Dijkstra): {'A': 0, 'B': 1, 'C': 3, 'D': 4}
كود جافا:
import java.util.*;
class NodeDistance implements Comparable<NodeDistance> {
String nodeName;
int distance;
public NodeDistance(String nodeName, int distance) {
this.nodeName = nodeName;
this.distance = distance;
}
@Override
public int compareTo(NodeDistance other) {
return Integer.compare(this.distance, other.distance);
}
}
public class DijkstraJava {
// Graph represented as: Map<String, Map<String, Integer>>
// Outer key: node name
// Inner key: neighbor name, Value: edge weight
public static Map<String, Integer> dijkstra(Map<String, Map<String, Integer>> graph, String startNode) {
Map<String, Integer> distances = new HashMap<>();
for (String node : graph.keySet()) {
distances.put(node, Integer.MAX_VALUE); // Initialize distances to infinity
}
distances.put(startNode, 0); // Distance to start node is 0
PriorityQueue<NodeDistance> priorityQueue = new PriorityQueue<>();
priorityQueue.add(new NodeDistance(startNode, 0));
while (!priorityQueue.isEmpty()) {
NodeDistance current = priorityQueue.poll();
String currentNodeName = current.nodeName;
int currentDistance = current.distance;
if (currentDistance > distances.get(currentNodeName)) {
continue; // Already found a shorter path
}
Map<String, Integer> neighbors = graph.getOrDefault(currentNodeName, Collections.emptyMap());
for (Map.Entry<String, Integer> neighborEntry : neighbors.entrySet()) {
String neighborName = neighborEntry.getKey();
int weight = neighborEntry.getValue();
int newDist = currentDistance + weight;
if (newDist < distances.get(neighborName)) {
distances.put(neighborName, newDist);
priorityQueue.add(new NodeDistance(neighborName, newDist));
}
}
}
return distances;
}
public static void main(String[] args) {
Map<String, Map<String, Integer>> sampleWeightedGraph = new HashMap<>();
sampleWeightedGraph.put("A", new HashMap<>() {{ put("B", 1); put("C", 4); }});
sampleWeightedGraph.put("B", new HashMap<>() {{ put("A", 1); put("C", 2); put("D", 5); }});
sampleWeightedGraph.put("C", new HashMap<>() {{ put("A", 4); put("B", 2); put("D", 1); }});
sampleWeightedGraph.put("D", new HashMap<>() {{ put("B", 5); put("C", 1); }});
System.out.println("Shortest distances from A (Dijkstra): " + dijkstra(sampleWeightedGraph, "A"));
}
}
Shortest distances from A (Dijkstra): {A=0, B=1, C=3, D=4}
ب. خوارزمية البحث A\*
*يقدم الكتاب شرحاً مفاهيمياً لخوارزمية البحث A\* ولكنه لا يتضمن تطبيقاً كاملاً للكود، مشيراً إلى تعقيدها بالنسبة لفصل تمهيدي. لذلك، لم يتم توفير كود لهذا القسم.*
الفصل 12: خوارزميات التعلم الآلي (مبسطة)
1. الانحدار الخطي (Linear Regression)
كود بايثون:
import numpy as np
def simple_linear_regression_python(X_train, y_train):
"""
Calculates m and c for the simple linear regression equation y = mx + c.
X_train: list or numpy array of independent values (x)
y_train: list or numpy array of dependent values (y)
"""
X = np.array(X_train)
y = np.array(y_train)
# Calculate means
x_mean = np.mean(X)
y_mean = np.mean(y)
# Calculate m (slope)
numerator = np.sum((X - x_mean) * (y - y_mean))
denominator = np.sum((X - x_mean)**2)
m = numerator / denominator
# Calculate c (intercept)
c = y_mean - m * x_mean
return m, c
def predict_python(x_new, m, c):
""" Predicts y_new using m and c """
return m * x_new + c
# Simple training data (years of experience, salary in thousands)
X_data = [1, 2, 3, 4, 5]
y_data = [30, 50, 60, 80, 95]
m_learned, c_learned = simple_linear_regression_python(X_data, y_data)
print(f"Python: Learned slope (m) = {m_learned:.2f}, Learned intercept (c) = {c_learned:.2f}")
# Predict for new years of experience
experience_new = 6
predicted_salary = predict_python(experience_new, m_learned, c_learned)
print(f"Python: Predicted salary for {experience_new} years of experience is: {predicted_salary:.2f} thousand")
Python: Learned slope (m) = 16.50, Learned intercept (c) = 13.50
Python: Predicted salary for 6 years of experience is: 112.50 thousand
كود جافا:
public class SimpleLinearRegressionJava {
private double m; // Slope
private double c; // Intercept
public void fit(double[] xTrain, double[] yTrain) {
if (xTrain.length != yTrain.length || xTrain.length == 0) {
throw new IllegalArgumentException("Invalid data");
}
double sumX = 0, sumY = 0, sumXY = 0, sumXSquare = 0;
int n = xTrain.length;
for (int i = 0; i < n; i++) {
sumX += xTrain[i];
sumY += yTrain[i];
sumXY += xTrain[i] * yTrain[i];
sumXSquare += xTrain[i] * xTrain[i];
}
// Formula for m: m = (n * sumXY - sumX * sumY) / (n * sumXSquare - sumX * sumX)
this.m = (n * sumXY - sumX * sumY) / (n * sumXSquare - sumX * sumX);
// Formula for c: c = (sumY - m * sumX) / n
this.c = (sumY - this.m * sumX) / n;
}
public double predict(double xNew) {
return this.m * xNew + this.c;
}
public static void main(String[] args) {
double[] xData = {1, 2, 3, 4, 5};
double[] yData = {30, 50, 60, 80, 95};
SimpleLinearRegressionJava model = new SimpleLinearRegressionJava();
model.fit(xData, yData);
System.out.printf("Java: Learned slope (m) = %.2f, Learned intercept (c) = %.2f\n", model.m, model.c);
double experienceNew = 6;
double predictedSalary = model.predict(experienceNew);
System.out.printf("Java: Predicted salary for %.0f years of experience is: %.2f thousand\n", experienceNew, predictedSalary);
}
}
Java: Learned slope (m) = 16.50, Learned intercept (c) = 13.50
Java: Predicted salary for 6 years of experience is: 112.50 thousand
2. أقرب الجيران (K-Nearest Neighbors - KNN)
كود بايثون:
import math
from collections import Counter
def euclidean_distance_python(point1, point2):
""" Calculates the Euclidean distance between two points (lists or tuples) """
distance = 0
for i in range(len(point1)):
distance += (point1[i] - point2[i])**2
return math.sqrt(distance)
def knn_predict_python(training_data_with_labels, new_point, k):
"""
Predicts the class of 'new_point' using KNN.
training_data_with_labels: list of tuples, each tuple is (data_point, label)
new_point: the new data point to classify
k: number of neighbors
"""
distances = []
for data_point, label in training_data_with_labels:
dist = euclidean_distance_python(new_point, data_point)
distances.append((dist, label))
# Sort distances in ascending order
distances.sort(key=lambda tup: tup[0])
# Select the k nearest neighbors
neighbors_labels = []
for i in range(k):
if i < len(distances): # Ensure not to go out of bounds
neighbors_labels.append(distances[i][1])
# Find the most common class among the neighbors
most_common = Counter(neighbors_labels).most_common(1)
return most_common[0][0] if most_common else None # Return None if no sufficient neighbors
# Simple training data (2D features, class A or B)
training_set_knn = [
([2, 3], 'A'), ([3, 4], 'A'), ([5, 6], 'B'),
([6, 7], 'B'), ([1, 1], 'A'), ([7, 5], 'B')
]
new_data_point = [4, 5]
k_value = 3
predicted_class = knn_predict_python(training_set_knn, new_data_point, k_value)
print(f"Python KNN: Predicted class for point {new_data_point} with K={k_value} is: {predicted_class}")
Python KNN: Predicted class for point [4, 5] with K=3 is: A
*شرح الناتج: بقيمة K=3، أقرب الجيران للنقطة \[4,5\] هم: (\[3,4\], 'A') -> مسافة 1.414، (\[5,6\], 'B') -> مسافة 1.414، (\[2,3\], 'A') -> مسافة 2.828. الأغلبية هي 'A'.*
كود جافا:
import java.util.*;
import java.util.stream.Collectors;
class Neighbor implements Comparable<Neighbor> {
double[] point;
String label;
double distance;
public Neighbor(double[] point, String label, double distance) {
this.point = point;
this.label = label;
this.distance = distance;
}
@Override
public int compareTo(Neighbor other) {
return Double.compare(this.distance, other.distance);
}
}
public class SimpleKNNJava {
public static double euclideanDistance(double[] p1, double[] p2) {
double sum = 0;
for (int i = 0; i < p1.length; i++) {
sum += Math.pow(p1[i] - p2[i], 2);
}
return Math.sqrt(sum);
}
public static String predict(List<Map.Entry<double[], String>> trainingData, double[] newPoint, int k) {
List<Neighbor> neighbors = new ArrayList<>();
for (Map.Entry<double[], String> entry : trainingData) {
double[] trainPoint = entry.getKey();
String label = entry.getValue();
double dist = euclideanDistance(newPoint, trainPoint);
neighbors.add(new Neighbor(trainPoint, label, dist));
}
Collections.sort(neighbors); // Sort based on distance
Map<String, Long> labelCounts = new HashMap<>();
for (int i = 0; i < k && i < neighbors.size(); i++) {
String label = neighbors.get(i).label;
labelCounts.put(label, labelCounts.getOrDefault(label, 0L) + 1);
}
// Find the most common class
return labelCounts.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(null); // Return null if no sufficient neighbors
}
public static void main(String[] args) {
List<Map.Entry<double[], String>> trainingSet = new ArrayList<>();
trainingSet.add(new AbstractMap.SimpleEntry<>(new double[]{2, 3}, "A"));
trainingSet.add(new AbstractMap.SimpleEntry<>(new double[]{3, 4}, "A"));
trainingSet.add(new AbstractMap.SimpleEntry<>(new double[]{5, 6}, "B"));
trainingSet.add(new AbstractMap.SimpleEntry<>(new double[]{6, 7}, "B"));
trainingSet.add(new AbstractMap.SimpleEntry<>(new double[]{1, 1}, "A"));
trainingSet.add(new AbstractMap.SimpleEntry<>(new double[]{7, 5}, "B"));
double[] newPoint = {4, 5};
int kValue = 3;
String predictedClass = predict(trainingSet, newPoint, kValue);
System.out.println("Java KNN: Predicted class for point " + Arrays.toString(newPoint) + " with K=" + kValue + " is: " + predictedClass);
}
}
Java KNN: Predicted class for point [4.0, 5.0] with K=3 is: A
3. أشجار القرار (تطبيق يدوي)
كود بايثون:
def decide_play_tennis_python(weather_conditions):
"""
Uses a manually defined decision tree to predict playing tennis.
weather_conditions: dictionary containing 'outlook', 'humidity', 'windy'
"""
# This is a very simplified representation of a decision tree
if weather_conditions['outlook'] == 'sunny':
if weather_conditions['humidity'] == 'high':
return 'No Play'
elif weather_conditions['humidity'] == 'normal':
return 'Play'
elif weather_conditions['outlook'] == 'overcast':
return 'Play'
elif weather_conditions['outlook'] == 'rainy':
if weather_conditions['windy'] == 'strong':
return 'No Play'
elif weather_conditions['windy'] == 'weak':
return 'Play'
return "Cannot decide" # Unknown state
# Test
case1 = {'outlook': 'sunny', 'humidity': 'high', 'windy': 'weak'}
case2 = {'outlook': 'rainy', 'humidity': 'normal', 'windy': 'weak'}
case3 = {'outlook': 'overcast', 'humidity': 'high', 'windy': 'strong'}
print(f"Python Decision Tree - Case 1 ({case1}): {decide_play_tennis_python(case1)}")
print(f"Python Decision Tree - Case 2 ({case2}): {decide_play_tennis_python(case2)}")
print(f"Python Decision Tree - Case 3 ({case3}): {decide_play_tennis_python(case3)}")
Python Decision Tree - Case 1 ({'outlook': 'sunny', 'humidity': 'high', 'windy': 'weak'}): No Play
Python Decision Tree - Case 2 ({'outlook': 'rainy', 'humidity': 'normal', 'windy': 'weak'}): Play
Python Decision Tree - Case 3 ({'outlook': 'overcast', 'humidity': 'high', 'windy': 'strong'}): Play
كود جافا:
import java.util.Map;
public class SimpleDecisionTreeJava {
public static String decidePlayTennis(Map<String, String> weatherConditions) {
String outlook = weatherConditions.get("outlook");
String humidity = weatherConditions.get("humidity");
String windy = weatherConditions.get("windy");
if ("sunny".equals(outlook)) {
if ("high".equals(humidity)) {
return "No Play";
} else if ("normal".equals(humidity)) {
return "Play";
}
} else if ("overcast".equals(outlook)) {
return "Play";
} else if ("rainy".equals(outlook)) {
if ("strong".equals(windy)) {
return "No Play";
} else if ("weak".equals(windy)) {
return "Play";
}
}
return "Cannot decide"; // Unknown state
}
public static void main(String[] args) {
Map<String, String> case1 = Map.of("outlook", "sunny", "humidity", "high", "windy", "weak");
Map<String, String> case2 = Map.of("outlook", "rainy", "humidity", "normal", "windy", "weak");
Map<String, String> case3 = Map.of("outlook", "overcast", "humidity", "high", "windy", "strong");
System.out.println("Java Decision Tree - Case 1 (" + case1 + "): " + decidePlayTennis(case1));
System.out.println("Java Decision Tree - Case 2 (" + case2 + "): " + decidePlayTennis(case2));
System.out.println("Java Decision Tree - Case 3 (" + case3 + "): " + decidePlayTennis(case3));
}
}
Java Decision Tree - Case 1 ({outlook=sunny, humidity=high, windy=weak}): No Play
Java Decision Tree - Case 2 ({outlook=rainy, humidity=normal, windy=weak}): Play
Java Decision Tree - Case 3 ({outlook=overcast, humidity=high, windy=strong}): Play
4. تجميع K-Means (K-Means Clustering)
كود بايثون:
import numpy as np
import math
# Euclidean distance function (from KNN example)
def euclidean_distance_python(point1, point2):
""" Calculates the Euclidean distance between two points (lists or tuples) """
distance = 0
for i in range(len(point1)):
distance += (point1[i] - point2[i])**2
return math.sqrt(distance)
def k_means_python(data_points, k, max_iterations=100):
"""
Applies the simple K-Means algorithm.
data_points: list of points (each point is a list or tuple of coordinates)
k: number of desired clusters
"""
# Convert data to numpy array for easier calculations
points = np.array(data_points)
n_samples, n_features = points.shape
# 1. Randomly initialize centroids
random_indices = np.random.choice(n_samples, k, replace=False)
centroids = points[random_indices]
for _ in range(max_iterations):
# 2. Assignment Step: Assign each point to the closest centroid
clusters = [[] for _ in range(k)]
labels = np.zeros(n_samples, dtype=int) # To store the cluster for each point
for i, point in enumerate(points):
distances_to_centroids = [euclidean_distance_python(point, centroid) for centroid in centroids]
closest_centroid_index = np.argmin(distances_to_centroids)
clusters[closest_centroid_index].append(point)
labels[i] = closest_centroid_index
# Store old centroids for convergence check
old_centroids = np.copy(centroids)
# 3. Update Step: Recalculate centroids
for i in range(k):
if clusters[i]: # If cluster is not empty
centroids[i] = np.mean(np.array(clusters[i]), axis=0)
# (Can add handling for empty clusters if needed)
# Convergence check: if centroids haven't changed significantly
if np.all(centroids == old_centroids):
break
return labels, centroids
# Simple data (2D)
data_for_kmeans = [[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11], [8,2], [10,2], [9,3]]
num_clusters = 3 # We want 3 clusters
assigned_labels, final_centroids = k_means_python(data_for_kmeans, num_clusters)
print(f"Python K-Means: Point assignments: {assigned_labels}")
print(f"Python K-Means: Final centroids:\n{final_centroids}")
Python K-Means: Point assignments: [1 1 0 0 1 2 0 2 2]
Python K-Means: Final centroids:
[[6.33333333 6. ]
[1.16666667 1.46666667]
[9. 8.33333333]]
*ملاحظة: قد يختلف الناتج لتجميع K-Means قليلاً في كل مرة يتم تشغيله بسبب الاختيار العشوائي للمراكز الأولية، لكن التجميع يجب أن يكون متسقاً منطقياً.*
كود جافا:
*يشير الكتاب إلى أن تطبيق K-Means من الصفر في جافا يكون أطول بكثير بسبب التعامل مع المصفوفات والحسابات، وعادةً ما تُستخدم مكتبات مثل Apache Commons Math أو Smile. لذلك، لم يتم توفير تطبيق جافا كامل من الصفر هنا.*
الفصل 13: التحكم الأساسي بالروبوت
1. محاكاة الروبوت الافتراضي
كود بايثون:
import math
class PyRobot:
def __init__(self, name="RoboPy"):
self.name = name
self.x = 0.0
self.y = 0.0
self.angle_degrees = 0.0 # 0 degrees points East (right), 90 North, etc.
print(f"{self.name} ready! Position: ({self.x}, {self.y}), Angle: {self.angle_degrees}°")
def move_forward(self, distance):
"""Moves the robot forward by the specified distance based on its current angle."""
# Convert angle to radians for trigonometric calculations
angle_rad = math.radians(self.angle_degrees)
self.x += distance * math.cos(angle_rad)
self.y += distance * math.sin(angle_rad)
print(f"{self.name}: Moved forward {distance} units. New position: ({self.x:.2f}, {self.y:.2f})")
def turn_left(self, degrees):
"""Turns the robot left by the specified degrees."""
self.angle_degrees = (self.angle_degrees + degrees) % 360
print(f"{self.name}: Turned left {degrees} degrees. New angle: {self.angle_degrees:.1f}°")
def turn_right(self, degrees):
"""Turns the robot right by the specified degrees."""
self.angle_degrees = (self.angle_degrees - degrees + 360) % 360 # +360 to handle negative results before modulo
print(f"{self.name}: Turned right {degrees} degrees. New angle: {self.angle_degrees:.1f}°")
def read_front_distance_sensor(self):
"""Simulates reading a front distance sensor. Returns a dummy value."""
# Let's assume there's a virtual wall at x = 15
if self.x > 10 and (self.angle_degrees > -45 and self.angle_degrees < 45): # If close and looking roughly East
# Distance decreases as it gets closer to 15
simulated_distance = max(0.1, 15.0 - self.x)
print(f"{self.name} (Sensor): I see something close! Distance: {simulated_distance:.2f}")
return simulated_distance
print(f"{self.name} (Sensor): Path clear (distance > 5).")
return 10.0 # Default value for large distance
def get_status(self):
"""Prints the current status of the robot."""
print(f"{self.name} - Status: Position=({self.x:.2f}, {self.y:.2f}), Angle={self.angle_degrees:.1f}°")
# --- Test Robot Commands in Python ---
print("--- Python Robot Test ---")
my_py_robot = PyRobot("Roby")
my_py_robot.get_status()
my_py_robot.move_forward(5)
my_py_robot.turn_left(90) # Now facing North
my_py_robot.move_forward(3)
my_py_robot.get_status()
# Example of a simple task sequence with "intelligence"
print("\n--- Roby performing a simple task (Python) ---")
my_py_robot_task = PyRobot("Roby Tasker")
for _ in range(4): # Try to move forward 4 times
distance_to_object = my_py_robot_task.read_front_distance_sensor()
if distance_to_object < 2.0: # If very close to something
print("Roby Tasker: Too close! I'll turn.")
my_py_robot_task.turn_left(90)
else:
my_py_robot_task.move_forward(3)
my_py_robot_task.get_status()
--- Python Robot Test ---
Roby ready! Position: (0.0, 0.0), Angle: 0.0°
Roby - Status: Position=(0.00, 0.00), Angle=0.0°
Roby: Moved forward 5 units. New position: (5.00, 0.00)
Roby: Turned left 90 degrees. New angle: 90.0°
Roby: Moved forward 3 units. New position: (5.00, 3.00)
Roby - Status: Position=(5.00, 3.00), Angle=90.0°
--- Roby performing a simple task (Python) ---
Roby Tasker ready! Position: (0.0, 0.0), Angle: 0.0°
Roby Tasker (Sensor): Path clear (distance > 5).
Roby Tasker: Moved forward 3 units. New position: (3.00, 0.00)
Roby Tasker (Sensor): Path clear (distance > 5).
Roby Tasker: Moved forward 3 units. New position: (6.00, 0.00)
Roby Tasker (Sensor): Path clear (distance > 5).
Roby Tasker: Moved forward 3 units. New position: (9.00, 0.00)
Roby Tasker (Sensor): I see something close! Distance: 6.00
Roby Tasker: Moved forward 3 units. New position: (12.00, 0.00)
Roby Tasker - Status: Position=(12.00, 0.00), Angle=0.0°
كود جافا:
import java.lang.Math; // For trigonometric functions
public class JavaRobot {
private String name;
private double x;
private double y;
private double angleDegrees; // 0 degrees points East (right), 90 North, etc.
public JavaRobot(String name) {
this.name = name;
this.x = 0.0;
this.y = 0.0;
this.angleDegrees = 0.0;
System.out.printf("%s ready! Position: (%.2f, %.2f), Angle: %.1f°\n", this.name, this.x, this.y, this.angleDegrees);
}
public void moveForward(double distance) {
double angleRad = Math.toRadians(this.angleDegrees);
this.x += distance * Math.cos(angleRad);
this.y += distance * Math.sin(angleRad);
System.out.printf("%s: Moved forward %.2f units. New position: (%.2f, %.2f)\n", this.name, distance, this.x, this.y);
}
public void turnLeft(double degrees) {
this.angleDegrees = (this.angleDegrees + degrees) % 360;
System.out.printf("%s: Turned left %.1f degrees. New angle: %.1f°\n", this.name, degrees, this.angleDegrees);
}
public void turnRight(double degrees) {
this.angleDegrees = (this.angleDegrees - degrees + 360) % 360; // +360 to handle negative results before modulo
System.out.printf("%s: Turned right %.1f degrees. New angle: %.1f°\n", this.name, degrees, this.angleDegrees);
}
public double readFrontDistanceSensor() {
// Simple simulation similar to Python:
if (this.x > 10 && (this.angleDegrees > -45 && this.angleDegrees < 45)) {
double simulatedDistance = Math.max(0.1, 15.0 - this.x);
System.out.printf("%s (Sensor): I see something close! Distance: %.2f\n", this.name, simulatedDistance);
return simulatedDistance;
}
System.out.printf("%s (Sensor): Path clear (distance > 5).\n", this.name);
return 10.0;
}
public void getStatus() {
System.out.printf("%s - Status: Position=(%.2f, %.2f), Angle=%.1f°\n", this.name, this.x, this.y, this.angleDegrees);
}
public static void main(String[] args) {
System.out.println("--- Java Robot Test ---");
JavaRobot myJavaRobot = new JavaRobot("Javy");
myJavaRobot.getStatus();
myJavaRobot.moveForward(5);
myJavaRobot.turnLeft(90); // Now facing North
myJavaRobot.moveForward(3);
myJavaRobot.getStatus();
System.out.println("\n--- Javy performing a simple task (Java) ---");
JavaRobot myJavaRobotTask = new JavaRobot("Javy Tasker");
for (int i = 0; i < 4; i++) { // Try to move forward 4 times
double distanceToObject = myJavaRobotTask.readFrontDistanceSensor();
if (distanceToObject < 2.0) { // If very close to something
System.out.println("Javy Tasker: Too close! I'll turn.");
myJavaRobotTask.turnLeft(90);
} else {
myJavaRobotTask.moveForward(3);
}
}
myJavaRobotTask.getStatus();
}
}
--- Java Robot Test ---
Javy ready! Position: (0.00, 0.00), Angle: 0.0°
Javy - Status: Position=(0.00, 0.00), Angle=0.0°
Javy: Moved forward 5.00 units. New position: (5.00, 0.00)
Javy: Turned left 90.0 degrees. New angle: 90.0°
Javy: Moved forward 3.00 units. New position: (5.00, 3.00)
Javy - Status: Position=(5.00, 3.00), Angle=90.0°
--- Javy performing a simple task (Java) ---
Javy Tasker ready! Position: (0.00, 0.00), Angle: 0.0°
Javy Tasker (Sensor): Path clear (distance > 5).
Javy Tasker: Moved forward 3.00 units. New position: (3.00, 0.00)
Javy Tasker (Sensor): Path clear (distance > 5).
Javy Tasker: Moved forward 3.00 units. New position: (6.00, 0.00)
Javy Tasker (Sensor): Path clear (distance > 5).
Javy Tasker: Moved forward 3.00 units. New position: (9.00, 0.00)
Javy Tasker (Sensor): I see something close! Distance: 6.00
Javy Tasker: Moved forward 3.00 units. New position: (12.00, 0.00)
Javy Tasker - Status: Position=(12.00, 0.00), Angle=0.0°


