//Create by Wubo
//Revise on 08/25/06 03:32



#include "d:\scilab-4.0\routines\stack-c.h"
void sba __PARAMS((int *a, int n, int m, int *b, int l,int *t,double *assort,int nn,int mm,double *k0,double *exp,int *c,int *d));

int intsba(fname) 
char *fname;
{
    static int l1, m1, n1, l2, m2, n2, l3,m3,n3,l4,l5,l6,l7,l8;
    static int minlhs=0, maxlhs=2, minrhs=6, maxrhs=6;   //why the minlhs must equal zero??
    static int tmp1,tmp2,tmp3;

    /* Check number of inputs (rhs=2) and outputs (lhs=1) */
    CheckRhs(minrhs,maxrhs) ;
    CheckLhs(minlhs,maxlhs) ;
    //m2=10;
    GetRhsVar(1, "i", &m1, &m1, &l1);   //the following sentence must be wrote together!!!! 
    GetRhsVar(2, "i", &m1, &m1, &l2);   
    GetRhsVar(3, "i", &m1, &m1, &l3);
    GetRhsVar(4, "d", &m1, &n1, &l4);
    GetRhsVar(5, "d", &m1, &n1, &l5);
    GetRhsVar(6, "d", &m1, &m1, &l6); 
    //sciprint("%i\n", *(istk(l1)));
    tmp1=*istk(l1);
    tmp2=*istk(l2);
    tmp3=*istk(l3);
    m2=tmp1*(tmp1-1)/2+tmp2*tmp3;  //Calculate the edge number;
    CreateVar(7, "i", &m1, &m2, &l7);  
    CreateVar(8, "i", &m1, &m2, &l8);
    sba(istk(l1), m1, m1, istk(l2),m1,istk(l3),stk(l4),m1,n1,stk(l5),stk(l6),istk(l7),istk(l8));
    /*  Return C (3)  */
    LhsVar(1) = 7;
    LhsVar(2)=  8;
    return 0;
}




#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>



int Kmax_name;

struct neinode {
    int neiname;
    struct neinode *next;
};



struct base {
    int nei_num;
    struct neinode *next;
};

struct base  node[40000];           

void initial(int M0,int M,int T)                    
{
    int k,i,j;
    for (k=0;k<(M0+T);k++) {
        node[k].nei_num=0;
        node[k].next=NULL;

    }

    for (i=0;i<M0;i++) {
        struct neinode *p;      
        for (j=0;j<M0;j++) {
            if (j!=i) {
                struct neinode *q;
                q=(struct neinode*)malloc(sizeof(struct neinode));
                q->neiname=j;              
                q->next=NULL;
                p=node[i].next;
                if (p!=NULL) {
                    while (p->next!=NULL)
                        p=p->next;         
                    p->next=q;
                } else
                    node[i].next=q;        
                node[i].nei_num++;
            }
        }
    }



}

// mssort[i]=assort[i];
// mk0[i]=k0[i]; 

double *massort;
double *mk0;

void evolve(int M0,int M,int T,int j,double exp)          
{
    double k;
    double ssk[40000];
    int s,rr,m,k1,flag;
    struct neinode *p2;
    struct neinode *r,*t;
    struct neinode *q,*p;
    node[M0+j-1].nei_num=0;
    node[M0+j-1].next=NULL;
    k=0;



    for (s=0;s<M0+j-1;s++) {
        ssk[s]=k;
        k+=pow(node[s].nei_num*massort[s]+mk0[s],exp);
    }


    for (rr=0;rr<M0+j-1;rr++) {
        ssk[rr]=(double)ssk[rr]/k;
    }

    ssk[M0+j-1]=1.0;
    m=0;
    while (m<M) {
        int temp;
        double frand=(double)rand()/RAND_MAX;
        for (k1=0;k1<M0+j-1;k1++) {
            if (frand>=ssk[k1] && frand<ssk[k1+1]) {
                temp=k1;
                break;
            } else {
                if (frand==1.0) {
                    temp=M0+j-2;
                    break;
                }
            }
        }

        flag=1;
        p2=node[temp].next;
        while (p2!=NULL) {
            if (p2->neiname==M0+j-1) {
                flag=0;
                break;
            }
            p2=p2->next;
        }
        if (flag) {
            if (j%1000==0)
                printf("%d\n",j);
            m++;

            r=(struct neinode *)malloc(sizeof(struct neinode));
            r->neiname=M0+j-1;
            r->next=NULL;
            node[temp].nei_num++;
            t=node[temp].next;
            if (t!=NULL) {
                while (t->next!=NULL)
                    t=t->next;
                t->next=r;
            } else {
                node[temp].next=r;
            }


            q=(struct neinode *)malloc(sizeof(struct neinode));
            q->neiname=temp;
            q->next=NULL;
            node[M0+j-1].nei_num++;
            p=node[M0+j-1].next;
            if (p!=NULL) {
                while (p->next!=NULL)
                    p=p->next;
                p->next=q;
            } else {
                node[M0+j-1].next=q;
            }
        }
    }


}


int *head;
int *tail;

int edge;


void  createba(int M0,int M,int T,double exp)
{
    int i,b;
    int en=M0*(M0-1)/2+M*T;
    head=(int *) malloc(en * sizeof(int));
    tail=(int *) malloc(en * sizeof(int));
    srand((unsigned) time(NULL)); 
    initial(M0,M,T);
    edge=0;
    for (i=1;i<=T;i++) {
        evolve(M0,M,T,i,exp);        
    }


    for (b=0;b<(T+M0);b++) {

        struct neinode *p;
        p=node[b].next;
        if (b%1000==0)
            sciprint("%i\n",b);
        while (p!=NULL) {
            if (p->neiname<b) {
                head[edge]=b+1;
                tail[edge]=p->neiname+1;
                //	sciprint("%i-->%i\n", head[edge],tail[edge]);
                edge++;
            }
            p=p->next;
        }
    }


}


//sba __PARAMS((int *a, int n, int m, int *b, int l,int *t,int *assort,int *k0,double *exp,int *c,int *d));


#define C(i) c[i]
#define D(i) d[i]
void sba(a,n,m,b,l,t,assort,nn,mm,k0,exp,c,d)
int a[],b[];
int c[],t[],d[];
double assort[],k0[],exp[];
int n,m,l;
int nn,mm;
{
    int i;
    massort=(double *) malloc(mm * sizeof(double));
    mk0=(double *) malloc(mm * sizeof(double));
    for (i=0;i<mm;i++) {
        massort[i]=assort[i];
        mk0[i]=k0[i];   

    }
    createba((*a),(*b),(*t),(*exp));
    for (i=0;i<(edge);i++) {
        C(i)=head[i];
        D(i)=tail[i];

    } 
    free(head);
    free(tail);
    free(massort);
    free(mk0);

}
