Code covered by the BSD License  

Highlights from
Count Loops in a Graph

image thumbnail
from Count Loops in a Graph by Joseph Kirk
Calculates the number of loops in a graph consisting of nodes and edges

COUNT LOOPS IN A NETWORK

COUNT LOOPS IN A NETWORK

This code counts the number of loops (cycles) in a network (graph) that is composed of nodes and edges. It employs an iterative algorithm that transforms the network into a tree (the ILCA - Iterative Loop Counting Algorithm). This is a "brute force" technique as there are no known (to my knowledge anyway) algorithms for providing a good estimation.

AUTHOR: Joseph Kirk jdkirk630@gmail.com (c) 2007

USAGE: >> run_loops;

NOTES: Refer to the README and the DETAILS files for more info

Contents

STEP 1: OBTAIN A NETWORK (FROM FILE OR RANDOMLY GENERATED)

Button1 = questdlg('Pick a network type:','Network Type', ...
    'Edge List File','Random Network','Edge List File');
switch Button1
    case 'Edge List File'
        % READ NET FROM FILE
        edge_list = read_edge_list(); % prompt user to select an edge list file
        if isempty(edge_list)
            return
        end
        usnet = edge_list2net(edge_list); % format the edgelist for the loop counting process
        net = sort_net(usnet);
    case 'Random Network'
        % GENERATE RANDOM NET
        prompt = {' Enter number of NODES for the random network: ',' Enter number of EDGES for the random network: '};
        name = 'Random Network Setup';
        answer1 = inputdlg(prompt,name,1,{'15','25'});
        if isempty(answer1)
            return
        end
        num_nodes = str2double(cell2mat(answer1(1)));
        num_edges = str2double(cell2mat(answer1(2)));
        usnet = gen_rand_net(num_nodes,num_edges); % generate random network
        net = sort_net(usnet);
    otherwise
        return
end
num_nodes = length(net);
num_edges = calc_num_edges(net);
disp(['  Net:  nodes = ' num2str(num_nodes) ' edges = ' num2str(num_edges)]);
 The random net was generated after 36 modifications
  Net:  nodes = 15 edges = 25

STEP 2: PLOT NET (OPTIONAL)

Button2 = questdlg('Plot Graph?','Plot Graph','Yes','No','Yes');
switch Button2
    case 'Yes'
        figure; plot_net(net); % plot of the network
        title('Network');
    case 'No'
    otherwise
end

STEP 3: REDUCE NET (OPTIONAL)

Button3 = questdlg('Reduce Network?','Reduce Network','Yes','No','Yes');
switch Button3
    case 'Yes'
        net = reduce_net(net);     % removes all 1-connected nodes and their corresponding edges
        num_nodes = length(net);
        num_edges = calc_num_edges(net);
        disp(['   Reduced net:  nodes = ' num2str(num_nodes) ' edges = ' num2str(num_edges)]);
        Button4 = questdlg('Plot Reduced Graph?','Plot Graph','Yes','No','Yes');
        switch Button4
            case 'Yes'
                figure; plot_net(net); % plot of the reduced network
                title('Reduced Network');
            case 'No'
            otherwise
        end
    case 'No'
    otherwise
end
   Reduced net:  nodes = 13 edges = 23

STEP 4: SETUP (INITIALIZE THE STARTING NODE)

n = get_starting_node(net);         % give the path a nearly optimal starting node
path = net(n).node;               % initialize the path
current_edge = net(n).edges(1);   % initialize the first edge
loop_list = [];                   % initialize the loop list
iterations = 0;              % initialize the number of algorithm steps

STEP 5: COUNT LOOPS (SEARCH THE GRAPH USING THE ILCA)

prompt = {' Approximately how many loops do you expect? (Needed for waitbar progress) '};
name = 'Loop Count (Estimate)';
answer2 = inputdlg(prompt,name,1,{'1000'});
if ~isempty(answer2)
    num_est_loops = cell2mat(answer2);
else
    return
end
wb = waitbar(0,['Searching Tree for Loops ... ' num2str(0) ' found']);
while (length(path)>1 || ~isempty(current_edge))
    [net,path,current_edge,loop_list] = iterate_tree(net,path,current_edge,loop_list);
    iterations = iterations+1;
    waitbar(length(loop_list)/str2double(num_est_loops),wb,['Searching Tree for Loops ... ' num2str(length(loop_list)) ' found']);
end
close(wb);
num_loops = length(loop_list);
disp(['    It took ' num2str(iterations) ' steps to complete the ILCA']);
disp(['     There are ' num2str(num_loops) ' loops in the net']);
    It took 6865 steps to complete the ILCA
     There are 330 loops in the net

STEP 6: PLOT H-LOOPS DISTRIBUTION (NUMBER OF LOOPS OF LENGTH H)

Button5 = questdlg('Show N(h) Distribution?','Loop Distribution','Yes','No','Yes');
switch Button5
    case 'Yes'
        figure; plot_loop_dist(net,loop_list);
    case 'No'
    otherwise
end

STEP 7: SAVE THE NET TO A .TXT FILE (OPTIONAL)

prompt = {'Enter the name of the file (no file extension):'};
name = 'Save Net to TXT File';
answer3 = inputdlg(prompt,name,[1 50],{'net'});
if ~isempty(answer3)
    filename = cell2mat(answer);
    net2file(NET,[filename '.txt']);
end

STEP 8: SAVE THE LOOP LIST TO A .TXT OR .MAT FILE (OPTIONAL)

prompt = {'Enter the name of the file (no file extension):'};
name = 'Save Loops to TXT or MAT File';
answer4 = inputdlg(prompt,name,[1 50],{'looplist'});
filename = cell2mat(answer4);
if ~isempty(filename)
    Button = questdlg('Choose File Type:','File Type','TXT File','MAT File','TXT File');
    switch Button
        case 'TXT File'
            loops2file(loop_list,[filename '.txt']);
        case 'MAT File'
            eval(sprintf([filename ' = loop_list;']));
            eval(sprintf('save %s %s',filename,filename));
        otherwise
    end
end

Contact us at files@mathworks.com