Any algorithm/approach to 'simulate' a cyclic graph over time? - algorithm

I don't know if something like this is even possible or where to look for something that could help address the same - hence the question for seeking some pointers.
Here is my situation: I have a matrix representation of a graph of activities. Each entry in the matrix indicates the relative impact of an activity on the other i.e., (There are 'n' activities in the 'system'. The matrix is just an 'n x n' representation of these activities and the entries imply relative impact)
0 (no impact) 1, 2, 3 (low, medium, high) 'positive' impact i.e., they positively (add) contribute to the activity
Negative numbers: -1, -2, -3 imply a 'negative' impact i.e., they negatively (subtract) contribute
(The numbers are informational, could be any numbers really but just simplified it to 0-3).
Now given this matrix I'll have a description of a graph. What I'd like to do is to 'simulate' the graph over time i.e., starting at time t=0 I'd like to be able to simulate the working of the 'system' over time. I'll have cycles in the graph for sure (very likely) and thus a time-step based simulation would be apt here.
I am not aware of anything in that I could use to help me understand the effects over time for a cyclic graph. I am aware of ONLY one such solution i.e., to use System Dynamics and convert this graph into stock/flow diagram and then simulate it to get what I want. Effectively the graph (above) is then a causal-loop diagram.
Issue: I'd really like to go from the matrix representation to a simulate-able system without forcing someone to understand system dynamics (basically do something in the background).
The question is: Is System Dynamics the only way to achieve what I'm looking for? How should I go about systematically converting any arbitrary matrix representation of graph into a system dynamic model?
If NOT system dynamics, then what other approaches should I look at to solve such a problem? Algorithm names with corresponding pointers for reference would be appreciated!
An example representation of a graph:
Say I have the following matrix of 3 activities:
Rows: Nodes that are 'cause' (outgoing arrows)
Columns: Nodes being 'affected' (incoming arrows)
__| A | B | C |
A | - | 3 | 2 |
B | 1 | - |-2 |
C |-1 | 0 | - |
If I 'start' the graph (simulation) with 10 units for A I'd like to see how the system plays out over time given the relative impacts in the matrix representation.
UPDATE: The 'simulation' would be in a series of time steps i.e., at time t=0 the node A would have the value of 10 and B would either multiply by 3 or add 3 depending on how someone would want to specify the 'impact'. The accumulated values of the nodes over time could be plotted on a graph to show the trend of how the value progresses.

It seems like you are looking for Markov chains.
Let G be a system of states.
The probability of the system transferring from one state to another is given by the matrix T.
f
After n transferences, the probability of the system transferring from one state to another is given by Tn.
For example, after 3 transferences:
This matrix represents:
Given the system is in A, it has a
32.4% chance of remaining at A
31.2% chance of transferring to B
36.4% chance of transferring to C
etcetera for B and C
I would attempt to apply this to your situation for you, but I do not really understand it.
If you are to use Markov chains, you must establish a probability of the system transferring.
Note that, because this is "chance of system being at a given node", you can apply it to a population of systems.
For example: After n transferences, X.XX% of the population will be at Y.

There have been several attempts to do this, with various origins in the cybernetics and system dynamics literature, without much success.
Basically the problem is that your matrix, while it may contain a lot of insight and have useful applications for group process, falls short of the degree of specification that one needs to actually simulate a dynamic system.
The matrix identifies the feedback loops that exist in your system, but to relate that structure to behavior, you also need to specify phase and gain relationships around those loops (i.e., identify the stocks and the slope of each relationship, which may be nonlinear). Without doing this, there's simply no way to establish which loops are dominant drivers of the behavior.
You might be able to get some further insight out of your matrix through graph theoretic approaches to identifying and visualizing important features, but unfortunately there's no escaping the model-building process if you want to simulate.

Related

Is there an established algorithm for reaching a goal through the sequential application of known cause and effect tuples?

