I started with this inviting post.

]]>

“The mind is a wonderful thing. You start off on one journey but it decides to take you somewhere completely different. The path of least resistance is the way to go. Don’t fight it – enjoy the ride.”

David Alejandro Fearnhead

Following an introduction by my colleague Ben Cohen, I’ve continued studying Steven Wolfman’s presentation on graph theory with the aid of some other resources.

Here, we’ll consider the shortest path problem:

Given: A graph G with (positively) weighted edges

Find: the least costly path from nodes X to Y

For this problem, we’ll explore Dijkstra’s algorithmic solution. Note that an unweighed graph shortest path can be solved using a simple breadth first search. A more general, but less efficient Bellman-Ford algorithm offers a solution for graphs with negatively weighted edges. Also consider that the algorithm being presented is not suitable for graphs with negative cost cycles, which make cost of transversal arbitrarily small.

Our implementation of Dijkstra’s shortest path algorithm should execute with O(n^2) (more precisely, O(|v|log|v|+|e|))time complexity. However, a simpler topological sort provides an answer for directed acyclic graphs in linear time.

An implementation of this algorithm using Python’s NetworkX package is in the works.

reference: *Algorithm Design Manual*, Skiena (2010)

]]>

#include <stdio.h> #include <iostream> class stack{ int stack[100]; // allocate a maximum of 101 information slots int t= 0; //top of stack void push(int x){ stack[t]=x; t++; // add error exception for full stack }; int pop(){ return stack[t]; t--; // add error exception for empty stack } int length(){ return t; } int peek(){ //make sure this is what peek actually is supposed to do return stack[t-1]; //add out of bounds except } bool isEmpty(){ //better way to do this? backed myself into a corner? return t==-1 ; //fix }

As the comments indicate, I haven’t finished yet.

]]>

I decided to take a few hours today to learn some Julia. Julia is a fairly new language (2012) that has received a good deal of attention for its appeal to the scientific/data-science communities. A statement of motivation here.

Since my first two posts on C and Python implementations of linked lists, I’ve quickly taken note of the enormous time cost of thorough documentation of progress. For now, I’ll readjust to write less of all I learn/do and more on what’s notable. Also, I’ll keep a focus on the facts rather than introspection.

Spending some minutes reading about the language revealed some desirable properties:

- strong and transparent type system appeals to tastes developed while journeying through Haskell
- fairly clear syntax
- f!() notation for those functions which mutate their arguments
- type classification is a property of values, rather than variables
- the existence of BioJulia, which might be something cool to contribute to in the future

I’ll add more notes here as I continue reading about the language.

]]>

Implementing a Python linked list left me a bit unsatisfied. Does this data structure *really* qualify as a linked list, or is it some sort of analogue? In searching for an answer, I came across this definition of Linked Lists from Wikipedia:

In computer science, a linked list is a data structure that consists of a sequence of data records such that in each record there is a field that contains a reference (i.e., a link) to the next record in the sequence.

While pointers don’t seem to be an explicit requirement, studying a proper linked list in C/C++ seems like a good learning exercise.

Here’s a C++ linked list I came across surfing the web for a simple implementation, annotated piecewise:

#include <iostream>; using namespace std; class LinkedList{ struct Node { int x; Node *next;</pre> };

Within the template for a linked list, a structure called node is defined first. Node, representing a single entry in the list, contains two bins, a value and a pointer referencing the next entry.

The Linked List class continues:

public: LinkedList(){ head = NULL; }

A value constructor sets the head value to NULL. Any instance of our linked list class starts its life an empty, with the head space set to NULL.

void addValue(int val){ Node *n = new Node(); n->x = val; n->next = head; head = n; }

To this empty list we use a method called addValue to chain items. This method evokes a new instance of the node structure, to which the argument value is passed as the node’s value. Next of this node points to the current head, which for a new linked list function is simply NULL. This new node then is designated as the new head.

int popValue(){ Node *n = head; int ret = n->x; head = head->next; delete n; return ret; }

