Skip to content

Commit

Permalink
add graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
RafaelGoncalvesUA committed Dec 9, 2022
1 parent a95126e commit a0affda
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,5 @@ dmypy.json

run.sh
benchmarks/
tree_search_legacy.py
tree_search_legacy.py
.vscode/
198 changes: 188 additions & 10 deletions graph.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import matplotlib.pyplot as plt
import numpy as np
import os

def linear_graph(filename, type_):
x = []
Expand All @@ -25,6 +27,89 @@ def bar_graph(filename):
y.append(int(line[1]))
return x, y

def plot_linear_regression(xlist, ylist, labels):
for i in range(len(xlist)):
x = xlist[i]
y = ylist[i]
m, b = np.polyfit(x, y, 1)
plt.plot(x, [m * i + b for i in x], label=labels[i])

def show_graphs(LEVELS_PACK):
# Gráfico com retas x = nível, y = tempo de execução, para cada strategy
x1, y1 = linear_graph(f"benchmarks/{LEVELS_PACK}/depth.csv", "time")
x2, y2 = linear_graph(f"benchmarks/{LEVELS_PACK}/breadth.csv", "time")
x3, y3 = linear_graph(f"benchmarks/{LEVELS_PACK}/uniform.csv", "time")
x4, y4 = linear_graph(f"benchmarks/{LEVELS_PACK}/greedy.csv", "time")
x5, y5 = linear_graph(f"benchmarks/{LEVELS_PACK}/a*.csv", "time")

plot_linear_regression([x1, x2, x3, x4, x5], [y1, y2, y3, y4, y5], ["Depth", "Breadth", "Uniform", "Greedy", "A*"])

if len(x1) < 20:
plt.xticks(np.arange(min(x1), max(x1) + 1, 1.0))

axes = plt.gca()
axes.set_xlim([0, None])
axes.set_ylim([0, None])
plt.xlabel("Level")
plt.ylabel("Time (s)")
plt.title(f"Linear regression of time per level ({LEVELS_PACK})")
plt.legend()
plt.savefig(f"graphs/{LEVELS_PACK}/time_graph.png")
plt.show()

# Gráfico com retas x = nível, y = número de nós expandidos, para cada strategy
x1, y1 = linear_graph(f"benchmarks/{LEVELS_PACK}/depth.csv", "nodes")
x2, y2 = linear_graph(f"benchmarks/{LEVELS_PACK}/breadth.csv", "nodes")
x3, y3 = linear_graph(f"benchmarks/{LEVELS_PACK}/uniform.csv", "nodes")
x4, y4 = linear_graph(f"benchmarks/{LEVELS_PACK}/greedy.csv", "nodes")
x5, y5 = linear_graph(f"benchmarks/{LEVELS_PACK}/a*.csv", "nodes")

plot_linear_regression([x1, x2, x3, x4, x5], [y1, y2, y3, y4, y5], ["Depth", "Breadth", "Uniform", "Greedy", "A*"])

if len(x1) < 20:
plt.xticks(np.arange(min(x1), max(x1) + 1, 1.0))

axes = plt.gca()
axes.set_xlim([0, None])
axes.set_ylim([0, None])
plt.xlabel("Level")
plt.ylabel("Number of expanded nodes")
plt.title(f"Linear regression of number of expanded nodes per level ({LEVELS_PACK})")
plt.legend()
plt.savefig(f"graphs/{LEVELS_PACK}/nodes_graph.png")
plt.show()

# Gráfico com retas x = nível, y = número de peças movidas, para cada strategy
x1, y1 = linear_graph(f"benchmarks/{LEVELS_PACK}/depth.csv", "moves")
x2, y2 = linear_graph(f"benchmarks/{LEVELS_PACK}/breadth.csv", "moves")
x3, y3 = linear_graph(f"benchmarks/{LEVELS_PACK}/uniform.csv", "moves")
x4, y4 = linear_graph(f"benchmarks/{LEVELS_PACK}/greedy.csv", "moves")
x5, y5 = linear_graph(f"benchmarks/{LEVELS_PACK}/a*.csv", "moves")

plot_linear_regression([x1, x2, x3, x4, x5], [y1, y2, y3, y4, y5], ["Depth", "Breadth", "Uniform", "Greedy", "A*"])

if len(x1) < 20:
plt.xticks(np.arange(min(x1), max(x1) + 1, 1.0))

axes = plt.gca()
axes.set_xlim([0, None])
axes.set_ylim([0, None])
plt.xlabel("Level")
plt.ylabel("Number of moved pieces")
plt.title(f"Linear regression of number of moved pieces per level ({LEVELS_PACK})")
plt.legend()
plt.savefig(f"graphs/{LEVELS_PACK}/moves_graph.png")
plt.show()

if not os.path.exists("graphs"):
os.mkdir("graphs")
if not os.path.exists("graphs/levels1"):
os.mkdir("graphs/levels1")
if not os.path.exists("graphs/levels2"):
os.mkdir("graphs/levels2")
if not os.path.exists("graphs/levels"):
os.mkdir("graphs/levels")