Let's say that I want to create a fictional product called g.
I know that:
a+b=c
x+y=z
and finally that
c+z=g
So clearly if I start off with products
a,b,x,y
I can create g in three steps:
a+b=c
x+y=z
c+z=g
So a naive algorithm for reaching a goal could be:
For each component required to make the goal (here c and z), recursively find a cause and effect tuple that can create that component.
But there are snags with that algorithm.
For example, let's say that my cause and effect tuples are:
a+b=c
x+y+c=z (NOTE THE EXTRA 'c' REQUIRED!!)
c+z=g
Now when I run my naive algorithm I will do
a+b=c
x+y+c=z (Using up the 'c' I created in the previous step)
c+z=g (Uh oh! I can't do this because I don't have the 'c' any more)
It seems like quite a basic area of research - how we can combine known causes and effects to reach a goal - so I suspect that work must have been done on it, but I've looked around and couldn't find anything and I don't really know where to look now.
Many thanks for any assistance!
Assuming that using a product consumes one item of it, which can then be replaced by producing a second item of that product, I would model this by giving each product a cost and working out how to minimize the cost of the final product. In this case I think this is the same as minimizing the costs of every product, because minimizing the cost of an input never increases the cost of any output. You end up with loads of equations like
a=min(b+c, d+e, f+g)
where a is the cost of a product that can be produced in alternative ways, one way consuming units with cost of b and c, another way consuming units with costs of d and e, another way consuming units with costs of f and g, and so on. There may be cycles in the associated graph.
One way to solve such a problem would be to start by assigning the cost infinity to all products not originally provided as inputs (with costs) and then repeatedly reducing costs where equations show a way of calculating a cost less than the current cost, keeping track of re-calculations caused by inputs not yet considered or reductions in costs. At each stage I would consider the consequences of the smallest input or recalculated value available, with ties broken by a second component which amounts to a tax on production. The outputs produced from a calculation are always at least as large as any input, so newly produced values are always larger than the recalculated value considered, and the recalculated value considered at each stage never decreases, which should reduce repeated recalculation.
Another way would be to turn this into a linear program and throw it at a highly optimized guaranteed polynomial time (at least in practice) linear programming solver.
a = min(b+c, d+e, f+g)
becomes
a = b+c-x
a = d+e-y
a = f+g-z
x >= 0
y >= 0
z >= 0
minimize sum(x+y+z+....)

What algorithm do I use to calculate voltage across a combination circuit?

I'm trying to programmatically calculate voltage changes over a very large circuit.
*This question may seem geared toward electronics, but it's
more about applying an algorithm over a set of data.
To keep things simple,
here is a complete circuit, with the voltages already calculated:
I'm originally only given the battery voltage and the resistances:
The issue I have is that voltage is calculated differently among parallel and series circuits.
A somewhat similar question asked on SO.
Some formulas:
When resistors are in parallel:
Rtotal = 1/(1/R1 + 1/R2 + 1/R3 ... + 1/Rn)
When resistors are in series:
Rtotal = R1 + R2 + R3 ... + Rn
Ohm's Law:
V = IR
I = V/R
R = V/I
V is voltage (volts)
I is current (amps)
R is resistance(ohms)
Every tutorial I've found on the internet consists of people conceptually grouping together parallel circuits to get the total resistance, and then using that resistance to calculate the resistance in series.
This is fine for small examples, but it's difficult to derive an algorithm out of it for large scale circuits.
My question:
Given a matrix of all complete paths,
is there a way for me to calculate all the voltage drops?
I currently have the system as a graph data structure.
All of the nodes are represented(and can be looked up by) an id number.
So for the example above, if I run the traversals, I'll get back a list of paths like this:
[[0,1,2,4,0]
,[0,1,3,4,0]]
Each number can be used to derive the actual node and it's corresponding data. What kind of transformations/algorithms do I need to perform on this set of data?
It's very likely that portions of the circuit will be compound, and those compound sections may find themselves being in parallel or series with other compound sections.
I think my problem is akin to this:
http://en.wikipedia.org/wiki/Series-parallel_partial_order
Some circuits cannot even be analyzed in terms of series and parallel, for example a circuit which includes the edges of a cube (there's some code at the bottom of that web page that might be helpful; I haven't looked at it). Another example that can't be analyzed into series/parallel is a pentagon/pentagram shape.
A more robust solution than thinking about series and parallel is to use Kirchhoff's laws.
You need to make variables for the currents in each linear section
of the circuit.
Apply Kirchhoff's current law (KCL) to nodes where
linear sections meet.
Apply Kirchhoff's voltage law (KVL) to as many
cycles as you can find.
Use Gaussian elimination to solve the
resulting linear system of equations.
The tricky part is identifying cycles. In the example you give, there are three cycles: through battery and left resistor, battery and right resistor, and through left and right resistors. For planar circuits it's not too hard to find a complete set of cycles; for three dimensional circuits, it can be hard.
You don't actually need all the cycles. In the above example, two would be enough (corresponding to the two bounded regions into which the circuit divides the plane). Then you have three variables (currents in three linear parts of the circuit) and three equations (sum of currents at the top node where three linear segments meet, and voltage drops around two cycles). That is enough to solve the system for currents by Gaussian elimination, then you can calculate voltages from the currents.
If you throw in too many equations (e.g., currents at both nodes in your example, and voltages over three cycles instead of two), things will still work out: Gaussian elimination will just eliminate the redundancies and you'll still get the unique, correct answer. The real problem is if you have too few equations. For example, if you use KCL on the two nodes in your example and KVL around just one cycle, you'll have three equations, but one is redundant, so you'll only really have two independent equations, which is not enough. So I would say throw in every equation you can find and let Gaussian elimination sort it out.
And hopefully you can restrict to planar circuits, for which it is easy to find a nice set of cycles. Otherwise you'll need a graph cycle enumeration algorithm. I'm sure you can find one if you need it.
use a maximum flow algorithm (Dijkstra is your friend).
http://www.cs.princeton.edu/courses/archive/spr04/cos226/lectures/maxflow.4up.pdf
You pretend to be in front of a water flow problem (well, actually it IS a flow problem). You have to compute the flow of water on each segment (the current). Then you can easily compute the voltage drop (water pressure) across every resistor.
I think the way to go here would be something like this:
Sort all your paths into groups of the same length.
While there are more than one group, choose the group with the largest length and:
2a. Find two paths with one item difference.
2b. "Merge" them into a path with the length smaller by one - the merge is dependent on the actual items that are different.
2c. Add the new path into the relevant group.
2d. If there are only paths with more than one item difference, merge the different items so that you have only one different item between the paths.
2e. When there is only one item left, find an item from a "lower" (= length is smaller) with minimum differences, and merge item to match.
When there is one group left with more than one item, keep doing #2 until there is one group left with one item.
Calculate the value of that item directly.
This is very initial, but I think the main idea is clear.
Any improvements are welcome.

