diff --git a/chapter9/dijkstra1.png b/chapter9/dijkstra1.png new file mode 100644 index 0000000..fb7c39e Binary files /dev/null and b/chapter9/dijkstra1.png differ diff --git a/chapter9/dijkstra2.png b/chapter9/dijkstra2.png new file mode 100644 index 0000000..f310167 Binary files /dev/null and b/chapter9/dijkstra2.png differ diff --git a/chapter9/dijkstra3.png b/chapter9/dijkstra3.png new file mode 100644 index 0000000..b4a19d9 Binary files /dev/null and b/chapter9/dijkstra3.png differ diff --git a/chapter9/ex171a.py b/chapter9/ex171a.py new file mode 100644 index 0000000..444b25a --- /dev/null +++ b/chapter9/ex171a.py @@ -0,0 +1,73 @@ +import logging +import math + +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__name__) + +graph = {} +graph["start"] = {} +graph["start"]["a"] = 5 +graph["start"]["b"] = 2 +graph["a"] = {} +graph["a"]["b"] = 8 +graph["a"]["c"] = 4 +graph["a"]["d"] = 2 +graph["b"] = {} +graph["b"]["a"] = 8 +graph["b"]["d"] = 7 +graph["c"] = {} +graph["c"]["d"] = 6 +graph["c"]["fin"] = 3 +graph["d"] = {} +graph["d"]["fin"] = 1 +graph["fin"] = {} + +costs = {} +costs["a"] = 5 +costs["b"] = 2 +costs["c"] = math.inf +costs["d"] = math.inf +costs["fin"] = math.inf + +parents = {} +parents["a"] = "start" +parents["b"] = "start" +parents["c"] = None +parents["d"] = None +parents["fin"] = None + +processed = set() + + +def find_lowest_cost_node(costs): + lowest_cost = math.inf + lowest_cost_node = None + for node in costs: + cost = costs[node] + if cost < lowest_cost and node not in processed: + lowest_cost = cost + lowest_cost_node = node + return lowest_cost_node + + +node = find_lowest_cost_node(costs) +while node is not None: + cost = costs[node] + neighbors = graph[node] + for n in neighbors.keys(): + new_cost = cost + neighbors[n] + if costs[n] > new_cost: + costs[n] = new_cost + parents[n] = node + processed.add(node) + node = find_lowest_cost_node(costs) + +print(f"lowest cost route: {costs['fin']}") +route = [] +next = "fin" +while next != "start": + route.append(next) + next = parents[next] +route.append("start") + +print(f"route: {list(reversed(route))}") diff --git a/chapter9/ex171b.py b/chapter9/ex171b.py new file mode 100644 index 0000000..6c7bcb2 --- /dev/null +++ b/chapter9/ex171b.py @@ -0,0 +1,58 @@ +import logging +import math + +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__name__) + +graph = {} +graph["start"] = {} +graph["start"]["a"] = 10 +graph["a"] = {} +graph["a"]["c"] = 20 +graph["b"] = {} +graph["b"]["a"] = 1 +graph["b"]["c"] = 1 +graph["c"] = {} +graph["c"]["b"] = 1 +graph["c"]["fin"] = 30 +graph["fin"] = {} + +costs = {} +costs["a"] = 10 +costs["b"] = math.inf +costs["c"] = math.inf +costs["fin"] = math.inf + +parents = {} +parents["a"] = "start" +parents["b"] = None +parents["c"] = None +parents["fin"] = None + +processed = set() + + +def find_lowest_cost_node(costs): + lowest_cost = math.inf + lowest_cost_node = None + for node in costs: + cost = costs[node] + if cost < lowest_cost and node not in processed: + lowest_cost = cost + lowest_cost_node = node + return lowest_cost_node + + +node = find_lowest_cost_node(costs) +while node is not None: + cost = costs[node] + neighbors = graph[node] + for n in neighbors.keys(): + new_cost = cost + neighbors[n] + if costs[n] > new_cost: + costs[n] = new_cost + parents[n] = node + processed.add(node) + node = find_lowest_cost_node(costs) + +print(f"lowest cost route: {costs['fin']}") diff --git a/chapter9/ex171c.py b/chapter9/ex171c.py new file mode 100644 index 0000000..74e3cba --- /dev/null +++ b/chapter9/ex171c.py @@ -0,0 +1,59 @@ +import logging +import math + +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__name__) + +graph = {} +graph["start"] = {} +graph["start"]["a"] = 2 +graph["start"]["b"] = 2 +graph["a"] = {} +graph["a"]["b"] = 2 +graph["b"] = {} +graph["b"]["c"] = 2 +graph["b"]["fin"] = 2 +graph["c"] = {} +graph["c"]["fin"] = 2 +graph["fin"] = {} + + +costs = {} +costs["a"] = 2 +costs["b"] = 2 +costs["c"] = math.inf +costs["fin"] = math.inf + +parents = {} +parents["a"] = "start" +parents["b"] = "start" +parents["c"] = None +parents["fin"] = None + +processed = set() + + +def find_lowest_cost_node(costs): + lowest_cost = math.inf + lowest_cost_node = None + for node in costs: + cost = costs[node] + if cost < lowest_cost and node not in processed: + lowest_cost = cost + lowest_cost_node = node + return lowest_cost_node + + +node = find_lowest_cost_node(costs) +while node is not None: + cost = costs[node] + neighbors = graph[node] + for n in neighbors.keys(): + new_cost = cost + neighbors[n] + if costs[n] > new_cost: + costs[n] = new_cost + parents[n] = node + processed.add(node) + node = find_lowest_cost_node(costs) + +print(f"lowest cost route: {costs['fin']}") diff --git a/chapter9/examples/heaptest.py b/chapter9/examples/heaptest.py new file mode 100644 index 0000000..9af2fb5 --- /dev/null +++ b/chapter9/examples/heaptest.py @@ -0,0 +1,10 @@ +import heapq + +customers = [] +heapq.heappush(customers, (2, "Harry")) +heapq.heappush(customers, (3, "Charles")) +heapq.heappush(customers, (1, "Riya")) +heapq.heappush(customers, (4, "Stacy")) + +while customers: + print(heapq.heappop(customers)) diff --git a/chapter9/examples/list.py b/chapter9/examples/list.py new file mode 100644 index 0000000..0e04b1c --- /dev/null +++ b/chapter9/examples/list.py @@ -0,0 +1,14 @@ +customers = [] +customers.append((2, "Harry")) # no sort needed here because 1 item. +customers.append((3, "Charles")) +customers.sort(reverse=True) +# Need to sort to maintain order +customers.append((1, "Riya")) +customers.sort(reverse=True) +# Need to sort to maintain order +customers.append((4, "Stacy")) +customers.sort(reverse=True) + +while customers: + print(customers.pop(0)) +# Will print names in the order: Stacy, Charles, Harry, Riya. diff --git a/chapter9/examples/priorityqueuetest.py b/chapter9/examples/priorityqueuetest.py new file mode 100644 index 0000000..4c48746 --- /dev/null +++ b/chapter9/examples/priorityqueuetest.py @@ -0,0 +1,12 @@ +from queue import PriorityQueue + +customers = ( + PriorityQueue() +) # we initialise the PQ class instead of using a function to operate upon a list. +customers.put((2, "Harry")) +customers.put((3, "Charles")) +customers.put((1, "Riya")) +customers.put((4, "Stacy")) + +while customers: + print(customers.get()) diff --git a/chapter9/rama.py b/chapter9/rama.py new file mode 100644 index 0000000..ba9abf2 --- /dev/null +++ b/chapter9/rama.py @@ -0,0 +1,78 @@ +import logging +import math + +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__name__) + + +### setup the graph + +graph = {} +graph["start"] = {} +graph["start"]["a"] = 6 +graph["start"]["b"] = 2 + +graph["a"] = {} +graph["a"]["fin"] = 1 + +graph["b"] = {} +graph["b"]["a"] = 3 +graph["b"]["fin"] = 5 + +graph["fin"] = {} + +### set up costs + +costs = {} +costs["a"] = 6 +costs["b"] = 2 +costs["fin"] = math.inf + +### setup parents + +parents = {} +parents["a"] = "start" +parents["b"] = "start" +parents["fin"] = None + +### our processed queue + +processed = set() + +### algorithm + + +def find_lowest_cost_node(costs): + lowest_cost = math.inf + lowest_cost_node = None + for node in costs: + cost = costs[node] + if cost < lowest_cost and node not in processed: + lowest_cost = cost + lowest_cost_node = node + return lowest_cost_node + + +node = find_lowest_cost_node(costs) # find lowest-cost node not already processed +while node is not None: + cost = costs[node] + neighbors = graph[node] + logger.debug(f"node: {node} cost: {cost} neighbor: {neighbors}") + for n in neighbors.keys(): + new_cost = cost + neighbors[n] + if costs[n] > new_cost: + costs[n] = new_cost + parents[n] = node + processed.add(node) + logger.debug(f"processed: {processed}") + node = find_lowest_cost_node(costs) + + +route = [] +next = "fin" +while next != "start": + route.append(next) + next = parents[next] +route.append("start") + +print(f"route: {list(reversed(route))}")