"""
levels1.txt: pack de níveis 6x6 da entrega preliminar
1) Breadth 488 640
Expand All @@ -33,10 +118,20 @@ def bar_graph(filename):
4) A* 489 576
"""

# Gráfico com retas x = nível, y = tempo de execução, para cada strategy
# Gráfico com retas x = nível, y = número de nós expandidos, para cada strategy
# Gráfico com retas x = nível, y = número de peças movidas, para cada strategy
show_graphs("levels1")

# Gráfico de barras x = strategy, y = pontos
x = ["Breadth", "Uniform", "Greedy", "A*"]
y = [488640, 489739, 487299, 489576]

plt.bar(x, y, color=["orange", "green", "red", "purple"])
plt.bar_label(plt.gca().containers[0], padding=3)
plt.xlabel("Strategy")
plt.ylabel("Points")
plt.title("Points per strategy (levels1)")
plt.ylim(487000, 490000)
plt.savefig("graphs/levels1/points_graph.png")
plt.show()

"""
levels2.txt: pack de níveis 8x8
Expand All @@ -46,10 +141,21 @@ def bar_graph(filename):
4) A* 1 039 496
"""

# Gráfico com retas x = nível, y = tempo de execução, para cada strategy
# Gráfico com retas x = nível, y = número de nós expandidos, para cada strategy
# Gráfico com retas x = nível, y = número de peças movidas, para cada strategy
# Gráfico de barras x = strategy, y = pontos
show_graphs("levels2")

# Gráfico de barras x = strategy, y = pontos
x = ["Breadth", "Uniform", "Greedy", "A*"]
y = [1041039, 1040375, 1041987, 1039496]

plt.bar(x, y, color=["orange", "green", "red", "purple"])
plt.bar_label(plt.gca().containers[0], padding=3, fmt="%d")
plt.xlabel("Strategy")
plt.ylabel("Points")
plt.title("Points per strategy (levels2)")
plt.ylim(1039000, 1043000)
plt.ticklabel_format(style='plain', axis='y')
plt.savefig("graphs/levels2/points_graph.png")
plt.show()

"""
levels.txt: pack definitivo para a entrega final
Expand All @@ -60,7 +166,79 @@ def bar_graph(filename):
5) Híbrido (Uniform para 6x6 + Greedy para 8x8) 1 558 015
"""

# Gráfico com retas x = nível, y = tempo de execução, para cada strategy
# Gráfico com retas x = nível, y = número de nós expandidos, para cada strategy
# Gráfico com retas x = nível, y = número de peças movidas, para cada strategy
# # Gráfico com retas x = nível, y = tempo de execução, para cada strategy
# x1, y1 = linear_graph(f"benchmarks/levels/depth.csv", "time")
# x2, y2 = linear_graph(f"benchmarks/levels/breadth.csv", "time")
# x3, y3 = linear_graph(f"benchmarks/levels/uniform.csv", "time")
# x4, y4 = linear_graph(f"benchmarks/levels/greedy.csv", "time")
# x5, y5 = linear_graph(f"benchmarks/levels/a*.csv", "time")
# x6, y6 = linear_graph(f"benchmarks/levels/hybrid.csv", "time")

# plt.plot(x1, y1, label="Depth", color="orange")
# plt.plot(x2, y2, label="Breadth", color="green")
# plt.plot(x3, y3, label="Uniform", color="red")
# plt.plot(x4, y4, label="Greedy", color="purple")
# plt.plot(x5, y5, label="A*", color="blue")

# plt.xlabel("Level")
# plt.ylabel("Time (s)")
# plt.title("Time per level (levels)")
# plt.legend()
# #plt.show()

# # Gráfico com retas x = nível, y = número de nós expandidos, para cada strategy
# x1, y1 = linear_graph(f"benchmarks/levels/depth.csv", "nodes")
# x2, y2 = linear_graph(f"benchmarks/levels/breadth.csv", "nodes")
# x3, y3 = linear_graph(f"benchmarks/levels/uniform.csv", "nodes")
# x4, y4 = linear_graph(f"benchmarks/levels/greedy.csv", "nodes")
# x5, y5 = linear_graph(f"benchmarks/levels/a*.csv", "nodes")
# x6, y6 = linear_graph(f"benchmarks/levels/hybrid.csv", "nodes")

# plt.plot(x1, y1, label="Depth", color="orange")
# plt.plot(x2, y2, label="Breadth", color="green")
# plt.plot(x3, y3, label="Uniform", color="red")
# plt.plot(x4, y4, label="Greedy", color="purple")
# plt.plot(x5, y5, label="A*", color="blue")
# plt.plot(x6, y6, label="Hybrid", color="black")

# plt.xlabel("Level")
# plt.ylabel("Number of expanded nodes")
# plt.title("Expanded nodes per level (levels)")
# plt.legend()
# #plt.show()