Efficient Algorithm for finding closest match in a graph

Edit: to include concrete explanation of my problem (as correctly deduced by Billiska):
"Set A is the set of users. set B is the set of products. each user rates one or more products. the rating is 1 to 10. you want to deduce for each user, who is the other user that has the most similar taste to him."
"The other half is choosing how exactly do you want to rank similarity of A-elements." - this is also part of my problem. I feel that users who have rated similarly across the most products have the closed affinity, but at the same time I want to avoid user1 and user2 with many mediocre matches being matched ahead of user1 and user3 who have just a few very good matches (perhaps I need a non-linear score).
Disclaimer: I have never used a graph database.
I two sets of data A and B. A has a relationship with zero to many Bs. Each relationship has a fixed value.
e.g.
A1--5-->B10
A1--1-->B1000
So my initial thought "Yay, thats a graph, time to learn about graph databases!" but before I get too carried away.... the only reason for doing this so that I can answer the question....
For each A find the set of As that are most similar based on their weights, where I want to take in to consideration
the difference in weights (assuming 1 to 10) so that 10 and 10 is scored higher than 10 and 1; but then I have an issue with how to handle where is is no pairing (or do I - I am just not sure)
the number of vertices (ignoring weights) that two sets have in common. Intention is to rank two As with lots of vertices to the same Bs higher than two As that have just a single matching vertices.
What would the best approach be to doing this?
(Supplementary - as I realise this may count a second question): How would that approach change if the set of A was in the millions and B in the 100 thousands and I needed real-time answers?
Not a complete answer. I don't fully understand the technique either. but I know it's very relevant.
If you view the data as a matrix. e.g. have the rows correspond to set A, have the columns correspond to set B, and the entries are the weight.
Then it's a matrix with some missing values.
One technique used in recommender system (under the category of collaborative filtering) is low-rank approximation.
It's based on the assumption that the said user-product rating matrix usually have low-rank.
In a rough sense, the said matrix have low-rank if the rows of many users could be expressed as linear combination of other users' row.
I hope this would give a start for further reading.
Yes, you could see in low-rank approximation wiki page that the technique can be used to guess the missing entries (the missing rating). I know it's a different problem, but related.

GA algorithm approach for TSP

I built a GA algorithm to solve the TSP.
It's in an exercise in Norvig's book (AIAMA). He suggested we read the Larrañaga's view on the problem for representations and such. I learned the some cross over operators and mutations there and tried out a few of them to see which suited me better. I also elaborated a fitness function based on the cost of each path.
Well, despite all that I have a question about my algorithm design, I had never worked with AI before so I don't know if my approach is a valid one for GAs.
Here's what I did:
I took a vector of paths (my initial population)
and then at each loop I organized this vector by increasing cost order and took the best X paths in this vector and deleted the other paths.
I then apply XOver and Mutation (at a certain rate) and put them at the position of the old deleted values of the vector.
I then do the same (order vector - extract best etc)
and keep doing it until it stabilizes.
Is it a good approach ? If it isn't give me some north. Cause when I selected the best and didn't keep them (just created a whole new pop from them, via Xover and mutation) I didn't get good results. This way (keeping the best ones - in some experiments I kept only THE best one) I have better results and the result always converges and well fast
State representation : For state representation I chose to use the Path Representation (I was already using it from start and decided to stick with it after I read Larrañaga et all),
it is as follows: if we have, let's say, 5 cities and visit the first city, then the second, then the third ... our path representation would be (1, 2, 3, 4, 5)
Initial population generation : Actually I'm generation random points to representing the cities (that's what the book asked me to do, generate random points in a closed square) - but for the sake of comparison I generated a population and stick with it when comparing the results - I think if I didn't stick with one particular population I wouldn't have much to know about my improvements
Best Fit Individuals : The best fit individuals are the one's that have the best traveling cost. (I don't know if I should have - in this problem - used something else as a parameter
crossover : I tried some crossover operators and compared my reuslts with the one presented in the book and ended up using one of the Order CrossOvers ( Larrañaga et al(1999) ):
this crossover takes tow random cuts (forming a sub-path) fromboth parent paths and then copies the rest of the path (the cities not yet visited inside that sub-path) from the other parent (starting at the second cut, not at the position '0') - adding the cities they appear in the other parent.
example: paths (1 2 3 4 5) (3 4 2 1 5) choosing the sub-paths (234) and (421)
we would have as offsprings (5 |2 3 4| 1) (5 |4 2 1| 3) <- the part inside the | | came from one parent and the other part from the other parent
mutation : For mutation I chose IVM (Inversion Mutation) approach. it takes a sub-path from the original path and inserts it back (inverted) at a random point.
example: path (1 2 3 4 5) sub path ( 2 3 4 )and random insertion after 5
generate : ( 1 5 | 4 3 2 )
First of all, avoid all these abbreviations (GA, TSP, XOver). It is hard to read and some people may have no idea what you are talking about.
The first problem with genetic algorithm is How you choose the initial population, How you perform the crossover, How you perform the mutation. The second problem is that the naive understanding of the description may be a terrible one.
For you the best fit individuals are the ones which have already better cost. You can argue that it will be better to take the most diverse individuals, ie the ones which are more likely to explore different part of the problem space. Describe how do you make the following operations:
State representation : just to make sure
Initial population generation : Really important. Maybe there are materials available for this step, as it is common with local search algorithms.
best fit individuals : I suggest you to try to play more here. Try different strategies. You are looking for the best fitted for reproduction, not for the overall solution of the problem.
crossover : How do you do it?
mutation : The goal of mutation is to evade the current region of the problem space, and you can create an individual with a really high cost. With your current algorithm at the next step he would be ditched out when you sort
You also need to evaluate how is your solution improved with running time. For example, rather than n iterations your provide 100n, does the solution get better, how much? How similar to each other are the individuals of the last generation when the algorithm stops, etc.
Another question, do you try to solve it for a fixed topology or a variable topology??
EDIT :
You are using published algorithms so it doesn't seems the problem is on specific operations. For the fitness you are right stick with the path cost. You say
Cause when I selected the best and didn't keep them (just created a whole new pop from them, via Xover and mutation) I didn't get good results. This way (keeping the best ones - in some experiments I kept only THE best one) I have better results and the result always converges and well fast.
You should keep the best fit individuals and their children. It follow a wicked principle of the nature, Only the best have the right to reproduce. The one which have to be replaced are the least fit individuals.
There are 3 parameters you can tune : The proportion of best fit individual which have children (also the number of individual will be ditched out), the mutation probability, and the number of runs.
To test how your algorithm perform you can sample the best solution by iteration, ie each t iteration you save the lower cost. Once plotted it should look like :

Correlating word proximity

Let's say I have a text transcript of a dialogue over a period of aprox. 1 hour. I want to know what words happen in close proximatey to one another. What type of statistical technique would I use to determine what words are clustered together and how close their proximatey to one another is?
I'm suspecting some sort of cluster analysis or PCA.
To determine word proximity, you will have to build a graph:
each word is a vertex (or "node"), and
left and right words are edges
So "I like dogs" would have 2 edges and 3 vertices.
Now, the next step will be to decide based on this model what your definition of "close" is.
This is where the statistics comes in.
To determine "groups" of correlated words
MCL clustering - This will give you a number of clusters which algorithmically have high odds of being seen together.
K MEANS clustering - This will give you "k" groups of words.
Thresholding - this is the most reliable and intuitive method. Plot all the relationships for a small subset of data that you understand (for example, a paragraph from a news clip or article you have read) and run your method to generate a graph, and visualize the graph using a tool such as graphviz or cytoscape. Once you can see the relatedness, you can count how many edges are generally found between different words that clearly cluster together. You might find that, for example, two words that cluster together will have an edge for every 5 instances. Use this as a cutoff and write your own graph analysis script which outputs word-pairs that have at least 1 edge for every 5 instances of the word in your vertex graph.
Evaluating 3 by ROC curves. You can titrate this value of your cutoff higher and higher until you have very few "clusters". If you then run your algorithm against a paragraph with known, expected results (created by a human who already knows what words should be reported as correlated), you can evaluate the precision of your algorithm using a receiver operating characteristic which compares the correlated-words output to a precalculated gold standard.

Resources