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



#include "d:\scilab-4.0\routines\stack-c.h"
void bbv __PARAMS((int *a, int n, int m, int *b, int l,int *t,double *w0,double *ta,int *c,int *d,double *w,double *ew));

int intbbv(fname) 
char *fname;
{
    static int l1, m1, n1, l2, m2, n2, l3,m3,n3,m4,l4,l5,l6,l7,l8,l9;
    static int minlhs=0, maxlhs=4, minrhs=5, maxrhs=5; 
    static int tmp1,tmp2,tmp3;

    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, &m1, &l4);
    GetRhsVar(5, "d", &m1, &m1, &l5);

    //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;
    m3=tmp1+tmp3;
    CreateVar(6, "i", &m1, &m2, &l6);  
    CreateVar(7, "i", &m1, &m2, &l7);
    CreateVar(8, "d", &m1, &m3, &l8);
    CreateVar(9, "d", &m1, &m2, &l9);
    bbv(istk(l1), m1, m1, istk(l2),m1,istk(l3),stk(l4),stk(l5),istk(l6),istk(l7),stk(l8),stk(l9));
    /*  Return C (3)  */
    LhsVar(1) = 6;
    LhsVar(2)=  7;
    LhsVar(3)=  8;
    LhsVar(4)=  9;
    // LhsVar(3)=  8;

    return 0;
}




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



int Kmax_name;

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



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

struct base  node[40000]; 
double SS[40000];          

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

    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;
                q->weight=W0;
                p=node[i].next;
                if (p!=NULL) {
                    while (p->next!=NULL) {
                        p->weight=W0;
                        p=p->next; 
                    }         
                    p->weight=W0;
                    p->next=q;
                } else
                    node[i].next=q;        
                node[i].nei_num++;
            }
        }
    }
    for (i=0;i<M0;i++)
        SS[i]=node[i].nei_num*W0;



}



void evolve(int M0,int M,int T,int j,double W0,double ta)          
{
    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++)
        SS[s]=0;


    for (s=0;s<M0+j-1;s++) {
        struct neinode *ww=node[s].next;
        while (ww!=NULL) {
            SS[s]+=ww->weight;
            ww=ww->next;    //计算s 
        }
    }


    for (s=0;s<M0+j-1;s++) {
        ssk[s]=k;
        k+=SS[s];
    }


    for (rr=0;rr<M0+j-1;rr++) { //时刻j每一个顶点的p
        ssk[rr]=(double)ssk[rr]/k;
    }

//	 printf("%lf\\\\\\",ssk[M0+j-2]);
    ssk[M0+j-1]=1.0;
    m=0;   
    while (m<M) {
        int temp;
        double frand=(double)rand()/RAND_MAX;//概率p
        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) {
            //加入一个顶点 
            m++;
            r=(struct neinode *)malloc(sizeof(struct neinode));
            r->neiname=M0+j-1;
            r->next=NULL;
            r->weight=W0;  //开始重新分配权重 
            node[temp].nei_num++;
            t=node[temp].next;
            if (t!=NULL) {
                while (t->next!=NULL) {   //分配到所有的邻居结点 
                    t->weight+=ta*(t->weight)/SS[temp];
                    t=t->next;
                }
                t->weight+=ta*(t->weight)/SS[temp]; 
                t->next=r;
            } else {
                node[temp].next=r;
            }

            q=(struct neinode *)malloc(sizeof(struct neinode));
            q->neiname=temp;
            q->next=NULL;
            q->weight=W0;
            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;
            }
            SS[temp]+=W0;

        }
    }  




}


int *head;
int *tail;
double *edgeweight;

int edge;  
void  createbbv(int M0,int M,int T,double W0,double ta)
{
    int i,b,s;
    int index;
    int en=M0*(M0-1)/2+M*T;
    head=(int *) malloc(en * sizeof(int));
    tail=(int *) malloc(en * sizeof(int));
    edgeweight=(double *) malloc(en * sizeof(double));

    srand((unsigned) time(NULL)); 
    initial(M0,M,T,W0);
    edge=0;
    for (i=1;i<=T;i++) {
        evolve(M0,M,T,i,W0,ta);        
    }


    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;
        }
    }
    for (i=0;i<M0+T;i++)
        SS[i]=0;  

    index=0;
    for (s=0;s<M0+T;s++) {
        struct neinode *ww=node[s].next;
        while (ww!=NULL) {
            SS[s]+=ww->weight;
            if (s>(ww->neiname)) {
                edgeweight[index]=ww->weight;
//	  sciprint("%d %d %e \n",s,ww->neiname,ww->weight);
                index++;
            }
            ww=ww->next;    //计算s 

        }
    }








}


#define C(i) c[i]
#define D(i) d[i]
#define EW(i) ew[i]
void bbv(a,n,m,b,l,t,w0,ta,c,d,w,ew)
int a[],b[];
int c[],t[],d[];
int n,m,l;
double w0[],ta[],w[],ew[];
{
    int i;
    createbbv((*a),(*b),(*t),(*w0),(*ta));
    for (i=0;i<(edge);i++) {
        C(i)=head[i];
        D(i)=tail[i];
        EW(i)=edgeweight[i];

    }

    for (i=0;i<((*a)+(*t));i++) {
//	sciprint("%d \n",weight[i]);
        w[i]=SS[i];
    }

    free(head);
    free(tail);
    free(edgeweight);
}
