How to Read Line From Txt as Matrix in Python
Last week I wrote how to represent graph structure as adjacency listing. This week time has come to describe how we tin can represent graphs in a a matrix representation.
Our requirements (the same as previous calendar week):
- small amount of code (we desire to code information technology fast on algorithmic contest)
- ability to alter our construction dynamically (nosotros want to add some edges or vertices after graph initialization)
- graph is undirected (for each two vertices there tin can be at virtually one border and edges don't have directions)
Graph as matrix in Python
Graph represented as a matrix is a structure which is usually represented by a \(2\)-dimensional assortment (tabular array) indexed with vertices. Value in cell described by row-vertex and column-vertex corresponds to an border. So for graph from this picture show:
nosotros can represent it by an assortment like this:
# jail cell | A | B | C | D |
---|---|---|---|---|
A | 0 | 1 | one | 1 |
B | 1 | 0 | 0 | 0 |
C | ane | 0 | 0 | one |
D | ane | 0 | ane | 0 |
For example \(cell[A][B] = one\), because at that place is an edge between \(A\) and \(B\), \(cell[B][D] = 0\), because there is no edge betwixt \(B\) and \(D\).
In C++ we tin can easily stand for such structure using \(2\)-dimensional arrays (std::vector
is better than regular array):
Of course then we accept to initialize every cell in our array:
In Python a list is an equivalent of an array. The about obvious implementation of a structure could look like this:
It seems in Python nosotros can initialize this structure in much shorter way (actually in one line - look at __init__
). For this implementation nosotros need \(O(|V| ^ two)\) memory, where \(|V|\) is number of vertices. Of course every bit graph is undirected we can skip one-half of this array, because we duplicate edge data, just I'm not going to cover it in this postal service, because for Python I've a better solution. And then, think about this question:
Is there a way to omit information about not existing edges?
And now think about dict
.
Using dict
for matrix graph implementation
Ok, so we want to store our graph-matrix in a dict
. As information technology'south a key-value store, we want to know what data to shop in keys and what value should they have. Every bit nosotros still want to be able to write something like this: graph[i][j]
to access an edge it becomes articulate that values are edges and equally keys we should accept pairs of vertices. And then allow's utilize tuple
of vertices as keys!
That'south information technology! When at that place is an edge between two vertices we will accept a not None
value otherwise None
. For sparse graphs we can relieve a lot of memory here, because we volition actually use \(|E| * 2\) where \(|E|\) is number of edges. Of course, we are unable to tell easily how many vertices our graph has (we have to check all keys). If nosotros demand this kind of data we can create a more sophisticated implementation:
Class DictGraph
derives from dict
, and so we still can use it equally dictionary, but we have too a list
of vertices. Now it'south easy to check if vertex is in our graph - it's enough that we check if it'due south in vertices
list.
Comparision of dict
and list
graph implementations
Adding a vertex
Let'due south meet how to add a vertex in both dict
and list
implementations mentioned above.
Adding a vertex in listing
implementation
To add a vertex \(v\) we demand to add to our matrix new cavalcade and new row. So nosotros take to iterate over all vertices lists and append \(v\) there (you can remember nigh it as adding a new column). Next nosotros have to create an array of vertices for \(5\) (adding a new row). Time complexity is \(O(|5|)\). We also need about \(2 * |V|\) space.
Calculation a vertex in dict
implementation
Hither we take to append a vertex \(v\) to vertices listing (if we use i, it's not necessary). Equally it doesn't take any edges with other vertices it doesn't require whatever activity. Necessary time: \(O(1)\) (worst case is \(O(|V|)\), space is \(O(ane)\).
Removing an border
In both implementation it's like shooting fish in a barrel:
Removing an edge in list
implementation
Just put \(0\) in both ends of border. Time \(O(ane)\). We don't save any space.
Removing an edge in dict
implementation
Here we can actually delete both ends of edge from dictionary. Time \(O(i)\), saving a piddling of space.
Removing a vertex
Removing a vertex is more complicated, especially in list
implementation.
Removing a vertex in listing
implementation
To remove vertex \(five\) nosotros take to remove its column and row in a table. So we have iterate over all vertices lists, remove vertex \(five\) from them (removing a column), finally remove whole list corresponding to this vertex (removing row). Time complexity is \(O(|Five|)\).
Removing a vertex in dict
implementation
To remove vertex \(v\) from dictionary graph we demand to remove all its edges, and so nosotros have to to cheque all keys (tuple
of two vertices) and if whatsoever of them has \(5\) remove it - it is removing an edge. After that we demand to remove \(5\) from vertices listing if we use it. Fourth dimension complexity is \(O(|E|)\), because we iterate over all edges, not vertices. Really for dense graphs it is worse than in listing
implementation.
Summing up
Information technology seems that except removing a vertex in dense graphs, dict
implementation of graph-matrix is much meliorate than list
implementation. It saves much more space, because information technology doesn't need to save information most non-existing edges. Also for me information technology's much more than readable, considering it allows usage of any kind of names for vertices - you can name them using numbers, letters, whatever you want (as long equally you don't add the same vertex twice, amend to check it before adding?). Dictionaries in Python are really powerful - they are implemented as hash tables that's mode it has actually adept time complexities for dictionary operations.
You can find code of both implementations and some tests as examples of usage here: gist. Hopefully y'all enjoyed reading about this approach for implementing graph structure. Let me know your thoughts or remarks in comments!
Source: https://vevurka.github.io/dsp17/python/cs/graph_in_python_matrix/
0 Response to "How to Read Line From Txt as Matrix in Python"
Post a Comment