commit
43ef16c103
@ -0,0 +1,107 @@ |
|||||||
|
from flask import Flask, jsonify, request, render_template |
||||||
|
import numpy as np |
||||||
|
|
||||||
|
app = Flask(__name__) |
||||||
|
|
||||||
|
|
||||||
|
class Graph(object): |
||||||
|
nodes = set() # set of strings |
||||||
|
edges = dict() # (string,string) -> float |
||||||
|
|
||||||
|
|
||||||
|
def bellmann_ford(graph, node_a, node_b): |
||||||
|
"""Calculate distance from node_a to node_b assuming no negative cycles.""" |
||||||
|
# weights |
||||||
|
from_a_to = {**[(node, np.inf) for node in graph.nodes]} |
||||||
|
from_a_to[node_a] = 0 |
||||||
|
# save path so we dont have to backtrace later |
||||||
|
path_from_a_to = {**[(node, []) for node in graph.nodes]} |
||||||
|
path_from_a_to[node_a] = [node_a] |
||||||
|
|
||||||
|
for i in range(len(graph.nodes)-1): |
||||||
|
for e in graph.edges: |
||||||
|
# because edges are not directed |
||||||
|
for (x,y) in [e,e[::-1]]: |
||||||
|
if from_a_to[x] + graph.edges[(x,y)] < from_a_to[y]: |
||||||
|
path_from_a_to[y] = path_from_a_to + [y] |
||||||
|
from_a_to[y] = from_a_to[x] + graph.edges[(x,y)] |
||||||
|
|
||||||
|
return path_from_a_to[node_b] |
||||||
|
|
||||||
|
|
||||||
|
graph = Graph() |
||||||
|
|
||||||
|
|
||||||
|
def error(message): |
||||||
|
return jsonify({"error": message}) |
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/nodes', methods=['GET']) |
||||||
|
def get_nodes(): |
||||||
|
return jsonify({'nodes': graph.nodes}) |
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/edges', methods=['GET']) |
||||||
|
def get_edges(): |
||||||
|
return jsonify({'edges': graph.edges}) |
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/nodes', methods=['POST']) |
||||||
|
def create_node(): |
||||||
|
if not request.json: |
||||||
|
return error("Request needs to be JSON."), 400 |
||||||
|
if 'name' not in request.json: |
||||||
|
return error("Name must be set."), 400 |
||||||
|
|
||||||
|
name = request.json['name'] |
||||||
|
if name == "": |
||||||
|
return error("Name cannot be empty."), 400 |
||||||
|
if name in graph.nodes: |
||||||
|
return error(f'Node with name "{name}" already exist.'), 400 |
||||||
|
|
||||||
|
graph.nodes.add(name) |
||||||
|
return jsonify(name), 201 |
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/edges', methods=['POST']) |
||||||
|
def create_edge(): |
||||||
|
if not request.json: |
||||||
|
return error("Request needs to be JSON."), 400 |
||||||
|
if 'start' not in request.json: |
||||||
|
return error("Start node must be set."), 400 |
||||||
|
if 'end' not in request.json: |
||||||
|
return error("End node must be set."), 400 |
||||||
|
if 'weight' not in request.json: |
||||||
|
return error("Edge weight must be set."), 400 |
||||||
|
|
||||||
|
start = request.json['start'] |
||||||
|
end = request.json['end'] |
||||||
|
weight = request.json['weight'] |
||||||
|
if weight < 0: |
||||||
|
return error("Weight must be positive."), 400 |
||||||
|
if start == end: |
||||||
|
return error("Start and end node must be different."), 400 |
||||||
|
if start not in graph.nodes: |
||||||
|
return error("Start node does not exist."), 400 |
||||||
|
if end not in graph.nodes: |
||||||
|
return error("End node does not exist."), 400 |
||||||
|
if (start,end) in graph.edges or (end,start) in graph.edges: |
||||||
|
return error("Edge exists already."), 400 |
||||||
|
try: |
||||||
|
weight = float(weight) |
||||||
|
except ValueError: |
||||||
|
return error("Weight must be a number."), 400 |
||||||
|
|
||||||
|
edge = {(start,end): weight} |
||||||
|
graph.edges[(start,end)] = weight |
||||||
|
|
||||||
|
return jsonify(edge), 201 |
||||||
|
|
||||||
|
|
||||||
|
@app.route("/") |
||||||
|
def index(): |
||||||
|
return render_template("index.html", nodes=graph.nodes, edges=graph.edges) |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
app.run(host="127.0.0.1", debug=True, port=5000) |
@ -0,0 +1,13 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="de" dir="ltr"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>Assignment</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<p><b>nodes:</b> {{ nodes }}</p> |
||||||
|
<p><b>edges:</b> {{ edges }}</p> |
||||||
|
<div ></div> |
||||||
|
<script src="{{ url_for('static', filename='js/canvas.js')}}"></script> |
||||||
|
</body> |
||||||
|
</html> |
Loading…
Reference in new issue