
% Combined Scripts
% Carlos Andres Devia
% 01.08.2022

% Network creation

% This script creates a small world network with 'Totalgents' agents



SP.TotalAgents = 100;
SP.num_top = 9;

clearvars -except SP
close all

Now = datetime('now');
time_stamp = datestr(Now, 'yyyymmddHHMMSS');

for model = 1:4

    switch model 
        case 1
            SP.ModelLabel = 'BC';
        case 2
            SP.ModelLabel = 'BEBA';
        case 3
            SP.ModelLabel = 'CB';
        case 4
            SP.ModelLabel = 'FJ';
    end

    
    disp(' ')
    disp(' ')

    disp([ 9 9 'Creating topologies for ' num2str(SP.TotalAgents) ' agents'])
    
    frac_con_array = 0.01:0.01:0.5;
    alpha_array = 0:0.05:1;
    Prob_bi_array = 0.1:0.1:0.9;
    
    NetworkTopology = cell(1,SP.num_top);
    NetworkTopology_Label = cell(1,SP.num_top);
    
    for id_topology = 1:SP.num_top
    
        if id_topology == 1
    
            disp([ 9 'Topology number ' num2str(id_topology) ' = Complete graph'])
            NetworkTopology_Label{id_topology} = 'Complete graph';
    
            % The first topology is a complete graph to recover the classic
            % bounded confidence model
            Adj_Mat = ones(SP.TotalAgents);
    
        elseif id_topology == 2
    
            disp([ 9 'Topology number ' num2str(id_topology) ' = Directed ring'])
            NetworkTopology_Label{id_topology} = 'Directed ring 1';
    
            % The second topology is a directed ring graph
            Adj_Mat = zeros(SP.TotalAgents);
            connections = 6; % This number of connections
    
            % Start creating a directed ring graph
            temp_row = [ones(1,connections), zeros(1,SP.TotalAgents - connections)];
            for id_row = 1:SP.TotalAgents
                Adj_Mat(id_row,:) = temp_row;
                temp_row = circshift(temp_row,1);
            end
    
            % Add self-edges
    
            for id_agent = 1:SP.TotalAgents
                Adj_Mat(id_agent,id_agent) = 1;
            end
    
        elseif id_topology == 3
    
            disp([ 9 'Topology number ' num2str(id_topology) ' = Directed ring'])
            NetworkTopology_Label{id_topology} = 'Directed ring 2';
    
            % The second topology is a directed ring graph
            Adj_Mat = zeros(SP.TotalAgents);
            connections = 11; % This number of connections
    
            % Start creating a directed ring graph
            temp_row = [ones(1,connections), zeros(1,SP.TotalAgents - connections)];
            for id_row = 1:SP.TotalAgents
                Adj_Mat(id_row,:) = temp_row;
                temp_row = circshift(temp_row,1);
            end
    
            % Add self-edges
    
            for id_agent = 1:SP.TotalAgents
                Adj_Mat(id_agent,id_agent) = 1;
            end
    
        elseif id_topology == 4
    
            disp([ 9 'Topology number ' num2str(id_topology) ' = Directed ring'])
            NetworkTopology_Label{id_topology} = 'Undirected ring';
    
            % The second topology is a directed ring graph
            Adj_Mat = zeros(SP.TotalAgents);
            connections = 6; % This number of connections
    
            % Start creating a directed ring graph
            temp_row = [ones(1,connections), zeros(1,SP.TotalAgents - connections)];
            for id_row = 1:SP.TotalAgents
                Adj_Mat(id_row,:) = temp_row;
                temp_row = circshift(temp_row,1);
            end
    
            % Add self-edges
    
            for id_agent = 1:SP.TotalAgents
                Adj_Mat(id_agent,id_agent) = 1;
            end
    
            % Make it symmetrical
    
            Adj_Mat = double((Adj_Mat + transpose(Adj_Mat))>0);
    
        elseif  id_topology == 5
    
            disp([ 9 'Topology number ' num2str(id_topology) ' = Small-world'])
            NetworkTopology_Label{id_topology} = 'Small-World';
    
            % The third topology is a small-world network with fixed parameters
    
            strongly_connected = 0;
            
            while ~strongly_connected
                
                frac_con = 0.1;
                alpha_net = 0.5;
                prob_bi_net = 0.5;
            
                Adj_Mat = SmallWorldNetwork(SP.TotalAgents, ceil(SP.TotalAgents*frac_con), alpha_net, prob_bi_net);
            
                % Check of the resulting digraph is strongly connected
            
                strong_bins = conncomp(digraph(transpose(Adj_Mat)),'Type','strong');
            
                if max(strong_bins) == 1
                    % There is only one strongly connected component
                    strongly_connected = 1;
                end
            
            end
        
            % Add self edge
            
            for id_agent = 1:size(Adj_Mat,2)
                Adj_Mat(id_agent,id_agent) = 1;
            end
    
    
        elseif  id_topology == 6
    
            disp([ 9 'Topology number ' num2str(id_topology) ' = Random network'])
            NetworkTopology_Label{id_topology} = 'Random network';
    
            % The fourth topology is a random network
    
            Adj_Mat = double(rand(SP.TotalAgents) > 0.8);
    
            % Add self-edges
    
            for id_agent = 1:SP.TotalAgents
                Adj_Mat(id_agent,id_agent) = 1;
            end
    
        elseif id_topology == 7
    
            disp([ 9 'Topology number ' num2str(id_topology) ' = Torus latiice'])
            NetworkTopology_Label{id_topology} = 'Torus lattice';
    
            % The fifth topology is a torus latice
    
            lado = sqrt(SP.TotalAgents);
    
            if lado ~= round(lado)
                disp('the square torus latice is not possible')
    
            else
    
                agent_id = reshape(1:(lado^2), lado, lado);
    
            end
    
            Adj_Mat = zeros((lado^2));
    
            x_pos = nan*ones(1,(lado^2));
            y_pos = nan*ones(1,(lado^2));
    
            for id_row = 1:lado
                for id_col = 1:lado
    
                    
    
                    Agent_1 = agent_id(id_row,id_col);
    
                    x_pos(Agent_1) = id_col;
                    y_pos(Agent_1) = id_row;
    
                    % Conectar arriba
                    if id_row > 1
                        new_row = id_row-1;
                    else
                        new_row = lado;
                    end
    
                    Agent_2 = agent_id(new_row,id_col);
                    Adj_Mat(Agent_1, Agent_2) = 1;
    
                    % Conectar abajo
                    if id_row < lado
                        new_row = id_row+1;
                    else
                        new_row = 1;
                    end
    
                    Agent_2 = agent_id(new_row,id_col);
                    Adj_Mat(Agent_1, Agent_2) = 1;
    
                    % Conectar derecha
                    if id_col < lado
                        new_col = id_col+1;
                    else
                        new_col = 1;
                    end
    
                    Agent_2 = agent_id(id_row,new_col);
                    Adj_Mat(Agent_1, Agent_2) = 1;
    
                    % Conectar izquierda
                    if id_col > 1
                        new_col = id_col-1;
                    else
                        new_col = lado;
                    end
    
                    Agent_2 = agent_id(id_row,new_col);
                    Adj_Mat(Agent_1, Agent_2) = 1;
    
                   
                end
            end
    
            % Add self-edges
    
            for id_agent = 1:SP.TotalAgents
                Adj_Mat(id_agent,id_agent) = 1;
            end
    
    
        elseif  id_topology == 8
    
            disp([ 9 'Topology number ' num2str(id_topology)  ' = Scale-Free network'])
            NetworkTopology_Label{id_topology} = 'Scale-Free';
    
            % The sixth topology is a scale-free network
    
            Adj_Mat = double(ScaleFreeNetwork(100, 1, [0 1 0 0 1;1 0 0 1 0;0 0 0 1 0;0 1 1 0 0;1 0 0 0 0] ));
    
            % Add self-edges
    
            for id_agent = 1:SP.TotalAgents
                Adj_Mat(id_agent,id_agent) = 1;
            end
    
        else
    
            disp([ 9 'Topology number ' num2str(id_topology)  ' = other'])
            NetworkTopology_Label{id_topology} = 'Small-World';
    
            % All the other topologies are small-world networks with random
            % parameters
    
            strongly_connected = 0;
            
            while ~strongly_connected
                
    %              frac_con = frac_con_array(randi(size(frac_con_array,2)))
    %              alpha_net = alpha_array(randi(size(alpha_array,2)))
    %              prob_bi_net = Prob_bi_array(randi(size(Prob_bi_array,2)))
    
                frac_con = 0.25;
                alpha_net = 0.55;
                prob_bi_net = 0.45;
            
                Adj_Mat = SmallWorldNetwork(SP.TotalAgents, ceil(SP.TotalAgents*frac_con), alpha_net, prob_bi_net);
            
                % Check of the resulting digraph is strongly connected
            
                strong_bins = conncomp(digraph(transpose(Adj_Mat)),'Type','strong');
            
                if max(strong_bins) == 1
                    % There is only one strongly connected component
                    strongly_connected = 1;
                end
            
            end
        
            % Add self edge
            
            for id_agent = 1:size(Adj_Mat,2)
                Adj_Mat(id_agent,id_agent) = 1;
            end
    
        end
        
        NetworkTopology{id_topology} = Adj_Mat;
    
        
    
    end
        
    
    InteractionNetworks = cell(1,SP.num_networks);
    
    id_network = 0;
    for id_topology = 1:SP.num_top
    
        Adj_Mat = NetworkTopology{id_topology}; % Load the network topology
    
        switch SP.ModelLabel
            case 'BC'
                BC_InitialNetworkCreation    
            case 'BEBA'
                BEBA_InitialNetworkCreation    
            case 'CB'
                CB_InitialNetworkCreation    
            case 'FJ'
                FJ_InitialNetworkCreation    
        end
        
    
    end
    
    save([ SP.ModelLabel '_InitialNetworks_' num2str(SP.TotalAgents) '_agents.mat'], 'InteractionNetworks', 'NetworkTopology', 'time_stamp')

end