This next method allows us to reverse the effect of the previous prepending addValue function. ret is assigned the value of the current head node’s x. Then, head is reassigned as the current next value. Now that the old next cell is set to the head of the list, it is now safe to delete the previous head node and return its x value.

private: Node *head; };

_

]]>

Today, I’ll implement the first of several elementary data structures in Python– linked lists. The goal here is not to create anything novel or efficient, but rather to master foundational building blocks for my future incursions into Data Structures and Algorithms. This approach follows the advice provided in the introduction of T*he Little Schemer*. The author uses the example of his college photography course to point out that ritualization of less glamorous technical knowledge is prerequisite to true creativity in a craft like programming.

I’ll start by consulting several familiar resources to understand the details of singly linked lists, which I’ll refer to from this point simply as linked lists. To my understanding, a linked list allows for the storage of a linear array of items (nodes). A reference to the address of the next node follows each item. The nodes need not be physically ordered in memory. Ordering is not relevant in tracing the path of items in the array. This property makes linked lists easier to modify than co-located arrays (e.g., C arrays). At the same time, accessing item at index *i *of a linked list may require O(n) time because the items preceding item *i* must be accessed sequentially to find item *i *(compared to constant time for a linear pre-set array).

This diagram from Stanford’s CS Library does a great job illustrating the linked list concept:

The figure above can be traced as follows. The stack and heap distinction will be disregarded in this Python implementation, since no actual pointers will be used (more on this choice later). The array reads linearly: First, a pointer at the head directs the observer towards the first element of the list. The observer sees the value, which here is an integer of value 1 at the first node. The memory slot immediately following the integer value indicates the location of the next element. At this element node, another value/pointer pair will be found. This pattern continues recursively until the last node’s pointer field contains a null character, at which point the observer understands that the reading is terminated.

Following the advice of a friend, I decided to embrace Python’s strengths and limitations as a high-level interpreted language, specifically with regards to object-oriented support and lack of pointer access. My list is implemented as an interaction between two generic objects, a node and a wrapper for the head node. These roughly correspond to the head (shown on the heap side) and the three node instances (stack side) shown in the diagram, although, again, the concepts of stack and heap have no place in my design.

Here’s the first class, Node:

class Node: ''' element of linked list with tail as reference to next element''' def __init__(self, head, tail=None): self.head = head #node content self.tail = tail #simulates pointer, reference to next item

I will assume the reader is familiar with the details of class implementation in Python. Each instance of node serves as an element of the linked list. This nuclear data structure *knows* only of its immediate sequential successor by means of tail reference. That is, the linked list is implemented in manner that makes each node unaware of any other node in the world but that node referenced at its tail address. No pointer support is allowed, so this node is simply an abstraction– one that holds a value and a reference to the next item. The tail is by default set to “None”, simulating what would be a NULL character in the C implementation.

What follows is a piecewise overview of the linked list object, with which the client interfaces.

class LinkedList: def __init__(self,firstNode=None): self.firstNode = firstNode

The linked list starts life as a reference to None, the Python equivalent to C’s NULL. If this remains the case, the following method, isEmpty(), will evaluate to True.

def isEmpty(self): if (self.firstNode == None): return True else: return False

Head resembles the Haskell function, returning the value of the leading entry of the list:

def head(self): return self.firstNode

On the other hand, a tail function, returns xs for x:xs. That is, all elements following the first are returned.

def tail(self): ''' returns xs for x:xs''' if (self.isEmpty()): return None else: return LinkedList(self.firstNode.tail) def last(self): #does this work? '''recursively yields the list node of the linked list''' if self.firstNode.tail == None: return firstNode else: return self.tail def cons(self,newFirstNode): '''perlim: replaces head with new head''' #assert type(newFirstNode) == Node instance newFirstNode.tail = self.firstNode self.firstNode = newFirstNode return None def push(self): pass ''' release first element''' handle = self.firstNode #check propriety of term self.firstNode = self.firstNode.tail return handle def length(self): pass '''recursively find length of link list''' if (self.firstNode.tail == None): 1 else: 1 + length(self)

]]>