SI_Traktor/Kamila.py

249 lines
7.1 KiB
Python
Raw Normal View History

2020-05-28 15:03:13 +02:00
import time
2020-05-15 13:54:18 +02:00
2020-05-18 17:13:09 +02:00
header = ["hydration", "weeds", "empty", "ready", "TODO"]
work = ["Podlac", "Odchwascic", "Zasadzic", "Zebrac"]
2020-05-28 15:03:13 +02:00
order = [3, 1, 2, 0]
2020-05-15 13:54:18 +02:00
2020-05-28 15:03:13 +02:00
# ustalenie kolejnosci czynnosci
# 3 - zebranie
# 1 - odchwaszczenie
# 2 - zasadzenie
# 0 - podlanie
def translate(field):
2020-05-15 13:54:18 +02:00
if field == 0:
2020-05-28 15:03:13 +02:00
return [0, 0, 1, 0]
2020-05-15 13:54:18 +02:00
elif field == 1:
2020-05-28 15:03:13 +02:00
return [0, 1, 1, 0]
2020-05-15 13:54:18 +02:00
elif field == 2:
2020-05-28 15:03:13 +02:00
return [0, 0, 0, 0]
2020-05-15 13:54:18 +02:00
elif field == 3:
2020-05-28 15:03:13 +02:00
return [0, 1, 0, 0]
2020-05-15 13:54:18 +02:00
elif field == 4:
2020-05-28 15:03:13 +02:00
return [1, 0, 1, 0]
2020-05-15 13:54:18 +02:00
elif field == 5:
2020-05-28 15:03:13 +02:00
return [1, 1, 1, 0]
2020-05-15 13:54:18 +02:00
elif field == 6:
2020-05-28 15:03:13 +02:00
return [1, 0, 0, 0]
2020-05-15 13:54:18 +02:00
elif field == 7:
2020-05-28 15:03:13 +02:00
return [1, 1, 0, 0]
2020-05-15 13:54:18 +02:00
elif field == 8:
2020-05-28 15:03:13 +02:00
return [0, 0, 0, 1]
2020-05-15 13:54:18 +02:00
else:
2020-05-28 15:03:13 +02:00
print("Błąd: Zły numer pola.")
2020-05-15 13:54:18 +02:00
2020-05-18 17:13:09 +02:00
# liczenie ilości prac do wykonania
2020-05-15 13:54:18 +02:00
def class_counts(rows):
counts = {}
for row in rows:
label = row[-1]
if label not in counts:
counts[label] = 0
counts[label] += 1
return counts
2020-05-18 17:13:09 +02:00
# sprawdzenie czy wartość jest liczbą
2020-05-15 13:54:18 +02:00
def is_numeric(value):
return isinstance(value, int) or isinstance(value, float)
2020-05-18 17:13:09 +02:00
# klasa tworząca zapytanie do podziału danych
2020-05-15 13:54:18 +02:00
class Question():
def __init__(self, column, value):
self.column = column
self.value = value
def match(self, example):
val = example[self.column]
if is_numeric(val):
2020-05-28 15:03:13 +02:00
return val >= self.value
else:
2020-05-15 13:54:18 +02:00
return val == self.value
2020-05-18 17:13:09 +02:00
# wyświetlenie pytania
2020-05-15 13:54:18 +02:00
def __repr__(self):
if is_numeric(self.value):
condition = "=="
2020-05-28 15:03:13 +02:00
return "Czy %s %s %s?" % (
2020-05-15 13:54:18 +02:00
header[self.column], condition, str(self.value)
)
2020-05-18 17:13:09 +02:00
# podział danych na spełnione i niespełnione wiersze
2020-05-15 13:54:18 +02:00
def partition(rows, question):
true_rows, false_rows = [], []
for row in rows:
if question.match(row):
true_rows.append(row)
else:
false_rows.append(row)
return true_rows, false_rows
2020-05-18 17:13:09 +02:00
# funkcja implementująca indeks gini
2020-05-15 13:54:18 +02:00
def gini(rows):
counts = class_counts(rows)
impurity = 1
2020-05-28 15:03:13 +02:00
for label in counts:
prob_of_label = counts[label] / float(len(rows))
impurity -= prob_of_label ** 2
2020-05-15 13:54:18 +02:00
return impurity
2020-05-28 15:03:13 +02:00
def info_gain(true, false, current_uncertainty):
p = float(len(true)) / (len(true) + len(false))
return current_uncertainty - p * gini(true) - (1 - p) * gini(false)
2020-05-15 13:54:18 +02:00
2020-05-18 17:13:09 +02:00
# znalezienie najlepszego "miejsca" na podział danych
2020-05-15 13:54:18 +02:00
def find_best_split(rows):
best_gain = 0
best_question = None
current_uncertainty = gini(rows)
n_features = len(rows[0]) - 1
for col in range(n_features):
values = set([row[col] for row in rows])
for val in values:
question = Question(col, val)
true_rows, false_rows = partition(rows, question)
if len(true_rows) == 0 or len(false_rows) == 0:
continue
2020-05-18 17:13:09 +02:00
gain = info_gain(true_rows, false_rows, current_uncertainty)
2020-05-15 13:54:18 +02:00
if gain >= best_gain:
best_gain, best_question = gain, question
return best_gain, best_question
class Leaf:
def __init__(self, rows):
self.predictions = class_counts(rows)
class DecisionNode:
def __init__(self, question, true_branch, false_branch):
self.question = question
self.true_branch = true_branch
self.false_branch = false_branch
2020-05-18 17:13:09 +02:00
# funkcja budująca drzewo
2020-05-15 13:54:18 +02:00
def build_tree(rows):
gain, question = find_best_split(rows)
if gain == 0:
return Leaf(rows)
true_rows, false_rows = partition(rows, question)
true_branch = build_tree(true_rows)
false_branch = build_tree(false_rows)
return DecisionNode(question, true_branch, false_branch)
2020-05-28 15:03:13 +02:00
# funkcja wypisująca drzewo
2020-05-15 13:54:18 +02:00
def print_tree(node, spacing=""):
if isinstance(node, Leaf):
2020-05-28 15:03:13 +02:00
print(spacing + "Przewidywana czynność:", node.predictions)
2020-05-15 13:54:18 +02:00
return
print(spacing + str(node.question))
2020-05-28 15:03:13 +02:00
print(spacing + '--> Prawda: ')
2020-05-15 13:54:18 +02:00
print_tree(node.true_branch, spacing + " ")
2020-05-28 15:03:13 +02:00
print(spacing + '--> Fałsz: ')
2020-05-15 13:54:18 +02:00
print_tree(node.false_branch, spacing + " ")
2020-05-28 15:03:13 +02:00
def classify(field, node):
if isinstance(node, Leaf):
return node.predictions
if node.question.match(field):
return classify(field, node.true_branch)
else:
return classify(field, node.false_branch)
def print_leaf(counts):
total = sum(counts.values()) * 1.0
probs = {}
for label in counts.keys():
probs[label] = str(int(counts[label] / total * 100)) + "%"
return probs
2020-05-15 14:03:52 +02:00
class main():
2020-05-18 17:13:09 +02:00
def __init__(self, traktor, field, ui, path):
self.traktor = traktor
self.field = field
self.ui = ui
self.path = path
2020-05-17 20:24:15 +02:00
self.best_action = 0
2020-05-18 17:13:09 +02:00
2020-05-28 15:03:13 +02:00
# tworzymy zbior uczacy, w ktorym podajemy wszystkie mozliwe pola i czynnosci
training_data = [[0, 0, 1, 0, "Zasadzic"],
[0, 1, 1, 0, "Odchwascic"],
[0, 0, 0, 0, "Podlac"],
[0, 1, 0, 0, "Odchwascic"],
#[1, 0, 1, 0, "Zasadzic"],
#[1, 1, 1, 0, "Odchwascic"],
[1, 0, 0, 0, "Czekac"],
#[1, 1, 0, 0, "Odchwascic"],
[0, 0, 0, 1, "Zebrac"]]
self.tree = build_tree(training_data)
print_tree(self.tree)
print("------------------")
print("TEST:")
# for i in range(len(training_data)):
# print("Przewidziania czynnosc: %s Czynnosc: %s"
# % (print_leaf(classify(translate(i), self.tree)), training_data[i][-1]))
# if training_data[i][-1] in self.work_field(classify(translate(i), self.tree)):
# continue
# else:
# print("Testowanie zakonczone niepowodzeniem")
# break
print("Przewidziania czynnosc: %s Czynnosc: Zasadzic"
% print_leaf(classify(translate(4), self.tree)))
print("Przewidziania czynnosc: %s Czynnosc: Odchwascic"
% print_leaf(classify(translate(5), self.tree)))
print("Przewidziania czynnosc: %s Czynnosc: Odchwascic"
% print_leaf(classify(translate(7), self.tree)))
2020-05-17 20:24:15 +02:00
def main(self):
2020-05-28 15:03:13 +02:00
for action in order:
self.traktor.set_mode(action)
self.search_field()
2020-05-17 20:24:15 +02:00
print("Koniec roboty")
2020-05-15 13:54:18 +02:00
2020-05-28 15:03:13 +02:00
def work_field(self, labels):
works = []
for label in labels:
if labels[label] > 0:
works.append(label)
return works
def search_field(self):
2020-05-17 20:24:15 +02:00
matrix = self.field.get_matrix()
2020-05-28 15:03:13 +02:00
for i in range(len(matrix)):
for j in range(len(matrix[i])):
print("Pole (%d,%d) Przewidziania czynnosc: %s"
% (i, j, print_leaf(classify(translate(matrix[i][j]), self.tree))))
if work[self.traktor.get_mode()] in self.work_field(classify(translate(matrix[i][j]), self.tree)):
print("Zgodna z aktualnym trybem, czynnosc wykonywana")
self.path.find_path(self.traktor, self.field, self.ui, [j, i])
self.ui.update()
time.sleep(0.5)