I'm using Matlab's SimBiology tool box to generate biograph (which are, just graphs).
When I'm trying to include a node which connects to itself, e.g:
g = [
0 1 0;
1 0 1;
0 0 1; % This one connects to itself.
]
I get the following warning message :
Warning: Self connecting nodes are not allowed, ignoring the diagonal of CM.
As my data sets include some self connecting nodes, I was wondering if this is a configurable feature.
Thanks!
Unfortunately biograph can not have self-connecting edges. If your purpose is only for visualization you could add some nodes with empty labels. Here is an example for a small graph and two self-connecting nodes:
cm = [0 1 1 0 0;1 0 0 1 1;1 0 1 0 0;0 0 0 0 1;1 0 1 0 1];
ids = {'M30931','L07625','K03454','M27323','M15390'};
sc = find(diag(cm));
cm = cm-diag(diag(cm));
n = size(cm,1);
m = numel(sc);
cm(n+m,n+m)=0;
cm(sub2ind([n+m,n+m],[sc;(1:m)'+n],[(1:m)'+n;sc]))=1;
ids((1:m)+n) = {' '};
bg = biograph(cm);
for i = 1:numel(bg.Nodes)
bg.Nodes(i).Label = ids{i};
if i>n
bg.Nodes(i).Shape = 'circle';
end
end
view(bg)
HTH
Lucio
Related
Does anyone have example code in gnuplot for a pie chart? I can't find any great example with a simple graph and the text around it and in it with the % signs that shows easily how much each part has of the circle.
Some example data:
Management frames 4596
Control frames 70173
Data frames 40347
TCP packets 36864
HTTP packets 525
ICMP packets 47
Total frames 115116
Updated:
After some years, I came again across this post, and I thought the code looked pretty messy. Therefore an attempt to improve and clean it up.
The following code is a bit different from the link I referenced above.
instead of a predefined color sequence or number codes in a separate list, the colors of the sections are given in the datablock (or datafile) next to the item/number by the names of predefined colors in gnuplot (see also https://stackoverflow.com/a/55736522/7295599). Because palette is used you can enter either colorname or hex-code, e.g. magenta or 0xff00ff.
the labels are aligned left or right depending on their position relative to 0.
you can choose the starting angle by PieStart and "rotation"-direction by PieDirection of the pie-chart
you can add individual radial and angular offsets for segments and labels
as you can see, there is no need for the total sum in the raw data. The total sum will be calculated automatically.
the reason why I define various functions f(n) which actually do not depend on n is to get the current values of other variables (at the time of calling the function) instead of passing a lot of parameters to the functions.
I hope you can adapt this code to your needs.
Code: (works with gnuplot>=5.0.0)
### pie-chart with labels with gnuplot
reset session
set size square
set angle degrees
set border 0
unset colorbox
unset tics
unset key
$Data <<EOD
# label value color SRoff SAoff LRoff LAoff
"Alpha" 85843 red 0 0 0 0
"Beta" 44000 green 0.2 45 0.2 0
"Gamma" 25399 blue 0 0 0 0
"Delta" 18451 magenta 0 0 0 0
"Epsilon" 12344 yellow 0 0 0 0
"Zeta" 11999 cyan 0 0 0 0
"Eta" 9000 orange 0 0 0 0
"Theta" 8500 0xb0f060 0 0 0.03 0
"Iota" 4711 dark-violet 0 0 0.12 0
EOD
colLabel = 1 # label
colValue = 2 # segment value
colColor = 3 # segment color, either color name or 0xRRGGBB value
colSegRoff = 4 # radial segment offset
colSegAoff = 5 # angular segment offset
colLabRoff = 6 # radial label offset
colLabAoff = 7 # angular label offset
# define a palette from colornames of the datafile/datablock in column colColor
set table $Dummy
myPalette = ''
plot $Data u (myPalette = myPalette.(myPalette eq '' ? '' : ', ').sprintf('%d "%s"',$0,strcol(colColor)),$0) with table
myPalette = '('.myPalette.')'
unset table
set palette defined #myPalette
stats $Data u colValue nooutput # get total sum from column colValue
TotalSum = STATS_sum
set xrange[-1.5:1.5]
set yrange[-1.5:1.5]
PieStart = 90 # 0 = 3 o'clock, 90 = 12 o'clock
PieDirection = -1 # -1 clockwise, 1 counterclockwise
Radius = 1.0
RadiusLabelOff = 0.05 # default radial label offset
SegPosX(n) = column(colSegRoff)*cos((a2+a1+column(colSegAoff))*0.5)
SegPosY(n) = column(colSegRoff)*sin((a2+a1+column(colSegAoff))*0.5)
LabPosX(n) = (Radius+RadiusLabelOff+column(colLabRoff))*cos((a2+a1+column(colLabAoff))*0.5)
LabPosY(n) = (Radius+RadiusLabelOff+column(colLabRoff))*sin((a2+a1+column(colLabAoff))*0.5)
a1=a2=PieStart
getAngles(n) = (a1=a2, a2=a2+sgn(PieDirection)*column(colValue)/TotalSum*360)
getLabel(n) = sprintf("%s %.1f%%", strcol(colLabel), column(colValue)/TotalSum*100)
set multiplot layout 2,1
plot $Data u (getAngles(0), SegPosX(0)):(SegPosY(0)):(Radius):(PieDirection<0?a2:a1):(PieDirection<0?a1:a2):($0) \
with circles fs solid 1.0 lc palette notitle,\
'' u ( getAngles(0), Align=LabPosX(0)):(LabPosY(0)): (Align>0? getLabel(0) : '') with labels font ",10" left, \
'' u ( getAngles(0), Align=LabPosX(0)):(LabPosY(0)): (Align<0? getLabel(0) : '') with labels font ",10" right
PieDirection = +1
a1=a2=PieStart
replot
unset multiplot
### end of code
Result:
for an homework I have to write xy+xz+yz using only NANDS port.
I will use the notation NAND(x,y) - or other types of bracket to make things clearer -, below my attempt and then an explanation for every step. I'd like to know if i'm doing this right and if there are better ways to do it.
My Solution
NAND[NAND(NAND(NAND(x,y),NAND(x,z)),NAND(NAND(x,y),NAND(x,z))),NAND(NAND(NAND(y,z),NAND(y,z)),NAND(NAND(y,z),NAND(y,z))))]`
I know this looks really impossible to read and keep track of. I'm sorry, didn't know how to make this more beautiful. Hope my explanation will clarify things.
I divided xy+xz+yz in two groups: xy+xz and yz
First Group:
xy+xz = NAND(NAND(x,y),NAND(xz)) = NOT[NOT(xy)*NOT(xz)] = xy+xz
Second Group:
yz = NAND(NAND(y,z),NAND(y,z)) = NOT(NOT(yz)*NOT(yz)) = yz (since yz+yz = yz)
Now I have to combine the first group with the second, for readibility I'll call the first group (in NAND as g1) and the second g2;
g1+g2= NAND[NAND(g1,g1),NAND(g2,g2)] = NOT[NOT(g1)*NOT(g2)] = g1+g2
So at the end:
xy+xz+yz= NAND[NAND(NAND(NAND(x,y),NAND(x,z)),NAND(NAND(x,y),NAND(x,z))),NAND(NAND(NAND(y,z),NAND(y,z)),NAND(NAND(y,z),NAND(y,z))))]
Is my reasoning right? There's a more easy way?
Thanks a lot guys
Your answer is correct (although you have some missing punctuation -- a couple commas and a parenthesis). You can confirm by generating a truth table of all possible outputs as so. I wrote a few lines of C code to confirm. As for your second question to whether there is an easier way, I don't know. Maybe someone else can help out.
x y z xy+xz+yz nands
------------------------------
0 0 0 0 0
0 0 1 0 0
0 1 0 0 0
0 1 1 1 1
1 0 0 0 0
1 0 1 1 1
1 1 0 1 1
1 1 1 1 1
I've been using GLPK to solve some mixed integer programming problems. Here's a sample input file in MathProg format:
set REACTIONS;
set REACTANTS;
param Ys {i in REACTANTS, j in REACTIONS};
param Gamma {i in REACTANTS, j in REACTIONS};
param eps;
param delt;
var w {i in REACTANTS} >=-delt <=delt;
var R0 {i in REACTIONS} >=0 <=1, integer;
var Rn {i in REACTIONS} >=0 <=1, integer;
minimize z: sum{i in REACTIONS} -Rn[i];
s.t. const1{i in REACTIONS} : sum{k in REACTANTS} w[k]*Gamma[k,i] <= delt*(1-R0[i]);
s.t. const2{i in REACTIONS} : -sum{k in REACTANTS} w[k]*Gamma[k,i] <= delt*(1-R0[i]);
s.t. const3{i in REACTIONS} : Rn[i] <= 1-R0[i];
s.t. const5{i in REACTIONS} : sum{k in REACTANTS} w[k]*Gamma[k,i] <= delt*(1-Rn[i])-eps;
s.t. const6{i in REACTIONS, j in REACTIONS: i <> j} : sum{k in REACTANTS} w[k]*(Ys[k,i]-Ys[k,j]) <= delt*(1-Rn[i]+Rn[j]+R0[j]);
data;
set REACTIONS:= 1 2 3 4 5 6;
set REACTANTS:= 1 2 3 4 5 6;
param Ys: 1 2 3 4 5 6:=
1 1 0 0 0 0 0
2 1 0 0 0 0 0
3 0 1 1 0 0 0
4 0 0 0 1 0 0
5 0 0 0 1 0 0
6 0 0 0 0 1 1;
param Gamma: 1 2 3 4 5 6:=
1 -1 1 0 0 0 1
2 -1 1 1 0 0 0
3 1 -1 -1 0 0 0
4 0 0 1 -1 1 0
5 0 0 0 -1 1 1
6 0 0 0 1 -1 -1;
param eps:=0.1;
param delt:=10;
end;
I've been running into performance problems for bigger problems of this type, and since SCIP claims to be several times faster than GLPK for MIP, it seems worth investigating. However, I haven't been able to make head or tail of the documentation when it comes to input file formats. SCIP's homepage says that it supports AMPL format, and the GLPK's homepagesays that MathProg is a subset of AMPL. Trying to feed the above file into SCIP 3.1.0 via scip -f file.nl returns the following error:
read problem <file.nl>
============
no reader for input file <file.nl> available
I'm not sure whether this is because I've failed to build SCIP with AMPL support, or something else. I found this blog post on building SCIP with AMPL support, but the instructions seem to be outdated as the source zip of SCIP 3.1.0 doesn't contain an interfaces folder.
So, I have two questions:
Is it possible to get SCIP to recognise my MathProg input as is?
If not, can anyone advise on how to convert it to a recognised format? An automated method would be preferable, as I don't really want to have to learn yet another format, but a manual method would be better than nothing.
Thanks for any help and apologies for my ignorance!
As I indicated in my comment above, the Ampl-interface is still included in the SCIP-distribution, and you should be able to compile it and read your problem
as documented in the excellent blog post you cite.
If you feel tempted to try different file formats, I see two options for you:
use glpk for translating your problem into a file format that is recognizable by SCIP. I found methods glp_write_mps() and glp_write_lp. SCIP can read both .lp and .mps-files. Make sure that you use exactly these file extensions, because SCIP doesn't recognize files in .lp-format but ending with .txt instead.
Use Zimpl to formulate your problems instead. The two formats of Zimpl and Ampl are strikingly similar, see the documentation for examples and further reference. Problem descriptions in Zimpl can be translated into .lp-format or read directly by SCIP, if you compile SCIP with the ZIMPL=true-option, which is the default.
Anybody can help me on this? Suppose the "p" is totally exogenous and following a uniform distribution. Then I want to generate "z", which is a TRUE(=1) or FALSE(=0) dummy, and has the property that the summation of each three elements (1-3, 4-6, 7-9,..., 58-60) in "z" should be greater than 0.
For example, if I get a "z" like {1 0 0 1 1 0 0 0 0 0 1 0...}, I hope to repeat the loop again ( since sum(z[7:9])=0 ) to draw a different "error" until I get a new "z" like {1 1 0 0 0 1 0 1 0 1 0 0...} where all summations for each three elements are greater than 0. The code I use is as follows. Where am I wrong?
set.seed(005)
p<-runif(60, 0, 1)
for (i in 1:20) {
repeat {
error= -0.2*log((1/runif(60, 0, 1))-1) # a random component
z=(p<0.5+error) # TRUE/FALSE condition
z=replace(z, z==TRUE, 1) # replace z to 1 if z is true, else z=0
if (sum(z[(3*i-2):(3*i)])>0) {break}
}
}
Your for loop generates a new z for every i. I don't think that's what you're trying to do. From what I can understand, you're trying to generate a new z and then use a for loop with the counter i to check for sums of three consecutive elements. If so, then you need to have one loop to generate new zs, and then another one inside this loop which checks for the sum of three consecutive elements.
I think this does what you want. But when I run it it seems unlikely that you will get a satisfactory z soon.
set.seed(005)
p<-runif(60, 0, 1)
invalidentriesexist =1
while(invalidentriesexist == 1) {
error = -0.2*log((1/runif(60, 0, 1))-1) # a random component
z=(p<0.5+error) # TRUE/FALSE condition
z=replace(z, z==TRUE, 1) # replace z to 1 if z is true, else z=0
z=replace(z, z==FALSE, 0) # replace z to 1 if z is true, else z=0
invalidentriesexist = 0
i = 1
while ( i <=20 & invalidentriesexist == 0 ) {
invalidentriesexist = 0
if (sum(z[((3*i)-2):(3*i)])==0) {invalidentriesexist = 1}
cat(i,'\n')
cat(invalidentriesexist,'\n')
cat(paste(z,collapse = ","),'\n')
cat(z[((3*i)-2):(3*i)],'\n\n')
i = i + 1
}
}
Note that a graph is represented as an adjacency list.
I've heard of 2 approaches to find a cycle in a graph:
Keep an array of boolean values to keep track of whether you visited a node before. If you run out of new nodes to go to (without hitting a node you have already been), then just backtrack and try a different branch.
The one from Cormen's CLRS or Skiena: For depth-first search in undirected graphs, there are two types of edges, tree and back. The graph has a cycle if and only if there exists a back edge.
Can somebody explain what are the back edges of a graph and what's the diffirence between the above 2 methods.
Thanks.
Update:
Here's the code to detect cycles in both cases. Graph is a simple class that represents all graph-nodes as unique numbers for simplicity, each node has its adjacent neighboring nodes (g.getAdjacentNodes(int)):
public class Graph {
private int[][] nodes; // all nodes; e.g. int[][] nodes = {{1,2,3}, {3,2,1,5,6}...};
public int[] getAdjacentNodes(int v) {
return nodes[v];
}
// number of vertices in a graph
public int vSize() {
return nodes.length;
}
}
Java code to detect cycles in an undirected graph:
public class DFSCycle {
private boolean marked[];
private int s;
private Graph g;
private boolean hasCycle;
// s - starting node
public DFSCycle(Graph g, int s) {
this.g = g;
this.s = s;
marked = new boolean[g.vSize()];
findCycle(g,s,s);
}
public boolean hasCycle() {
return hasCycle;
}
public void findCycle(Graph g, int v, int u) {
marked[v] = true;
for (int w : g.getAdjacentNodes(v)) {
if(!marked[w]) {
marked[w] = true;
findCycle(g,w,v);
} else if (v != u) {
hasCycle = true;
return;
}
}
}
}
Java code to detect cycles in a directed graph:
public class DFSDirectedCycle {
private boolean marked[];
private boolean onStack[];
private int s;
private Graph g;
private boolean hasCycle;
public DFSDirectedCycle(Graph g, int s) {
this.s = s
this.g = g;
marked = new boolean[g.vSize()];
onStack = new boolean[g.vSize()];
findCycle(g,s);
}
public boolean hasCycle() {
return hasCycle;
}
public void findCycle(Graph g, int v) {
marked[v] = true;
onStack[v] = true;
for (int w : g.adjacentNodes(v)) {
if(!marked[w]) {
findCycle(g,w);
} else if (onStack[w]) {
hasCycle = true;
return;
}
}
onStack[v] = false;
}
}
Answering my question:
The graph has a cycle if and only if there exists a back edge. A back edge is an edge that is from a node to itself (selfloop) or one of its ancestor in the tree produced by DFS forming a cycle.
Both approaches above actually mean the same. However, this method can be applied only to undirected graphs.
The reason why this algorithm doesn't work for directed graphs is that in a directed graph 2 different paths to the same vertex don't make a cycle. For example: A-->B, B-->C, A-->C - don't make a cycle whereas in undirected ones: A--B, B--C, C--A does.
Find a cycle in undirected graphs
An undirected graph has a cycle if and only if a depth-first search (DFS) finds an edge that points to an already-visited vertex (a back edge).
Find a cycle in directed graphs
In addition to visited vertices we need to keep track of vertices currently in recursion stack of function for DFS traversal. If we reach a vertex that is already in the recursion stack, then there is a cycle in the tree.
Update:
Working code is in the question section above.
For the sake of completion, it is possible to find cycles in a directed graph using DFS (from wikipedia):
L ← Empty list that will contain the sorted nodes
while there are unmarked nodes do
select an unmarked node n
visit(n)
function visit(node n)
if n has a temporary mark then stop (not a DAG)
if n is not marked (i.e. has not been visited yet) then
mark n temporarily
for each node m with an edge from n to m do
visit(m)
mark n permanently
unmark n temporarily
add n to head of L
I think the above code works only for a connected digraph since we start dfs from the source node only, for if the digraph is not connected there may be a cycle in the other component which may go unnoticed!
Here is the code I've written in C based on DFS to find out whether a given undirected graph is connected/cyclic or not. with some sample output at the end. Hope it'll be helpful :)
#include<stdio.h>
#include<stdlib.h>
/****Global Variables****/
int A[20][20],visited[20],count=0,n;
int seq[20],connected=1,acyclic=1;
/****DFS Function Declaration****/
void DFS();
/****DFSearch Function Declaration****/
void DFSearch(int cur);
/****Main Function****/
int main()
{
int i,j;
printf("\nEnter no of Vertices: ");
scanf("%d",&n);
printf("\nEnter the Adjacency Matrix(1/0):\n");
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&A[i][j]);
printf("\nThe Depth First Search Traversal:\n");
DFS();
for(i=1;i<=n;i++)
printf("%c,%d\t",'a'+seq[i]-1,i);
if(connected && acyclic) printf("\n\nIt is a Connected, Acyclic Graph!");
if(!connected && acyclic) printf("\n\nIt is a Not-Connected, Acyclic Graph!");
if(connected && !acyclic) printf("\n\nGraph is a Connected, Cyclic Graph!");
if(!connected && !acyclic) printf("\n\nIt is a Not-Connected, Cyclic Graph!");
printf("\n\n");
return 0;
}
/****DFS Function Definition****/
void DFS()
{
int i;
for(i=1;i<=n;i++)
if(!visited[i])
{
if(i>1) connected=0;
DFSearch(i);
}
}
/****DFSearch Function Definition****/
void DFSearch(int cur)
{
int i,j;
visited[cur]=++count;
seq[count]=cur;
for(i=1;i<count-1;i++)
if(A[cur][seq[i]])
acyclic=0;
for(i=1;i<=n;i++)
if(A[cur][i] && !visited[i])
DFSearch(i);
}
Sample Output:
majid#majid-K53SC:~/Desktop$ gcc BFS.c
majid#majid-K53SC:~/Desktop$ ./a.out
************************************
Enter no of Vertices: 10
Enter the Adjacency Matrix(1/0):
0 0 1 1 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 1 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0 0 0
The Depdth First Search Traversal:
a,1 c,2 d,3 f,4 b,5 e,6 g,7 h,8 i,9 j,10
It is a Not-Connected, Cyclic Graph!
majid#majid-K53SC:~/Desktop$ ./a.out
************************************
Enter no of Vertices: 4
Enter the Adjacency Matrix(1/0):
0 0 1 1
0 0 1 0
1 1 0 0
0 0 0 1
The Depth First Search Traversal:
a,1 c,2 b,3 d,4
It is a Connected, Acyclic Graph!
majid#majid-K53SC:~/Desktop$ ./a.out
************************************
Enter no of Vertices: 5
Enter the Adjacency Matrix(1/0):
0 0 0 1 0
0 0 0 1 0
0 0 0 0 1
1 1 0 0 0
0 0 1 0 0
The Depth First Search Traversal:
a,1 d,2 b,3 c,4 e,5
It is a Not-Connected, Acyclic Graph!
*/
Offering an observation with regards to a subset of the problem here: a connected undirected graph will have a cycle if num_edges >= num_nodes.
UPDATE: Also offering Python code for detecting cycles in an undirected graph using DFS. Would greatly appreciate help in optimizing this.
def detect_cycle(graph, root):
# Create an empty stack
stack = []
# Track visited nodes
visited = [False] * graph.num_nodes
# Track the order of traversal
traversal = []
# Track parents of traversed nodes
parent = [None] * graph.num_nodes
# Begin Traversal
stack.append(root)
parent[root] = root
while len(stack) > 0:
# Pop the stack
node = stack.pop()
if not visited[node]:
visited[node] = True
traversal.append(node)
# Check the neighbors for visited nodes, or continue traversal
for neighbor in graph.edges[node]:
if not visited[neighbor]:
stack.append(neighbor)
parent[neighbor] = node
# If the neighbor is visited, check for back edge
# If a back edge exists, neighbor will have been visited before
# the parent of the current node
elif traversal.index(neighbor) < traversal.index(parent[node]):
return (f'Cycle at node {node}!')
return ('Acyclic graph!')