Skip to content
Extraits de code Groupes Projets
Valider 7005e15f rédigé par Christophe-Leblanc's avatar Christophe-Leblanc
Parcourir les fichiers

Performance test for python version

parent b1b2f983
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Pipeline #30486 annulé
import random
import argparse
import warnings
import os
def create_random_graph(args):
nb_nodes = args.nodes
nb_links = args.links
random.seed(args.seed)
nodes = dict()
for _ in range(nb_links):
node_a = random.randint(0, nb_nodes - 1)
node_b = random.randint(0, nb_nodes - 1)
while node_b == node_a:
node_b = random.randint(0, nb_nodes - 1)
c_ab = random.randint(1, 10)
nodes.setdefault(node_a, list()).append((node_b, c_ab))
nodes.setdefault(node_b, list())
return nodes, nb_links
def ntf_parse(args):
with open(args.ntf) as fd:
data = fd.read().split("\n")
mapping = dict()
nodes = dict()
for line in data:
tab = line.split(" ")
node_a = tab[0]
node_b = tab[1]
node_a = mapping.setdefault(node_a, len(mapping))
node_b = mapping.setdefault(node_b, len(mapping))
c_ab = int(tab[2])
nodes.setdefault(node_a, list()).append((node_b, c_ab))
nodes.setdefault(node_b, list())
return nodes, len(data)
def to_header_file(nodes, nb_links, output):
# Check that the extension is correct.
_, file_extension = os.path.splitext(output)
if file_extension != ".h":
warnings.warn(
f'The extension of the output file is not ".h": {output}')
s = ""
# Create the array containing the links.
for node_id, neighs in nodes.items():
for (neigh_id, cost) in neighs:
s += f"\t{{{node_id}, {neigh_id}, {cost}}},\n"
s = s[:-2] + "\n"
with open(output, "w+") as fd:
content = f'#include <stdint.h>\n\n#define NB_NODES {len(nodes)}\n#define NB_LINKS {nb_links}\n\nint64_t links[NB_LINKS][3] = {{\n{s}}};'
fd.write(content)
def to_binary_file(nodes, nb_links, output):
nb_nodes = len(nodes)
with open(output, "wb+") as fd:
fd.write(nb_nodes.to_bytes(4, "big"))
fd.write(nb_links.to_bytes(4, "big"))
print(nodes)
for node in nodes:
for j, cost in nodes[node]:
print(node, j, cost)
fd.write(node.to_bytes(4, "big"))
fd.write(j.to_bytes(4, "big"))
fd.write(cost.to_bytes(4, "big", signed=True))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--ntf", type=str, default=None,
help="Parse an NTF file instead of creating a graph")
parser.add_argument("-o", "--output", type=str,
help="Output file", default="graph.bin")
parser.add_argument("-n", "--nodes", type=int,
help="Number of nodes. Unused if '--ntf'", default=5)
parser.add_argument("-l", "--links", type=int,
help="Number of links. Unused if '--ntf'", default=10)
parser.add_argument("-c", "--c-header", action="store_true",
help="Writes the graph as a C header file (.h) instead of a binary file")
parser.add_argument("-s", "--seed", type=int, help="Seed for random generation of the graph", default=42)
args = parser.parse_args()
if args.ntf:
graph, nb_links = ntf_parse(args)
else:
graph, nb_links = create_random_graph(args)
if args.c_header:
to_header_file(graph, nb_links, args.output)
else:
to_binary_file(graph, nb_links, args.output)
#include <stdint.h>
#define NB_NODES 5
#define NB_LINKS 10
int32_t LINKS[NB_LINKS][3] = {
{0, 1, 3},
{0, 2, 2},
{1, 2, 1},
{1, 3, -2},
{2, 3, 4},
{2, 4, 1},
{3, 4, 2},
{0, 3, 1},
{1, 4, 2},
{2, 0, -1}
};
graph.png

33,6 ko

import argparse
import struct
OKGREEN = '\033[92m'
FAIL = '\033[91m'
def verify_output(file):
with open(file, "rb") as fd:
# First 4 bytes should be the number of nodes.
data = fd.read(4)
nb_nodes, = struct.unpack(">l", data)
# The file should contain exactly nb_nodes entries.
for _ in range(nb_nodes):
# An entry is 4 + 4 + 8 + 4 + len(path) * 4 bytes.
data = fd.read(20)
# Index of the node, distance value, path length (number of hops).
source_idx, destination_idx, _cost, path_len = struct.unpack(">llql", data)
# The node index lies within the limits.
assert source_idx >= 0 and source_idx < nb_nodes, FAIL + f"The source idx does not have the correct format: {source_idx}"
assert destination_idx >= 0 and destination_idx < nb_nodes, FAIL + f"The destination idx does not have the correct format: {destination_idx}"
# The path len can be nul if there is no path.
# The shortest path cannot contain loops.
assert path_len >= 1 and path_len <= nb_nodes, FAIL + f"The path length is too long or nul: {path_len}"
if path_len > 0:
for i in range(path_len):
data = fd.read(4)
hop_idx, = struct.unpack(">l", data)
# Same... the node index lies within the limits.
assert hop_idx >= 0 and hop_idx < nb_nodes, FAIL + f"A hop of the path does not have the correct format {hop_idx}"
# The first node should be the source.
if i == 0:
assert hop_idx == source_idx, FAIL + f"The first node of the path is not the source: {hop_idx} (and source is {source_idx})"
# The last node should be the destination.
if i == path_len - 1:
assert hop_idx == destination_idx, FAIL + f"The first node of the path is not the destination: {hop_idx} (and destination is {destination_idx})"
# The file does not contain anymore bytes
assert fd.read() == b"", FAIL + "The file is not empty"
print(OKGREEN + "The file has the correct format!\nThis does not mean that it solves the shortest path problem, but at least it contains readable information...")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"file", type=str, help="Binary file generated by the project to inspect")
args = parser.parse_args()
verify_output(args.file)
import graphviz
import struct
import argparse
import os
def read_graph(filename):
with open(filename, "rb") as fd:
data = fd.read(8)
_, nb_links = struct.unpack(">ll", data)
graph = dict()
for _ in range(nb_links):
data = fd.read(12)
node_1, node_2, cost_12 = struct.unpack(">lll", data)
graph.setdefault(node_1, list()).append((node_2, cost_12))
return graph
def plot_graph(graph, output_filepath):
file, file_extension = os.path.splitext(output_filepath)
g = graphviz.Graph(format=file_extension[1:])
for node in graph:
for nei_id, cost in graph[node]:
g.node(f"{node}", label=f"{node}")
g.node(f"{nei_id}", label=f"{nei_id}")
g.edge(f"{node}", f"{nei_id}", label=f"{cost}", dir="forward")
g.render(file)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"file", type=str, help="Input file (binary) representing the graph")
parser.add_argument("save", type=str,
help="Save the graph visualization in the indicated path")
args = parser.parse_args()
graph = read_graph(args.file)
plot_graph(graph, args.save)
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter