I recently started to work with C# and I have to import a Visio file that is including a flow-chart with different path.
I load the file with this code.
public Container loadFile(string fileName)
{
Microsoft.Office.Interop.Visio.Application app = new Microsoft.Office.Interop.Visio.Application();
app.Visible = false;
Documents docs = app.Documents;
Document doc = docs.Open(fileName);
Microsoft.Office.Interop.Visio.Page page = doc.Pages[1];
Container container = printProperties(page.Shapes);
return container;
}
public Container printProperties(Microsoft.Office.Interop.Visio.Shapes shapes)
{
Container container = new Container("Visio Import");
container.setParent(null);
// Look at each shape in the collection.
foreach (Microsoft.Office.Interop.Visio.Shape shape in shapes)
{
// traverse
}
return container;
}
I want to traverse through every possible (!) path of the flow-chart and print the process names. E.g.
Path 1:
- Enter PIN
- Select Account
- Select Amount
- Print Receipt
- Take Money
Path 2:
- Enter PIN
- Select Account
- Check Money
- Abort
Can you tell me how to check the connections between the single processes and traverse it? Thank you very much for your help!
I have code that does this, but I cannot share it, since it's part of a commercial product.
However, I can tell you that the way I coped with doing this within Visio was, I first wrote a set of very generic directed graph classes in VBA: one for nodes, one for edges, and one for the graph as a whole. I built circular path checks into the graph class, as well as the code for finding all paths in the graph.
Then I had some code that would read the Visio page and populate this simple graph representation, and call the appropriate code.
I think this would probably be good for you to do, too, since the Visio side of things will inevitably be messier than a simple directed graph implementation. I didn't use the ConnectedShapes part of the API since I have to support down to Visio 2003, so I actually look at the Connects and FromConnects objects on my shapes to see what OneD connectors are attached to a shape, and determine whether a shape is at the head or tail of an arrow. This is another reason to break the graph part away from the Visio part, since the way we read the Visio page is subject to change over time, but the graph theory will stay the same.
The path-finding algorithm works by first finding all the terminal nodes in the graph, and I mean those nodes with no Downstream nodes. For each of these I add a list called DownstreamPaths, which is just empty since there is nothing downstream. Then for each node in the graph I call a recursive function that populates all the downstream paths for the current node, and basically all it does is builds a DownstreamPaths list on each node. This list is a list of lists, so you just look at each downstream node, and append that node on the head of its own DownstreamPaths list, and add that into the current node's path list.
When that's all done, you find all the starting nodes, with nothing upstream, and collate all the downstream paths lists on those, and you get your list of paths.
You could use shape.ConnectedShapes (Visio 2010+) to find which shapes are connected to the current one. Thus, you will be able to build a graph (model) out of the flowchart.
Check out also this article which explains things about Visio connectivity:
http://blogs.msdn.com/b/visio/archive/2009/09/22/the-visio-2010-connectivity-api.aspx
Finding all paths in that graph is a different story though, the solution may depend of what kind of flowchart you analyze; for example, if the flowchart has a cycle, there will be infinite number of paths in fact... Also, the number of possible paths may grow exponentially for relatively simple acyclic graphs. You could try "finding all paths in directed graph" search.
Related
We are using the classes in the Microsoft.VisualStudio.XmlEditor namespace (https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.xmleditor.aspx) to parse an xml document in an Visual Studio Extension. Documents are parsed to an object structure, and only changes are parsed. This part is working perfectly.
Now we want to use the parsed data objects to show adornments (https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.text.editor.intratextadornmenttag.aspx) on specific locations within the XML file, based on some conditions. The tagging system expects that the extension gives a list of snapshotspans, where the tags should be rendered.
The problem is that we cannot find a way to know the correct positions of the XML tags. The XmlModel class, provides a GetTextSpan() method (https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.xmleditor.xmlmodel.gettextspan.aspx), but the result of that method call doesn't contain the ITextSnapshot to which the coordinates belong. Since the XML parser is running on a separate thread, there is no way to guarantee that these coordinates are still valid for the most recent snapshot of the text buffer when doing changes quickly after each other. If the result would have been a SnapshotSpan struct (https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.text.snapshotspan.aspx), we would be able to translate that span to the current snapshot.
Does anybody know a proper way to resolve this issue?
I'm writing a script editor that needs to transform the user's input (which is similar to script syntax) into valid C# according to some rules I define. For example, if the users puts in
using System;
public string hello()
{
return "Hi!" // whoops, semicolon here is missing!
}
I'd need to transform this to
using System;
public class ContainerClass
{
public string hello()
{
return "Hi!" // whoops, semicolon here is missing!
}
}
my transformation will insert new nodes (such as the class declaration) and might move around existing ones, but it will never modify or remove existing ones. (I know SourceCodeKind = Script does something vaguely similar, but I can't use that for a variety of reasons).
Now I need to come up with a way to do this transformation given the following considerations:
Since I need to run the transformation each time the user changes the original document (i.e. just types a single letter), I can't afford to re-parse the entire thing every time from a performance perspective. For example, if the user inserts the missing semicolon after ";", ideally I would just insert the same (or cloned) node into my already transformed document, instead of re-parsing everything. I suppose that rules out standard ways of modification such as DocumentEditor.
I need to have a way to re-map locations from my transformed document to locations in the original document. Since I will never delete nodes, I think theoretically this should be possible (but how?).
This is necessary e.g. as I would end up with diagnostic messages (and intellisense information etc.) pointing to locations in the transformed document, and need to get the original document's location for these to actually show them to the user.
Can anyone thing of a more or less direct way to do this? Is there maybe even some Roslyn helper classes for use cases like this?
My ideas below. I'm not quite sure they'd work, and I think they'd be very hard to implement, so I'm hoping there is some easier way to be honest;
For #1, my only idea was to get get the text changes (Document.GetTextChangesAsync) of the original document after its source code changes; and then somehow try to find out what nodes have been affected by this (maybe get nodes that intersect the edited area in the old and new document, then compute which ones have been deleted, added or modified) - and then to apply these changes in my transformed document. This seems awfully complex though.
For #2, my only idea so far was to enable tracking for nodes of the original document. Then I would find whatever node a location points to in the transformed document, and find the node in the original document this originated from (and then find the location of that node).
But the problem is that e.g. the code above would produce a diagnostic error pointing towards the location right after "Hi!", wich the location span's length of 0, as there's a semicolon missing. So the location doesn't really point to a node at all. Maybe I could try finding adjacent nodes in that case?!
I have to solve the rushhour problem using iterative deepening search, I'm generating new node for every move, everything works fine, except that it takes too much time to compute everything and the reason for this is that I'm generating duplicated nodes. Any ideas how to check for duplicates?
First I start at the root, then there is a method which checks every car whether is it possible to move it if yes, new node is created from the current node but the one car that has valid move replaced with new car that has new coordinates.
Problem is that the deeper the algorithm is the more duplicates moves there are.
I have tried to not to replace the car, but used the same collection as was used in root node but then the cars were moving only in one direction.
I think that I need to tie car collection somehow, but don't know how.
The code
Any ideas how to stop making duplicates?
Off topic: I'm new to C# (read several tutorial and then have been using for 2 days) so can you tell me what I'm doing wrong or what should I not do?
If you want to stick with iterative deepening, then the simplest solution may be to build a hash table. Then all you need to do with each new node is something like
NewNode = GenerateNextNode
if not InHashTable(NewNode) then
AddToHashTable(NewNode)
Process(NewNode)
Alternately, the number of possible positions (nodes) in RushHour is fairly small (assuming you are using the standard board dimensions) and it is possible to generate all possible (and impossible!) boards fairly easily. Then rather than iterative deepening you can start with the 'solution' state and work backwards (ticking off all possible 'parent' states) until you reach the start state. By working on the table of possible states you never generate duplicates, and by tagging each state once it is visited you never re-visit states.
I'm looking for the longest-path trough a map in a game which is turn based. I got 1s computation time and need to move at that point.
Right now I'm generating the tree every move again.
Is it possible to use my old tree and stack (in which I store the nodes yet to be visited) to get a bigger depth and thus a better result?
For now my SearchClass is based on a Interface, thus changing the return-type and the input-variables of my function is a lot of work. Is there an easy solution for my problem?
If your map is static and not overly large, you could generate your tree in advance.
For each node, calculate the longest path to every other node on the map then store the path and its length against the original node. That way, you no longer need to compute paths during program execution; you only need to use the pre-computed longest path from your current node to your chosen destination.
Can you probably make your (Player's) tree static? Or if you are the only player, you could make it a global variable for the whole program on player's-side, but that depends on many things, that you did not share with us. I would still suggest you to have a look at MCTS: Wikipedia description and Here, it has sample code.
With MCTS the idea is simple: You compute all your 900ms, then make a player's move to the node, that has the highest winning-probability. If you can persist the tree as a global or static ( or both :D ) variable, the first thing, that you do at the begining of the next turn (or the next computation) is to get rid of all parts of the previous tree, that you can not access any more - because you are not at position [0][0], but at position lets say [1][3] ... so that shrinks the tree-size for you, which is good. So what you have to do is to replace the original tree with a new tree, which starts with the node, that you are at the moment standing on. Good thing is, you have some values precomputed, now it depends on your implementation, how you want the nodes to be explored and/or probability-updated. But as the game goes on, the program should have enough data, that it can guarrant it a very high winning probability.
This approach is exceptionally good, because it does not compute the probabilities of the steps you do not take, when known, you are not going to take them (this is a thing you did not mention in your approach and I find it a necessity, so that's why I responded).
Excuse any failures, I'm gonna specify/update/correct things upon request.
And all the things you are doing seem to meet some pattern of university-delivery, see for example, if this is not your case, you could pretty well inspire there. If you have to meet some school-delivery, make sure you do not discuss too much into detail and/or do not ask for technical-implementation help.
Looking for a good approach to keep track of a Breadth-First traversal between two nodes, without knowing anything about the graph. Versus Depth-First (where you can throw away the path if it doesn't pan out) you may have quite a few "open" possibilities during the traversal.
The naive approach is to build a tree with the source node as the root and all its connections as its children. Depending on the amount of space you have, you might need to eliminate cycles as you go. You can do that with a bitmap where each bit corresponds to a distinct node in the graph. When you reach the target node, you can follow the parent links back to the root and that is your path. Since you are going breadth first, you are assured that it is a shortest path even if you don't eliminate cycles.
For a breadth-first search you need to store at least two things. One is the set of already visited nodes and the other is the set of nodes that are directly reachable from the visited nodes but are not visited themselves. Then you keep moving states from the latter set to the former, adding newly reachable states to the latter. If you need the have a path from the root to some node(s), then you will also need to store a parent node for each node (except the root) in the aforementioned sets.
Usually the union of the set of visited nodes and the set of not-visited child nodes (i.e. the set of seen nodes) is stored in a hash table. This is to be able to quickly determine whether or not a "new" state has been seen before and ignore it if this is the case. If you have really big number of states you might indeed need a bit array (as mentioned by Joseph Bui (57509), but unless your states can be used (directly or indirectly) as indices to that array, you will need to use a hash function to map states to indices. In the latter case you might completely ignore certain states because they are mapped to the same index as a different (and seen) node, so you might want to be careful with this. Also, to get a path you still need to store the parent information which pretty much negates the use of the bit-array.
The set of unvisited but seen nodes can be stored as a queue. (Bit arrays are of no use for this set because the array will be mostly empty and finding the next set bit is relatively expensive.)
I just submitted a solution over here that also applies to this question.
Basically, I just keep a single list (a stack really) of visited nodes. Add a node to the list just before recursing or saving a solution. Always remove from the list directly after.
If you are using .NET 3.5 consider using the Hashset to prevent duplicate nodes from being expanded, this happens when there is cycles in your graph. If you have any knowledge about the contents of the graph consider implementing an A* search to reduce the number of nodes that are expanded. Good luck and I hope it works out for you.
If you are still a fan of treeware there are many excellent books on the topic of graphs and graph search such as Artificial Intelligence: A Modern Approach by Peter Norvig and Stuart Russell.
The links in my response appear to have a bug they are Hashset: http://msdn.com/en-us/library/bb359438.aspx and A* search: http://en.wikipedia.org/wiki/A*_search_algorithm