#adjacency list representation of directed graph
Explore tagged Tumblr posts
Text
An adjacency list in a graph is a series of numbers that tells you how many nodes are adjacent to each node. So if you imagine a 3x3 square of rooms that all connect with a door in the center of each wall, the corner rooms would have a value of 2 (the side rooms adjacent to them), the side rooms would have a value of 3 (the adjacent corner rooms and the center), and the center would have a value of 4 (being adjacent to all 4 side rooms).
An adjacency matrix for a graph is possibly more confusing, depending on how your brain works, but defaults to containing more info and has faster lookups in terms of computer processing. It would represent those 9 rooms as a 9x9 grid and mark each door you could go out of as a 1 instead of a 0. So
becomes
And you can see it's symmetrical (split down the line of Xs), because you can go through a door either direction. If these were streets in a city and the street going from intersection E to F was a one-way street, the E,F would be a 1 but the F,E would be a 0.
To get a 2-hop option - everything available in 2 jumps from each point, allowing for overlap - you do slightly different things depending on whether List or Matrix is your representation.
For a List, you have a nested for loop, grabbing the set of adjacent options in the outer loop, and asking for them to spit out a list of their adjacent options in the inner loop. Imagine a 4-square of rooms
J Q K A
the outer loop would say, What's adjacent to J? Q- What's adjacent to Q? J and A are adjacent to Q K- What's adjacent to K? J and A are adjacent to K What's adjacent to Q? J- What's adjacent to J? Q and K are adjacent to J A- What's adjacent to A? Q and K are adjacent to A and so on. So the 2-hop for J ends up with J,A,J,A, for Q it's Q,K,Q,K, for K it's Q,K,Q,K, and for A it's J,A,J,A.
For matrices you do Matrix Multiplication. For square matrices of the same size (which works perfectly for us because we're trying to square the matrix in the first place) you take the row and column that meet at each point in the matrix and multiply across. If you were squaring a matrix
your new A would be A*A + B*D + C*G. Your new B would be A*B + B*E + C*H.
So the square of
For A,A it's a,a(0)*a,a(0) + b,a(1)*a,b(1) ... + i,a(0)*a,i(0) = 2 For B,A it's a,a(0)*b,a(1) + b,a(1)*b,b(1) ... + i,b(0)*b,i(0) = 0
And this makes sense. Remember, this is representing how many paths there are to go from one space to another in exactly 2 jumps. A,A means "how many paths go from A back to A in 2 steps." You can see there are 2: A -> B -> A and A -> D -> A. There's no way to actually take 2 steps starting from B and get to A. Using this logic we can guess by looking at the "map" that B,H would give us a value of 1, because there's only one way to get from B to H in 2 hops.
If we do the same cross-section trick to multiply it out, we have 1*0 + 0*0 + 1*0 + 0*0 + 1*1 + 0*0 + 0*1 + 0*0 + 0*1 and sure enough, we have just one spot where the numbers match up.
1 note
·
View note
Text
50.004 – Introduction to Algorithms Homework Set 4
Question 1. Figure 1 shows a directed graph G. a b c d e f g Figure 1: A directed graph for use in Question 1 and Question 2. (i) Give the adjacency-list representation of G. When giving your answer, please order the vertices alphabetically. [2.5 points] (ii) Give the adjacency-matrix representation of G. When giving your answer, please order the vertices alphabetically. [2.5 points] Question 2.…
0 notes
Text
1310 - lab 9 graph representation
files that should be included in your submission GraphList.h Driver.cpp graph.txt Given Files graph.txt lab specifications (directions on how to write the program) main.cpp Open graph.txt Read the number of vertices Create your adjacency list object based on the number of vertices Use a loop to read from the file the edges and add the edge to the adjacency list Make sure to print what edge…
0 notes
Text
1310 - lab 9 graph representation
files that should be included in your submission GraphList.h Driver.cpp graph.txt Given Files graph.txt lab specifications (directions on how to write the program) main.cpp Open graph.txt Read the number of vertices Create your adjacency list object based on the number of vertices Use a loop to read from the file the edges and add the edge to the adjacency list Make sure to print what edge…
View On WordPress
0 notes
Note
why do graphs suck so much in rust :///
Because of ownership, mutability, and aliasing rules, all of which are in place to prevent double frees, use-after-frees, and data races.
To elaborate, a pretty straightforward way to implement a graph in, say, C++ would be something like the following:
template <typename T> class Node { T data; std::vector<Node<T>*> neighbors; };
Individually allocate each node and have them all store pointers to their neighboring nodes.
The problem with this design is that it is inherently memory-unsafe. Assuming a general graph structure (i.e. non-trees are permitted) then there's no clear hierarchy to the nodes, and so no clear way to delegate the deallocation of each node to another one. You gotta do that shit manually, and make sure you're not double-freeing or use-after-freeing or any of that. Probably you're gonna wanna depth-first traverse the entire graph and collect all of the node pointers into a single vector and then deallocate them from there; it's an involved process, very prone to error.
Trying to do a similar thing in Rust, we might try:
struct Node<T> { data: T, neighbors: Vec<Box<Node<T>>>, }
Problem with this is that Box is not interchangeable with a pointer; it can only have one owner, so that it's completely unambiguous when it needs to be deallocated and which Thing needs to do the deallocating, so that it happens automatically. But that means this structure only allows for directed trees. No cycles or back-edges allowed, that would mean the same Box<Node<T>> being owned by more than one other node!
Trying again, we might try to refcount the nodes:
struct Node<T> { data: T, neighbors: Vec<Rc<Node<T>>>, }
And that... kinda works, sometimes? It's a pain in the ass to construct, especially if you want cycles. Gotta juggle weak refs and shit, probably gonna need to add another field in there like weak_neighbors or something, which means also imposing a kinda pseudo-hierarchy anyway, and how do you manage that? Gonna run into a million and a half lifetime problems. Oh yeah, mutability is also a concern, could try sticking a RefCell in there, for even more of a headache.
I haven't even touched on how this shit might work in a multithreaded setting. Data races everywhere.
Anyway, I imagine since you sent this ask you're already painfully aware of all of these problems. But since you're here, might I suggest the following graph structure:
struct Graph<T> { nodes: Vec<(T, Vec<usize>)>, }
(Many variations exist, use your own discretion and ingenuity.)
This is basically an adjacency list representation. We've got all the nodes stored in one vec, owned by an overall graph structure, and each node is stored alongside a vec of indices into that same vec, indicating which nodes it has outgoing edges to. This is almost identical in spirit to the C++ example, except that we're using a kind of insulated memory space where every access is checked by necessity to make sure it's following the rules, and nothing has to worry about deallocating other things in the space because that's managed from outside. If you're not careful here you might run into some out-of-bounds access panics, but you won't run into any memory unsafety.
(Now, giving this structure a convenient public interface is another problem altogether.)
66 notes
·
View notes
Text
Write a C Program for Creation of Adjacency Matrix
Creation of Adjacency Matrix Write a C Program for Creation of Adjacency Matrix. Here’s simple Program for adjacency matrix representation of graph in data structure in C Programming Language. Adjacency Matrix: Adjacency Matrix is a 2D array of size V x V where V is the number of vertices in a graph. Let the 2D array be adj[][], a slot adj[i][j] = 1 indicates that there is an edge from vertex i…
View On WordPress
#adjacency list implementation of graph in c#adjacency list representation of directed graph#adjacency matrix#adjacency matrix example#adjacency matrix graph program in c#adjacency matrix representation#adjacency matrix representation of graph#adjacency matrix representation of graph in c#adjacency matrix representation of graph in c program#adjacency matrix representation of graph in data structure#c data structures#c graph programs#C program to create graph using adjacency matrix method#C Program to Represent Graph Using Adjacency Matrix#graph adjacency matrix c code
0 notes
Text
What in your opinion is the single most important motivation for the development of hashing schemes while there already are other techniques that can be used to realize the same functionality provided by hashing methods?
Given a directed graph, described with the set of vertices and the set of edges, · Draw the picture of the graph· Give an example of a path, a simple path, a cycle· Determine whether the graph is connected or disconnected· Give the matrix representation of the graph· Give the adjacency lists representation of the graphEssay Question: What in your opinion is the single most important motivation…
View On WordPress
0 notes
Text
Finding Eulerian circuits
As discussed previously, Eulerian circuits are useful in 3D printing because they enable continuous extrusion which increases the strength of the printed object . In addition the lack of a seam improves its visual appearance.
However finding a Eulerian circuit in a design is not always easy, and finding the ‘best’ even harder.
For a rectangular grid (3 x 2)
a braiding program I developed a while ago finds a circuit. It attempts to find a braid on an N x M grid. If N and M are relatively prime, one rope (ie. a Eulerian circuit) completes the grid but if not (like this 6 x 3), multiple ropes are needed.
This restriction on the size of this mesh is not helpful. Since every N x M mesh of this style is Eulerian, they must all have a Eulerian circuit. This could be constructed if we were able to join up the separate partial loops. Start somewhere and follow a chain of unvisited edges until you get back to the start. If all edges have been visited, you are done. If not, go back to the last vertex with unvisited edges and start a new circuit at that point, with those points inserted into the current circuit .This is the Hierholzer algorithm.
Hierholzer algorithm
I searched for a pseudo code implementation but wasn’t satisfied with any that I found. Any implementation depends heavily on the data structures used: for the graph itself in a form in which edges can be removed as they are visited and for the path as it is constructed, adding a vertex to the end and rotating the path to backtrack.
One representation of a graph with V vertices and E edges is as a V x V adjacency matrix where adj[i,j] =1 indicates the edge i to j which will be symmetric across the diagonal if the graph (as here) is undirected. Updating is straightforward but navigating from vertex to vertex requires a scan through a row.
Alternatively, the graph can be represented as an array of lists of the connected vertices - easy to navigate, more compact for a sparse graph (as these are) but harder to update.
The JavaScript array structure can implement the vertex list and the evolving path. I found this is a useful summary of operators. push() and pop() will add and remove the head of the list; unshift() and shift() do the same at the tail of the list. myArray[myArray.length - 1] and myArray[0] return the head and tail of the list respectively.
Minimizing turns in the circuit
The Hierholzer algorithm mechanically selects the next vertex by taking any vertex (the first or the last perhaps) from the list of possible vertices. This does find a circuit but not necessarily a good circuit. For the purposes of 3D printing, good means a circuit with a minimum number of turns since straight runs will be stronger and faster. To get a good, though not necessarily the best, circuit, I added a kind code to each edge and then choose a vertex in the same kind if possible. For the rectangular mesh above, there are two kinds , coded +1 for the right diagonal, -1 for the left. (note that we don’t need to distinguish between the direction of travel on a diagonal since we can’t reverse direction at a vertex as that edge has just been traversed)
JavaScript Implementation
In the Fottery suite, the algorithm is implemented as a method in a Graph class which includes the adjacency structure adj and supporting functions:
find_circuit(kind-0,start_vertex = 0 ) { // assumes graph is connected and a euler circuit exists var cpath =[]; var vertex, next_vertex, edge, edges; cpath.push(start_vertex); while (cpath.length < this.n_edges ) { vertex = cpath[cpath.length - 1]; // the last vertex in the constructed path edges = this.adj[vertex]; // get its adjacent nodes (untraversed edges) if (edges.length == 0) { // if no untraversed edges cpath.pop(); // rotate back to the previous vertex if (!(vertex == initial_vertex && cpath[0]==vertex)) { // dont include the start at the end cpath.unshift(vertex); } } else { edge = this.best_edge(edges,kind); next_vertex= edge[0]; kind = edge[1]; cpath.push(next_vertex); // add vertex to the path this.remove_edge(vertex,next_vertex); // remove the traversed edge } }
// get start back to the first in the path while (cpath[0] != start_vertex) cpath.push(cpath.shift()); return cpath;
[damn discovered a use-case where this implementation fails!
16 April 2024 - fixed edge case with the bold change ]
Example
A rectangular N x M mesh like the one above is more useful if the vertices at the edges are connected to make a border. This addition does not change the Eulerian nature of the graph, but introduces two more directions, horizonal and vertical. This is the resultant 2 x 3 mesh.

and this a box constructed from rectangular meshes. The sides are bevelled by insetting the top layer from the bottom by the thickness of the tile to make a 45 degree bevel. Assembled with plastic glue (UHU).

Stars (stellated polygons)
This algorithm has been applied to other structures such as a triangular mesh and stars.
A pentagram can be constructed with 5 vertices and 5 edges connecting pairs of vertices.This is a closed path so Eulerian.

A hexagram looks Eulerian, but if constructed by connecting the vertices of the star, the graph is not connected (two separate triangular paths).

To make a circuit so it can be printed continuously, we have to compute the 6 intersections and the 18 edges (of 3 kinds) which result from the intersections, and then use the modified Hierholzer algorithm to find a good circuit.
A fully connected star is only Eulerian if the number of vertices is odd - which makes for a kind of infill pattern.
Nearly Eulerian graphs
Structures which are Eulerian are rather limited. An hexagonal tiling is not Eulerian because vertices are order 3. However it and many others are nearly Eulerian in the sense that small modifications to the graph will make the graph Eulerian. The basic idea is to duplicate ( the minimum number of ) edges. If this is a problem with printing, the edge could be omitted or an additional edge inserted.
This problem is called the Chinese Postman Problem or Route Inspection Problem and the subject of extensive research.
This is work for another day -.April 2024 see Non-Eulerian graphs
References
Fleischner, Herbert (1991), "X.1 Algorithms for Eulerian Trails” https://archive.org/details/euleriangraphsre0001flei/page/
Gregory Dreifus,Kyle Goodrick,Scott Giles,Milan Patel Path Optimization Along Lattices in Additive Manufacturing Using the Chinese Postman Problem June 2017 https://www.researchgate.net/publication/317701126_Path_Optimization_Along_Lattices_in_Additive_Manufacturing_Using_the_Chinese_Postman_Problem
Prashant Gupta, Bala Krishnamoorthy, Gregory Dreifus Continuous Toolpath Planning in a Graphical Framework for Sparse Infill Additive Manufacturing April 2021 https://arxiv.org/pdf/1908.07452.pdf
https://algorithms.discrete.ma.tum.de/graph-algorithms/directed-chinese-postman/index_en.html
https://www.stem.org.uk/resources/elibrary/resource/31128/chinese-postman-problems
https://ibmathsresources.com/2014/11/28/the-chinese-postman-problem/
http://www.suffolkmaths.co.uk/pages/Maths%20Projects/Projects/Topology%20and%20Graph%20Theory/Chinese%20Postman%20Problem.pdf
1 note
·
View note
Text
50.004 Homework Set4 Solved
50.004 Homework Set4 Solved
Question 1. Figure 1 shows a directed graph G. Figure 1: A directed graph for use in Question 1 and Question 2. Give the adjacency-list representation of G. When giving your answer, please order the vertices alphabetically. [2.5 points] Give the adjacency-matrix representation of G. When giving your answer, please order the vertices alphabetically. [2.5 points] Question 2. Consider the directed…

View On WordPress
0 notes
Text
Writing A Multiplayer Text Adventure Engine In Node.js: Game Engine Server Design (Part 2)
Writing A Multiplayer Text Adventure Engine In Node.js: Game Engine Server Design (Part 2)
Fernando Doglio
2019-10-23T14:00:59+02:002019-10-23T12:06:03+00:00
After some careful consideration and actual implementation of the module, some of the definitions I made during the design phase had to be changed. This should be a familiar scene for anyone who has ever worked with an eager client who dreams about an ideal product but needs to be restraint by the development team.
Once features have been implemented and tested, your team will start noticing that some characteristics might differ from the original plan, and that’s alright. Simply notify, adjust, and go on. So, without further ado, allow me to first explain what has changed from the original plan.
Battle Mechanics
This is probably the biggest change from the original plan. I know I said I was going to go with a D&D-esque implementation in which each PC and NPC involved would get an initiative value and after that, we would run a turn-based combat. It was a nice idea, but implementing it on a REST-based service is a bit complicated since you can’t initiate the communication from the server side, nor maintain status between calls.
So instead, I will take advantage of the simplified mechanics of REST and use that to simplify our battle mechanics. The implemented version will be player-based instead of party-based, and will allow players to attack NPCs (Non-Player Characters). If their attack succeeds, the NPCs will be killed or else they will attack back by either damaging or killing the player.
Whether an attack succeeds or fails will be determined by the type of weapon used and the weaknesses an NPC might have. So basically, if the monster you’re trying to kill is weak against your weapon, it dies. Otherwise, it’ll be unaffected and — most likely — very angry.
Triggers
If you paid close attention to the JSON game definition from my previous article, you might’ve noticed the trigger’s definition found on scene items. A particular one involved updating the game status (statusUpdate). During implementation, I realized having it working as a toggle provided limited freedom. You see, in the way it was implemented (from an idiomatic point of view), you were able to set a status but unsetting it wasn’t an option. So instead, I’ve replaced this trigger effect with two new ones: addStatus and removeStatus. These will allow you to define exactly when these effects can take place — if at all. I feel this is a lot easier to understand and reason about.
This means that the triggers now look like this:
"triggers": [ { "action": "pickup", "effect":{ "addStatus": "has light", "target": "game" } }, { "action": "drop", "effect": { "removeStatus": "has light", "target": "game" } } ]
When picking up the item, we’re setting up a status, and when dropping it, we’re removing it. This way, having multiple game-level status indicators is completely possible and easy to manage.
The Implementation
With those updates out of the way, we can start covering the actual implementation. From an architectural point of view, nothing changed; we’re still building a REST API that will contain the main game engine’s logic.
The Tech Stack
For this particular project, the modules I’m going to be using are the following:
Module Description Express.js Obviously, I’ll be using Express to be the base for the entire engine. Winston Everything in regards to logging will be handled by Winston. Config Every constant and environment-dependant variable will be handled by the config.js module, which greatly simplifies the task of accessing them. Mongoose This will be our ORM. I will model all resources using Mongoose Models and use that to interact directly with the database. uuid We’ll need to generate some unique IDs — this module will help us with that task.
As for other technologies used aside from Node.js, we have MongoDB and Redis. I like to use Mongo due to the lack of schema required. That simple fact allows me to think about my code and the data formats, without having to worry about updating the structure of my tables, schema migrations or conflicting data types.
Regarding Redis, I tend to use it as a support system as much as I can in my projects and this case is no different. I will be using Redis for everything that can be considered volatile information, such as party member numbers, command requests, and other types of data that are small enough and volatile enough to not merit permanent storage.
I’m also going to be using Redis’ key expiration feature to auto manage some aspects of the flow (more on this shortly).
API Definition
Before moving into client-server interaction and data-flow definitions I want to go over the endpoints defined for this API. They aren’t that many, mostly we need to comply with the main features described in Part 1:
Feature Description Join a game A player will be able to join a game by specifying the game’s ID. Create a new game A player can also create a new game instance. The engine should return an ID, so that others can use it to join. Return scene This feature should return the current scene where the party is located. Basically, it’ll return the description, with all of the associated information (possible actions, objects in it, etc.). Interact with scene This is going to be one of the most complex ones, because it will take a command from the client and perform that action — things like move, push, take, look, read, to name just a few. Check inventory Although this is a way to interact with the game, it does not directly relate to the scene. So, checking the inventory for each player will be considered a different action. Register client application The above actions require a valid client to execute them. This endpoint will verify the client application and return a Client ID that will be used for authentication purposes on subsequent requests.
The above list translates into the following list of endpoints:
Verb Endpoint Description POST /clients Client applications will require to get a Client ID key using this endpoint. POST /games New game instances are created using this endpoint by the client applications. POST /games/:id Once the game is created, this endpoint will enable party members to join it and start playing. GET /games/:id/:playername This endpoint will return the current game state for a particular player. POST /games/:id/:playername/commands Finally, with this endpoint, the client application will be able to submit commands (in other words, this endpoint will be used to play).
Let me go into a bit more detail about some of the concepts I described in the previous list.
Client Apps
The client applications will need to register into the system to start using it. All endpoints (except for the first one on the list) are secured and will require a valid application key to be sent with the request. In order to obtain that key, client apps need to simply request one. Once provided, they will last for as long as they are used, or will expire after a month of not being used. This behavior is controlled by storing the key in Redis and setting a one-month long TTL to it.
Game Instance
Creating a new game basically means creating a new instance of a particular game. This new instance will contain a copy of all of the scenes and their content. Any modifications done to the game will only affect the party. This way, many groups can play the same game on their own individual way.
Player’s Game State
This is similar to the previous one, but unique to each player. While the game instance holds the game state for the entire party, the player’s game state holds the current status for one particular player. Mainly, this holds inventory, position, current scene and HP (health points).
Player Commands
Once everything is set up and the client application has registered and joined a game, it can start sending commands. The implemented commands in this version of the engine include: move, look, pickup and attack.
The move command will allow you to traverse the map. You’ll be able to specify the direction you want to move towards and the engine will let you know the result. If you take a quick glimpse at Part 1, you can see the approach I took to handle maps. (In short, the map is represented as a graph, where each node represents a room or scene and is only connected to other nodes that represent adjacent rooms.) The distance between nodes is also present in the representation and coupled with the standard speed a player has; going from room to room might not be as simple as stating your command, but you’ll also have to traverse the distance. In practice, this means that going from one room to the other might require several move commands). The other interesting aspect of this command comes from the fact that this engine is meant to support multiplayer parties, and the party can’t be split (at least not at this time). Therefore, the solution for this is similar to a voting system: every party member will send a move command request whenever they want. Once more than half of them have done so, the most requested direction will be used.
look is quite different from move. It allows the player to specify a direction, an item or NPC they want to inspect. The key logic behind this command, comes into consideration when you think about status-dependant descriptions. For example, let’s say that you enter a new room, but it’s completely dark (you don’t see anything), and you move forward while ignoring it. A few rooms later, you pick up a lit torch from a wall. So now you can go back and re-inspect that dark room. Since you’ve picked up the torch, you now can see inside of it, and be able to interact with any of the items and NPCs you find in there. This is achieved by maintaining a game wide and player specific set of status attributes and allowing the game creator to specify several descriptions for our status-dependant elements in the JSON file. Every description is then equipped with a default text and a set of conditional ones, depending on the current status. The latter are optional; the only one that is mandatory is the default value. Additionally, this command has a short-hand version for look at room: look around; that is because players will be trying to inspect a room very often, so providing a short-hand (or alias) command that is easier to type makes a lot of sense.
The pickup command plays a very important role for the gameplay. This command takes care of adding items into the players inventory or their hands (if they’re free). In order to understand where each item is meant to be stored, their definition has a “destination” property that specifies if it is meant for the inventory or the player’s hands. Anything that is successfully picked up from the scene is then removed from it, updating the game instance’s version of the game.
The use command will allow you to affect the environment using items in your inventory. For instance, picking up a key in a room will allow you to use it to open a locked door in another room.
There is a special command, one that is not gameplay-related, but instead a helper command meant to obtain particular information, such as the current game ID or the player’s name. This command is called get, and the players can use it to query the game engine. For example: get gameid.
Finally, the last command implemented for this version of the engine is the attack command. I already covered this one; basically, you’ll have to specify your target and the weapon you’re attacking it with. That way the system will be able to check the target’s weaknesses and determine the output of your attack.
Client-Engine Interaction
In order to understand how to use the above-listed endpoints, let me show you how any would-be-client can interact with our new API.
Step Description Register client First things first, the client application needs to request an API key to be able to access all other endpoints. In order to get that key, it needs to register on our platform. The only parameter to provide is the name of the app, that’s all. Create a game After the API key is obtained, the first thing to do (assuming this is a brand new interaction) is to create a brand new game instance. Think about it this way: the JSON file I created in my last post contains the game’s definition, but we need to create an instance of it just for you and your party (think classes and objects, same deal). You can do with that instance whatever you want, and it will not affect other parties. Join the game After creating the game, you’ll get a game ID back from the engine. You can then use that game ID to join the instance using your unique username. Unless you join the game, you can’t play, because joining the game will also create a game state instance for you alone. This will be where your inventory, your position and your basic stats are saved in relation to the game you’re playing. You could potentially be playing several games at the same time, and in each one have independent states. Send commands In other words: play the game. The final step is to start sending commands. The amount of commands available was already covered, and it can be easily extended (more on this in a bit). Everytime you send a command, the game will return the new game state for your client to update your view accordingly.
Let’s Get Our Hands Dirty
I’ve gone over as much design as I can, in the hopes that that information will help you understand the following part, so let’s get into the nuts and bolts of the game engine.
Note: I will not be showing you the full code in this article since it’s quite big and not all of it is interesting. Instead, I’ll show the more relevant parts and link to the full repository in case you want more details.
The Main File
First things first: this is an Express project and it’s based boilerplate code was generated using Express’ own generator, so the app.js file should be familiar to you. I just want to go over two tweaks I like to do on that code to simplify my work.
First, I add the following snippet to automate the inclusion of new route files:
const requireDir = require("require-dir") const routes = requireDir("./routes") //... Object.keys(routes).forEach( (file) => { let cnt = routes[file] app.use('/' + file, cnt) })
It’s quite simple really, but it removes the need to manually require each route files you create in the future. By the way, require-dir is a simple module that takes care of auto-requiring every file inside a folder. That’s it.
The other change I like to do is to tweak my error handler just a little bit. I should really start using something more robust, but for the needs at hand, I feel like this gets the work done:
// error handler app.use(function(err, req, res, next) { // render the error page if(typeof err === "string") { err = { status: 500, message: err } } res.status(err.status || 500); let errorObj = { error: true, msg: err.message, errCode: err.status || 500 } if(err.trace) { errorObj.trace = err.trace } res.json(errorObj); });
The above code takes care of the different types of error messages we might have to deal with — either full objects, actual error objects thrown by Javascript or simple error messages without any other context. This code will take it all and format it into a standard format.
Handling Commands
This is another one of those aspects of the engine that had to be easy to extend. In a project like this one, it makes total sense to assume new commands will pop up in the future. If there is something you want to avoid, then that would probably be avoid making changes on the base code when trying to add something new three or four months in the future.
No amount of code comments will make the task of modifying code you haven’t touched (or even thought about) in several months easy, so the priority is to avoid as many changes as possible. Lucky for us, there are a few patterns we can implement to solve this. In particular, I used a mixture of the Command and the Factory patterns.
I basically encapsulated the behavior of each command inside a single class which inherits from a BaseCommand class that contains the generic code to all commands. At the same time, I added a CommandParser module that grabs the string sent by the client and returns the actual command to execute.
The parser is very simple since all implemented commands now have the actual command as to their first word (i.e. “move north”, “pick up knife”, and so on) it’s a simple matter of splitting the string and getting the first part:
const requireDir = require("require-dir") const validCommands = requireDir('./commands') class CommandParser { constructor(command) { this.command = command } normalizeAction(strAct) { strAct = strAct.toLowerCase().split(" ")[0] return strAct } verifyCommand() { if(!this.command) return false if(!this.command.action) return false if(!this.command.context) return false let action = this.normalizeAction(this.command.action) if(validCommands[action]) { return validCommands[action] } return false } parse() { let validCommand = this.verifyCommand() if(validCommand) { let cmdObj = new validCommand(this.command) return cmdObj } else { return false } } }
Note: I’m using the require-dir module once again to simplify the inclusion of any existing and new command classes. I simply add it to the folder and the entire system is able to pick it up and use it.
With that being said, there are many ways this can be improved; for instance, by being able to add synonym support for our commands would be a great feature (so saying “move north”, “go north” or even “walk north” would mean the same). That is something that we could centralize in this class and affect all commands at the same time.
I won’t go into details on any of the commands because, again, that’s too much code to show here, but you can see in the following route code how I managed to generalize that handling of the existing (and any future) commands:
/** Interaction with a particular scene */ router.post('/:id/:playername/:scene', function(req, res, next) { let command = req.body command.context = { gameId: req.params.id, playername: req.params.playername, } let parser = new CommandParser(command) let commandObj = parser.parse() //return the command instance if(!commandObj) return next({ //error handling status: 400, errorCode: config.get("errorCodes.invalidCommand"), message: "Unknown command" }) commandObj.run((err, result) => { //execute the command if(err) return next(err) res.json(result) }) })
All commands only require the run method — anything else is extra and meant for internal use.
I encourage you to go and review the entire source code (even download it and play with it if you like!). In the next part of this series, I’ll show you the actual client implemention and interaction of this API.
Closing Thoughts
I may not have covered a lot of my code here, but I still hope that the article was helpful to show you how I tackle projects — even after the initial design phase. I feel like a lot of people try to start coding as their first response to a new idea and that sometimes can end up discouraging to a developer since there is no real plan set nor any goals to achieve — other than having the final product ready (and that is too big of a milestone to tackle from day 1). So again, my hope with these articles is to share a different way to go about working solo (or as part of a small group) on big projects.
I hope you’ve enjoyed the read! Please feel free to leave a comment below with any type of suggestions or recommendations, I’d love to read what you think and if you’re eager to start testing the API with your own client-side code.
See you on the next one!
(dm, yk, il)
0 notes
Text
A matrix representation of a graph of a square with doors going from 1-2 and back, 2-3 and back, 3-4 and back, and 4-1 and back, would look like this 0101 1010 0101 1010 Each node has a total degree of 4. In spite of using a door as an analogy the "degree" counts the fact that there's a path out to and in from those adjacent rooms. Looking at the matrix you can get the same result by adding up the number of 1s in the matching row and column. In row 3 there are two 1s, indicating the means to go out to rooms 2 and 4. In column 3 there are two 1s, indicating the ability to come in from rooms 2 and 4.
Now imagine the same square but it's all 1-way streets. You can only go from 1-2, from 2-3, from 3-4, and from 4-1. It looks like so: 0100 0010 0001 1000 You can see that the matrix still shows the correct information. Row 1 column 2 has a 1 in it, so you can go from 1 to 2. Row 4 column 1 has a 1 in it, so you can go from 4 to 1. And between row 1 and column 1 you have a total of two 1s, so the first node has a degree of two.
The adjacency list representation of the "doorways" is like this:
1 - (2,4) 2 - (1,3) 3 - (2,4) 4 - (1,3)
The list representation is nice when you've got big areas described, because you may have noticed that even with just a square there's a lot of needless 0s telling you "there's not a line between these two points going this direction." With the list you only bother to say something exists when it's something existing.
0 notes
Text
CSPB 3104 Assignment 8: Problem Set solved
Question 1: Shortest Cycle Involving a Given Node. You are given a directed graph G:(V,E)G:(V,E) using an adjacency list representation and a vertex (node) uu of the graph. Write an algorithm to perform the following tasks: 1(A) Write an algorithm that decides (true/false) whether the vertex uu belongs to a cycle. What is the complexity for your algorithm in terms of the number of…
0 notes
Text
QUESTIONS (Write a program to find the adjacency list of a given directed graph)
Write a program to find the adjacency list of a given directed graph G which is represented as adjacency matrix. Input Format: The first line of the input contains a positive integer n, the number of vertices in the graph, in the range 1 to 1000. The next lines represents the Adjacency matrix representation of the given graph. Output Format: Then lines contain the adjacency list of each node…
0 notes
Text
QUESTIONS (Write a program to find the adjacency list of a given directed graph)
Write a program to find the adjacency list of a given directed graph G which is represented as adjacency matrix. Input Format: The first line of the input contains a positive integer n, the number of vertices in the graph, in the range 1 to 1000. The next lines represents the Adjacency matrix representation of the given graph. Output Format: Then lines contain the adjacency list of each node…
View On WordPress
0 notes
Text
Corsair A500 Review: Premium Price, Curious Flaws
Corsair – the company who has brought us seemingly endless options of AIO liquid cooler models for the masses, has recently introduced their first large air cooling option, the A500. The dual-fan, monolithic heatpipe cooler is also devoid of another Corsair staple: RGB/aRGB lighting, meaning the new Corsair A500 is either a welcome change or a deal breaker, depending on which camp you defend.
Features
Corsair ships the A500 with a quality set of mounting hardware, including nicely plated mounting studs and securing nuts as well as a very robust, laser-cut steel backplate. Cable ties are a welcome addition, as is the 2-way PWM splitter and Phillips screwdriver included in the box.
And while the A500 does ship with pre-applied thermal paste, an additional syringe of XTM50 thermal compound is provided for future re-installs of the cooler. Corsair covers the A500 with a 5-year warranty.
The most interesting feature of the A500 is its pair of non-RGB ML120 fans nested within a set of molded frames which ride on friction rails on either side of the cooler tower. Fans are pre-installed out of the box in a standard push+pull configuration, eliminating any confusion around fan and airflow direction.
The A500 features a quartet of plated heatpipes to dissipate thermal load from the base of the cooler throughout the thermal tower. The mounting plate comes permanently affixed to the base and utilizes a pair of tension-screws to secure to the cooler’s included cross-bar frames.
Access to the tension screws is gained by removing the attractive, brushed-aluminum top plate bearing the Corsair logo by popping it free of cooler tower. The center of the tower fin stack has a central cutaway to allow the Phillips screwdriver direct access through this channel to the tension screws of the base.
Corsair ships the A500 with a pre-applied patch of thermal compound in grid layout. The four direct-contact heatpipes of the cooler are integrated into the plated mounting base. The central cutaway is also visible here, showing how the tension screws are accessed via this channel.
We clean every cooler base of pre-installed thermal compound using alcohol wipes and cloth and later use Arctic MX-4 for all of our tests. During this process, we noticed a small irregularity of the direct-contact heatpipes along the base of the A500. One of the heatpipes (second from the left) is slightly raised when compared with the others in our sample, which is easily seen with a steel straightedge and some backlighting.
The thermal compound contact patch shows the representation of this impact when the cooler is installed, leaving one of the direct contact heatpipes elevated just slightly to isolate it from CPU IHS contact. This also means that this single heatpipe can only ‘work’ by absorbing heat from remainder of the cooler base and the adjacent (raised) heatpipe, instead of directly removing it from the processor.
Making use of the removable top plate, installing the A500 is quite a simple task and one which does not require the cooler’s fans to be removed, which is typically a requirement with other large air coolers. Larger memory DIMMs can be accounted for with a bit of vertical adjustment of the fans, although this may only be required with the tallest of memory sticks.
We tested the Corsair A500 against peers of similar price and relative size, specifically the be quiet! Dark Rock Pro 4, DeepCool Gamer Storm Assassin III and Noctua NH-U12A. All have been evaluated on our i7-5930k test bench running at 4.20 Ghz @ 1.20v paired with 16GB of DDR-2400 Crucial Ballistix on our MSI X99S XPower AC motherboard.
Note that while our cooling platform is old at this point, the CPU’s 140W TDP, combined with a healthy overclock, still gives today’s coolers a tough workout. That said, we are planning to update our cooling testbed once Intel’s latest Comet Lake-S CPUs and accompanying motherboards arrive.
Both the Corsair A500 and Noctua NH-U12A utilize a pair of 120mm fans, which does account for slightly higher thermal load temperatures than the be quiet! Dark Rock Pro 4 utilizing a 135mm + 120mm fan and the dual 140mm DeepCool Gamer Storm Assassin III.
Use of smaller 120mm fans by the A500 and the NH-U12A gives us higher measured fan RPM while larger fans will usually spin more slowly. Since the Dark Rock Pro 4 features two fans of different diameters, we’ve listed them separately as we did from our original coverage of this cooler.
The 2400+ RPM fans on the Corsair A500 kick up a lot of turbulence, leading to elevated decibel levels, but considering we’ve seen similar results on the Corsair H100i Pro lineup, this comes as no surprise.
Acoustic efficiency evaluates how coolers in our tests perform when we combine thermal performance and noise level, essentially building a graph of how well a cooler does work and how acoustically efficient it is during that process.
With the Corsair A500 priced right at $100, it struggles with some of its peers due to noise level and a few degrees of thermal separation. Both the Corsair A500 and the Noctual NH-U12A are priced around 10% higher than the be quiet! Dark Rock Pro 4 and the DeepCool Gamer Storm Assassin III, also creating more separation in our performance value chart.
Thermal imaging from our FLIR ONE Pro camera shows some notable differences of heat soak at 50% fan speed seen in the center cooler cutout vent as well as an indication of additional thermal buildup at the exhaust fan (left of the center logo). Overall, the mass of the cooling fin stack shows equalization in both photos, providing indication that the cooler is effectively distributing thermal loads evenly through the A500.
Corsair have positioned themselves in a way which allows its customers another choice that retains the triple-sail logo while alleviating the fears of liquid cooling and maintaining brand loyalty. The A500 isn’t the highest-performing cooler for big-air money, so unless you are a Corsair loyalist, it’s a difficult option to recommend considering other options available.
We also have some concerns around the irregularities in the milling of the direct-contact heatpipes as we know we aren’t the only ones to have encountered this problem. It makes us wonder if there would be marked performance improvement if this build anomaly were corrected, and we’re hopeful that Corsair will correct the issue in future retail updates.
0 notes
Text
GRA workshop 2
This workshop was on “Computational and algorithmic aspects” (of groups, representations and applications, presumably). In my opinion, this was the week when the programme really took off.
There were many good talks, so as ever I shall just select a few. First, two contrasting styles to actually use the computer to solve problems.
Richard Parker gave a talk on “10 years of meataxe development”, the Meataxe being Richard’s program for decomposing modules. He described it as “a rant”; he works very close to the metal in an attempt to squeeze more speed out of the hardware. He said (and this echoed comments at our Big Data symposium a few years ago) that data movement is more expensive than actually doing the work. (So, of the three Rs, arithmetic is cheap and quick, while reading and writing are much slower and more expensive.) He claimed that programmers mostly ignore modern hardware design. Typically there are three levels of cache with very differing speeds well above RAM access, and if you don’t use them you are taking a factor of hundreds longer than you need. But things are not made easier by the lack of user-friendly assemblers for today’s very complex chips. His wish list was a scheduler, a more friendly assembler, and a solution to the synchronization problem.
At the other end was Nicolas Thiéry. He has a new PhD student, who is going to work on representation theory of semigroups. The software he needs is scattered over many different systems (GAP, Magma, Singular, many others); with some effort he can call everything he needs from Sage, but it is considerably harder than it should be because of differing formats. This is a software engineering problem.
But there was much more to Nicolas’ talk. He was much more concerned to give us insight and motivation than to write down detailed definitions. What is the difference between groups and semigroups? He explained, rather briefly, the J-classes of a semigroup, and how these might be structured round a group. Why do you want to do representation theory of semigroups? Group theory has been applied to the analysis of Markov chains by Diaconis and others; but in this imperfect world, things mightn’t be reversible, and semigroups are like groups where the operations can’t always be reversed. (His picture of a group is a perfect circle.) His example was the Tsetlin library, rephrased in more homely terms: you pull the shirt you want out of the pile, and when it is washed it is put back on top.
I took away the impression that moving from groups to semigroups is not unlike moving from ordinary to modular representation theory of finite groups: things are no longer completely reducible, and you have to deal with the radical.
There was a surprising amount of algebraic geometry; some of it I found very interesting. I’ll mention two. Mohammed Barakat talked about “Chevalley’s Theorem on constructible images made constructive”. In a topological space, a set is locally closed if it is the intersection of an open set and a closed set, and is constructible if it is a finite union of locally closed sets. Chevalley’s theorem says that the image of a rational map of affine varieties is constructible (in the Zariski topology). If this sounds hard, his simple example made it clear. We take the map between two-dimensional affine spaces taking the point (x,y) to x,xy). The image of this map is the whole plane with the Y-axis removed and the origin put back, obviously a constructible set. He has a new proof of this which produces a kind of canonical decomposition into locally closed sets, and which can be implemented on a computer, not just over a field but over rings like the integers too. There were several nice applications.
Tobias Rossman took us on an absolute roller-coaster ride connecting group theory, combinatorics, graph theory, and algebraic geometry. To cut to the chase, given a finite graph Γ, he defines a group scheme GΓ where you have a generator for each vertex, two generators commute if the vertices are non-adjacent (I am not certain I have this right), and commutators are central (so the group is nilpotent of class at most 2). The object of interest is the number of conjugacy classes of this group, over some given field or ring. This has a zeta-function with an Euler product, and the factors are bivariate rational functions of p and p-s. For some special graphs (a subclass of the cographs or N-free graphs), these are simple combinations of translates of the Riemann zeta function. The proof covers a huge amount of ground (as proofs in this area tend to do, in my experience).
Joanna Fawcett and Melissa Lee gave us an update on the base size 2 project: which primitive groups have a base of size 2, or perhaps easier, which ones don’t? (The base size is the minimal number of points whose pointwise stabiliser is the identity.) There is a nice graph, the Saxl graph, associated with groups of base size 2: very simply, the edges are the bases. This is conjectured to have nice properties resembling those of the generating graph of a finite simple group.
Madeleine Whybrow talked about dihedral axial algebras. It would take a while to explain this, but let’s say that the Griess algebra for the Monster is the motiviating example of an axial algebra, though others arise in Jordan algebras. There are now quite simple axioms for axial algebras, though it has taken a while to reach this point, and (the point of the talk) good computational tools to explore them. “Dihedral” just means “two generators”. One can put in values for various numbers that occur in the multiplication table of the idempotents. What has emerged is that the values that occur in the Griess algebra (1, 1/4 and 1/32), which seemed rather artificial at first, really are the sweet spot.
Finally, a lovely talk by Eilidh McKemmie on invariable generation. A group is invariably generated by a set of elements if you can replace any of them by arbitrary conjugates and still have a generating set. It is a result due to Pemantle, Peres and Rivin in one direction and Eberhard, Ford and Green in the other, that four random elements invariably generate the symmetric group Sn with probability bounded away from zero, but three random elements do not. Eilidh has proved that exactly the same holds in classical groups. (There is a slight complication here: classical groups have two parameters, and we may take them to infinity in either order or together, but I will skip over this.)
All rather exciting and exhausting!
from Peter Cameron's Blog https://ift.tt/31ieZun from Blogger https://ift.tt/2tgrFFy
0 notes