# # Gráfico com retas x = nível, y = número de peças movidas, para cada strategy
# x1, y1 = linear_graph(f"benchmarks/levels/depth.csv", "moves")
# x2, y2 = linear_graph(f"benchmarks/levels/breadth.csv", "moves")
# x3, y3 = linear_graph(f"benchmarks/levels/uniform.csv", "moves")
# x4, y4 = linear_graph(f"benchmarks/levels/greedy.csv", "moves")
# x5, y5 = linear_graph(f"benchmarks/levels/a*.csv", "moves")
# x6, y6 = linear_graph(f"benchmarks/levels/hybrid.csv", "moves")

# plt.plot(x1, y1, label="Depth", color="orange")
# plt.plot(x2, y2, label="Breadth", color="green")
# plt.plot(x3, y3, label="Uniform", color="red")
# plt.plot(x4, y4, label="Greedy", color="purple")
# plt.plot(x5, y5, label="A*", color="blue")
# plt.plot(x6, y6, label="Hybrid", color="black")

# plt.xlabel("Level")
# plt.ylabel("Number of moved pieces")
# plt.title("Moved pieces per level (levels)")
# plt.legend()
# #plt.show()

# Gráfico de barras x = strategy, y = pontos

x = ["Breadth", "Uniform", "Greedy", "A*", "Hybrid"]
y = [1556748, 1557267, 1556135, 1556969, 1558015]

plt.bar(x, y, color=["orange", "green", "red", "purple", "blue"])
plt.bar_label(plt.gca().containers[0], padding=3, fmt="%d")
plt.xlabel("Strategy")
plt.ylabel("Points")
plt.title("Points per strategy (levels)")
plt.ylim(1555000, 1559000)
plt.ticklabel_format(style='plain', axis='y')
plt.savefig("graphs/levels/points_graph.png")
plt.show()
Binary file added graphs/levels/points_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/levels1/moves_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/levels1/nodes_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/levels1/points_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/levels1/time_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/levels2/moves_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/levels2/nodes_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/levels2/points_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphs/levels2/time_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions report.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Numa primeira fase do projeto, entendemos que deveríamos dividir o desenvolvime
- Numa primeira versão do search, a estrutura grid_visited era uma lista. Após discutirmos estratégias de otimização, com o grupo "102536_102778", concluímos que seria mais eficiente utilizar um conjunto (set), uma vez que a operação de verificação de pertença (lookup) apresenta uma complexidade O(1), enquanto que, nas listas, é O(n). Em versões posteriores, mantivemos esta estrutura. Contudo, há que salientar que a complexidade do lookup com chave, nos dicionários, é também O(1).
- Tendo por base conhecimentos prévios de Algoritmos e Estruturas de Dados, ponderámos a utilização de uma min-heap, como estrutura para guardar os nós por explorar. Para esse efeito, aproveitámos o módulo heapq, nativo do Python. Os resultados foram bastante positivos, dado que cada inserção garante a ordenação da heap, não sendo necessária qualquer operação ulterior, com vista a obter o valor mínimo. O critério de ordenação é definido pelo método **lt** da classe de objetos que compõem a heap, neste caso, a Matrix ou a MatrixForGreedy.

### HEURÍSTICA

### Agente

O agente em cada iteração sensoriza o jogo através das funções detectCrazy e detectStuck.
Expand Down
11 changes: 9 additions & 2 deletions tree_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ def __lt__(self, other):
return (self.heuristic, self.idx) < (other.heuristic, other.idx)

class MatrixForAStar(Matrix):
"""
Tree node with a puzzle state, for A* search.
Instances are firstly compared by total cost (heuristic + cost) and then, if necessary, by creation order.
"""

counter = 0

def __init__(self, grid, action=[], parent=None, cost=0, heuristic=0, cursor=[3, 3]):
super().__init__(grid, action, parent, cost, heuristic, cursor)
MatrixForAStar.counter += 1
Expand Down Expand Up @@ -341,7 +347,7 @@ def main():

LEVELS_PACKS = ["levels1", "levels2", "levels"]
STRATEGIES = ["depth", "breadth", "greedy", "uniform", "a*"]
SKIP_CONTEXTS = {("levels2", "a*"), ("levels", "a*")}
SKIP_CONTEXTS = {} # ex.: SKIP_CONTEXTS = [("levels2", "depth"")]

for LEVELS_PACK in LEVELS_PACKS:
with open(LEVELS_PACK + ".txt", "r") as f, open(f"benchmarks/{LEVELS_PACK}/hybrid.csv", "w") as fout:
Expand Down Expand Up @@ -405,6 +411,7 @@ def main():
result = f"{i},{time_},{t.expanded_nodes},{total_moves}"
fout.write(result + "\n")
print(f"{LEVELS_PACK} {STRATEGY} -> {total_time} seconds, {t.expanded_nodes} nodes expanded, {total_moves} moves")

print()

if __name__ == "__main__":
main()

0 comments on commit a0affda

Please sign in to comment.