I started to learn igraph in C and I was wondering how can I visualize a graph made with this library. I've seen that with igraph R one just use the plot function and the graph is plotted but if I use C, should I print the graph in a file and then use another program to visualize it or which is the usual way?
Thanks!
edit: This kind of graph.
Follow the Unix philosophy, and have your program output the description of the graph (in text format, or in an easily processed form if no pure text format is easily available).
(Note that this also applies to image formats; the NetPBM (.pnm, or .pbm, .pgm, and .ppm) formats are easy to generate in pure C (to e.g. standard output), and if necessary, the NetPBM tools can be used to convert to any other image format you might wish.)
For example, if your program outputs
graph {
rankdir=LR;
"6" -- "4";
"4" -- "5";
"3" -- "4";
"3" -- "2";
"5" -- "2";
"5" -- "1";
"2" -- "1";
}
then redirecting the output to e.g. output.dot and running dot -Tx11 output.dot will output a graph similar to the one shown in the Wikipedia Graph article,
You mention that you are using igraph, and luckily this library already supports writing graphs in the DOT format. See the igraph_write_graph_dot() function.
The DOT language is specified here, but it really is quite simple. -- denotes an undirected edge, and -> a directed edge. The rankdir=LR; line is a graph attribute, and tells DOT that it should try to order the nodes seen from left to right. The default is from top to bottom. You can add node attributes too, for example "6" [ label="Six" ]; would change the label of node "6" to Six. Edge attributes work exactly the same way; so using "2" -- "1" [ taillabel="Z" ]; adds "Z" near node "2" end of the edge between nodes "2" and "1". It is best to quote node names, even though the quotes are not necessary if the node name starts with a letter and does not match a graph attribute name.
Here is a useful hint, when printing trees or linked lists:
Use %p (a pointer to the node) as the node name, and label="value" to set the visible label of the node to value. For example, if you have
struct node {
struct node *left;
struct node *right;
int value;
};
then a simple function pair,
void print_tree_recursive(FILE *out, struct node *curr)
{
fprintf(out, " \"%p\" [ label=\"%d\" ];\n", (void *)curr, curr->value);
if (curr->left) {
print_tree_recursive(out, curr->left);
fprintf(out, " \"%p\" -> \"%p\" [ taillabel="L" ];\n", curr, curr->left);
}
if (curr->right) {
print_tree_recursive(out, curr->right);
fprintf(out, " \"%p\" -> \"%p\" [ taillabel="R" ];\n", curr, curr->right);
}
}
void print_tree(FILE *out, struct node *tree)
{
fprintf(out, "digraph {\n");
if (tree)
print_tree_recursive(out, tree);
fprintf(out, "}\n");
fflush(out);
}
will print a nice directed graph of any tree. It is easy to modify to print linked lists (both singly and doubly linked). Note how the helper function describes the node first (the fprintf with label=), and the edges separately (the fprintfs with taillabel=).
If you print the graph to standard output, you can either redirect the output to a file and display or convert it using dot -Tformat filename, or you can pipe the output directly to | dot -Tx11 to see the generated graph.
I frequently use the Graphviz DOT format for checking whether my mental picture of data structure linkage matches the reality. I find it an extremely useful tool, and keep recommending it for anyone working with complex data structures.
To plot directed graphs try GraphViz (https://www.graphviz.org).
Alternatively you could use a tool like Gephi (https://gephi.org) if you are willing to write the data into a file in a manner compliant with one of their supported formats (https://gephi.org/users/supported-graph-formats/). GML looks pretty straight forward.
Related
I'm trying to update some old code which used to work with Graphviz 2.26 and iterated over all the nodes of a graph and did something with their names:
for (Agnode_t *n = agfstnode(graph); n; n = agnxtnode(graph, n)) {
... use n->name ...
}
However in recent (2.30+?) versions of Graphviz, cgraph library is used for node representation and it doesn't have name field in its Agnode_t struct.
I know about agnode() function which allows to lookup the node by name, but there doesn't seem to be any function to go in the other direction. Am I missing something or is there really no way to access the name of the existing node with cgraph?
You can use the function agnameof, which is listed in the "Generic Objects" section of the cgraph manpage:
char *agnameof(void*);
I'm currently working on a program that reads in text from standard input, creates a Huffman tree from the data, and then generates the Huffman codes for the symbols in the Huffman tree.
I'm able to create the Huffman tree, which consists of Tree Node structs that contain the symbol, the frequency of the symbol, the Huffman code for the symbol, and pointers to the let and right nodes. However, I'm kind of stuck on how to traverse the tree and modify each node's "code" according to where it is in the tree.
Essentially what I'm asking is how to traverse a binary tree while modifying a node's elements based on where it is in the tree.
Originally I tried something along the lines of:
void generateCodes (struct HuffTreeNode* root, unsigned long bitShift)
{
struct HuffTreeNode* current = root;
if (root != NULL)
{
current->code |= 0<<bitShift;
generateCodes(root->left,bitShift+1);
current->code |= 1<<bitShift;
generateCodes(root->right,bitShift+1);
}
}
However, that didn't work, and I'm kind of at a loss for what to try next. Any ideas?
You have formed the tree. SO now remains the traversing.
17
/\
/ 7
/ /\
10 / 3
/\ C4 /\
A6 B4 D1 E2
Now initilaly you just put them( the 0's or 1's) in array.Left child link - 1 right child link-0
So in the array you put a[currrent]=1 then call huffmancode(tree->left,current+1)
OR if going to right subtree a[current]=0 then call huffmancode(tree->right,current+1).
At reaching the leaf node print array.
Pseudocode: (printtree)
if (root->left exists)
{
a[current] = 0;
printtree(root->left, a, current + 1);
}
if (root->right exists)
{
a[current] = 1;
printtree(root->right, a,current + 1);
}
if (root is leaf)
{
print a[].
}
I assume that your tree is correctly (and optimally) built.
Each Huffman code is a path from the root to a leaf defining a symbol. You add a 0 when you traverse a left arc and a 1 when you traverse a right arc.
So, a way for getting a list of all the pairs symbol,code consists in traversing recursively the tree. You maintain the current path from the root to the current visited node and when you reach a leaf you generate the pair symbol (which would be stored in the leaf) and the current path.
A data structure for managing the current path is a stack.
So, an algorithm could be as follows:
void codes(struct Node * root, struct Stack * s)
{
if (is_leaf(root))
{
char symbol = // symbol stored in the node
char * code = // the reversed stack content; that is the code of current leaf
printf("symbol %c has code %s\n", symbol, code);
}
s->push('0');
codes(LLINK(root), s);
s->pop();
s->push('1');
codes(RLINK(root), s);
s->pop();
}
I leave to you the details of implementation of the stack and other meta-parts (is_leaf(), LLINK(root), ...).
You can improve the algorithm to generate bits
I hope will be helpful
I have this line:
0, 6 -> W(1) L(#);
or
\# -> #shift_right R W(1) L
I have to parse this line with flex, and take every element from every part of the arrow and put it in a list. I know how to match simple things, but I don't know how to match multiple things with the same rule. I'm not allowed to increase the limit for rules. I have a hint: parse the pieces, pieces will then combine, and I can use states, but I don't know how to do that, and I can't find examples on the net. Can someone help me?
So, here an example:
{
a -> W(b) #invert_loop;
b -> W(a) #invert_loop;
-> L(#)
}
When this section begins I have to create a structure for each line, where I put what is on the left of -> in a vector, those are some parameters, and the right side in a list, where each term is kinda another structure. For what is on the right side I wrote rules:
writex W([a-zA-Z0-9.#]) for W(anything).
So I need to parse these lines, so I can put the parameters and the structures int the big structure. Something like this(for the first line):
new bigStruc with param = a and list of struct = W(anything), #invert(it is a notation for a reference to another structure)
So what I need is to know how to parse these line so that I can create and create and fill these bigStruct, also using to rules for simple structure(i have all I need for these structures, but I don't how to parse so that I can use these methods).
Sorry for my English and I hope this time I was more clear on what I want.
Last-minute editing: I have matched the whole line with a rule, and then work on it with strtok. There is a way to use previous rules to see what type of structure i have to create? I mean not to stay and put a lots of if, but to use writex W([a-zA-Z0-9.#]) to know that i have to create that kind of structure?
Ok, lets see how this snippet works for you:
// these are exclusive rules, so they do not overlap, for inclusive rules, use %s
%x dataStructure
%x addRules
%%
<dataStructure>-> { BEGIN addRules; }
\{ { BEGIN dataStructure; }
<addRules>; { BEGIN dataStructure; }
<dataStructure>\} { BEGIN INITIAL; }
<dataStructure>[^,]+ { ECHO; } //this will output each comma separated token
<dataStructure>. { } //ignore anything else
<dataStructure>\n { } //ignore anything else
<addRules>[^ ]+ { ECHO; } //this will output each space separated rule
<addRules>. { } //ignore anything else
<addRules>\n { } //ignore anything else
%%
I'm not entirely sure what it it you want. Edit your original post to include the contents of your comments, with examples, and please structure your English better. If you can't explain what you want without contradicting yourself, I can't help you.
I am trying to extract Arabic proper names from a text using Stanford Parser.
for example if I have an input sentence:
تكريم سعد الدين الشاذلى
using the Arabic Stanford parser, the tree diagram will be:
(ROOT (NP (NN تكريم) (NP (NNP سعد) (DTNNP الدين) (NNP الشاذلى))))
I want to extract the proper name:
سعد الدين الشاذلى
which have the sub-tree:
(NP (NNP سعد) (DTNNP الدين) (NNP الشاذلى))
I have tried this: similar question
but there is some thing wrong in this line:
List<TaggedWord> taggedWords = (Tree) lp.apply(str);
the error in putting a tree type in a list of taggedword
another thing that I didnot understand that where could i use the suggested taggedYield() function
Any Ideas, please?
This is pretty basic Java with respect to the library, but what you want is:
Tree tree = lp.apply(str);
List<TaggedWord> taggedWords = tree.taggedYield();
for (TaggedWord tw : taggedWords) {
if (tw.tag().contains("NNP")) {
System.err.println(tw.word());
}
}
Some time ago we took over the responsibility of a legacy code base.
One of the quirks of this very badly structured/written code was that
it contained a number of really huge structs, each containing
hundreds of members. One of the many steps that we did was to clean
out as much of the code as possible that wasn't used, hence the need
to find unused structs/struct members.
Regarding the structs, I conjured up a combination of python, GNU
Global and ctags to list the struct members that are unused.
Basically, what I'm doing is to use ctags to generate a tags file,
the python-script below parses that file to locate all struct
members and then using GNU Global to do a lookup in the previously
generated global-database to see if that member is used in the code.
This approach have a number of quite serious flaws, but it sort of
solved the issue we faced and gave us a good start for further
cleanup.
There must be a better way to do this!
The question is: How to find unused structures and structure members
in a code base?
#!/usr/bin/env python
import os
import string
import sys
import operator
def printheader(word):
"""generate a nice header string"""
print "\n%s\n%s" % (word, "-" * len(word))
class StructFreqAnalysis:
""" add description"""
def __init__(self):
self.path2hfile=''
self.name=''
self.id=''
self.members=[]
def show(self):
print 'path2hfile:',self.path2hfile
print 'name:',self.name
print 'members:',self.members
print
def sort(self):
return sorted(self.members, key=operator.itemgetter(1))
def prettyprint(self):
'''display a sorted list'''
print 'struct:',self.name
print 'path:',self.path2hfile
for i in self.sort():
print ' ',i[0],':',i[1]
print
f=open('tags','r')
x={} # struct_name -> class
y={} # internal tags id -> class
for i in f:
i=i.strip()
if 'typeref:struct:' in i:
line=i.split()
x[line[0]]=StructFreqAnalysis()
x[line[0]].name=line[0]
x[line[0]].path2hfile=line[1]
for j in line:
if 'typeref' in j:
s=j.split(':')
x[line[0]].id=s[-1]
y[s[-1]]=x[line[0]]
f.seek(0)
for i in f:
i=i.strip()
if 'struct:' in i:
items=i.split()
name=items[0]
id=items[-1].split(':')[-1]
if id:
if id in y:
key=y[id]
key.members.append([name,0])
f.close()
# do frequency count
for k,v in x.iteritems():
for i in v.members:
cmd='global -a -s %s'%i[0] # -a absolute path. use global to give src-file for member
g=os.popen(cmd)
for gout in g:
if '.c' in gout:
gout=gout.strip()
f=open(gout,'r')
for line in f:
if '->'+i[0] in line or '.'+i[0] in line:
i[1]=i[1]+1
f.close()
printheader('All structures')
for k,v in x.iteritems():
v.prettyprint()
#show which structs that can be removed
printheader('These structs could perhaps be removed')
for k,v in x.iteritems():
if len(v.members)==0:
v.show()
printheader('Total number of probably unused members')
cnt=0
for k,v in x.iteritems():
for i in v.members:
if i[1]==0:
cnt=cnt+1
print cnt
Edit
As proposed by #Jens-Gustedt using the compiler is a good way to do it. I'm after a approach that can do a sort of "High Level" filtering before using the compiler-approach.
If these are only a few struct and if the code does no bad hacks of accessing a struct through another type... then you could just comment out all the fields of your first struct and let the compiler tell you.
Uncomment one used field after the other until the compiler is satisfied. Then once that compiles, to a good testing to ensure the precondition that there were no hacks.
Iterate over all struct.
Definitively not pretty, but at the end you'd have at least one person who knows the code a bit.
Use coverity. This is a wonderful tool to detect code flaws, but is a bit costly.
Although it is a very old post. But recently I did the same using python and gdb. I compiled following snippet of code with structure at the top of hierarchy and then using gdb did print type on the structure and re-cursed into its members.
#include <usedheader.h>
UsedStructureInTop *to_print = 0;
int main(){return 0;}
(gdb) p to_print
(gdb) $1 = (UsedStructureInTop *) 0x0
(gdb) pt UsedStructureInTop
type = struct StructureTag {
members displayed here line by line
}
(gdb)
Although my purpose is little different. It is to generate a header that contains only the structure UsedStructureInTop and its dependency types. There are compiler options to do this. But they do not remove unused/unlinked structures found in the included header files.
Under C rules, it's possible to access struct members via another structure which has a similar layout. That means that you can access struct Foo {int a; float b; char c; }; via struct Bar { int x; float y; }; (except of course for Foo::c).
Hence, your algorithm is potentially flawed. It's bloody hard to find what you want, which BTW is why C is hard to optimize.