1 | #include "mltaln.h" |
---|
2 | #define DEBUG 0 |
---|
3 | |
---|
4 | |
---|
5 | void topolcpy( int s1[], int s2[], int *mpt1, int *mpt2 ) |
---|
6 | { |
---|
7 | int i; |
---|
8 | |
---|
9 | *mpt1 = *mpt2; |
---|
10 | for( i=0; i<*mpt2; i++ ) |
---|
11 | { |
---|
12 | s1[i] = s2[i]; |
---|
13 | } |
---|
14 | } |
---|
15 | |
---|
16 | void topolcat( int s1[], int s2[], int *mpt1, int *mpt2 ) |
---|
17 | { |
---|
18 | int i; |
---|
19 | |
---|
20 | for( i=*mpt1; i<*mpt1+*mpt2; i++ ) |
---|
21 | { |
---|
22 | s1[i] = s2[i-*mpt1]; |
---|
23 | } |
---|
24 | *mpt1 += *mpt2; |
---|
25 | } |
---|
26 | |
---|
27 | void topolsort( int m, int s[] ) |
---|
28 | { |
---|
29 | int i, j, im; |
---|
30 | int sm; |
---|
31 | |
---|
32 | for( j=0; j<m-1; j++ ) |
---|
33 | { |
---|
34 | sm = s[j]; im = j; |
---|
35 | for( i=j+1; i<m; i++ ) |
---|
36 | { |
---|
37 | if( s[i] < sm ) |
---|
38 | { |
---|
39 | sm = s[i]; |
---|
40 | im = i; |
---|
41 | } |
---|
42 | } |
---|
43 | s[im] = s[j]; s[j] = sm; |
---|
44 | } |
---|
45 | } |
---|
46 | |
---|
47 | void topolswap( int s1[], int s2[], int *mpt1, int *mpt2 ) |
---|
48 | { |
---|
49 | int i; |
---|
50 | int im; |
---|
51 | int b; |
---|
52 | b = *mpt1; *mpt1 = *mpt2; *mpt2 = b; |
---|
53 | im = MAX(*mpt1,*mpt2); |
---|
54 | for( i=0; i<im; i++ ) |
---|
55 | { |
---|
56 | b = s1[i]; s1[i] = s2[i]; s2[i] = b; |
---|
57 | /* |
---|
58 | printf( "s1[%d]=%d\ns2[%d]=%d\n", i, s1[i], i, s2[i] ); |
---|
59 | */ |
---|
60 | } |
---|
61 | } |
---|
62 | |
---|
63 | void reduc( double **mtx, int nseq, int im, int jm ) |
---|
64 | { |
---|
65 | int i; |
---|
66 | for( i=0; i<nseq; i++ ) |
---|
67 | { |
---|
68 | if( i==im || i==jm |
---|
69 | || mtx[MIN(i,im)][MAX(i,im)] == 9999.9 |
---|
70 | || mtx[MIN(i,jm)][MAX(i,jm)] == 9999.9 |
---|
71 | ) continue; |
---|
72 | mtx[MIN(i,im)][MAX(i,im)] |
---|
73 | = 0.5 * ( mtx[MIN(i,im)][MAX(i,im)] + mtx[MIN(i,jm)][MAX(i,jm)] |
---|
74 | - mtx[MIN(im,jm)][MAX(im,jm)] ); |
---|
75 | mtx[MIN(i,jm)][MAX(i,jm)] = 9999.9; |
---|
76 | } |
---|
77 | mtx[MIN(im,jm)][MAX(im,jm)] = 9999.9; |
---|
78 | } |
---|
79 | |
---|
80 | |
---|
81 | void nj( int nseq, double **omtx, int ***topol, double **dis ) |
---|
82 | { |
---|
83 | int i, j, l, n, m; |
---|
84 | int count; |
---|
85 | double r[M]; |
---|
86 | double t; |
---|
87 | double s, sm; |
---|
88 | double totallen = 0.0; |
---|
89 | int im=0, jm=0; |
---|
90 | double len1, len2; |
---|
91 | #if 1 |
---|
92 | static char **par = NULL; |
---|
93 | static double **mtx = NULL; |
---|
94 | static int **mem = NULL; |
---|
95 | if( par == NULL ) |
---|
96 | { |
---|
97 | par = AllocateCharMtx( njob, njob ); |
---|
98 | mtx = AllocateDoubleMtx( njob, njob ); |
---|
99 | mem = AllocateIntMtx( njob, 2 ); |
---|
100 | } |
---|
101 | #else |
---|
102 | char par[njob][njob]; |
---|
103 | double mtx[njob][njob]; |
---|
104 | int mem[njob][2]; |
---|
105 | #endif |
---|
106 | for( i=0; i<nseq; i++ ) for( j=0; j<nseq; j++ ) mtx[i][j] = omtx[i][j]; |
---|
107 | for( i=0; i<nseq; i++ ) for( j=0; j<nseq; j++ ) par[i][j] = 0; |
---|
108 | for( i=0; i<nseq; i++ ) par[i][i] = 1; |
---|
109 | // for( i=0; i<nseq; i++ ) for( j=0; j<2; j++ ) for( l=0; l<nseq+1; l++ ) topol[i][j][l] = -1; |
---|
110 | for( i=0; i<nseq; i++ ) for( j=0; j<2; j++ ) for( l=0; l<nseq; l++ ) topol[i][j][l] = -1; |
---|
111 | for( n=nseq, m=0; n>2; n--, m=nseq-n ) |
---|
112 | { |
---|
113 | t = 0.0; |
---|
114 | for( i=0; i<nseq-1; i++ ) for( j=0; j<nseq; j++ ) if( mtx[i][j] < 9999.9 ) |
---|
115 | t += mtx[i][j]; |
---|
116 | for( i=0; i<nseq; i++ ) |
---|
117 | { |
---|
118 | r[i] = 0.0; |
---|
119 | for( l=0; l<nseq; l++ ) |
---|
120 | if( ( l != i ) && ( mtx[MIN(i,l)][MAX(i,l)] < 9999.9 ) ) |
---|
121 | r[i] += mtx[MIN(i,l)][MAX(i,l)]; |
---|
122 | } |
---|
123 | sm = 9999.9; |
---|
124 | for( i=0; i<nseq-1; i++ ) for( j=i+1; j<nseq; j++ ) if( mtx[i][j] < 9999.9) |
---|
125 | { |
---|
126 | s = ( ( 2.0 * t - r[i] - r[j] + (n-2.0)*mtx[i][j] ) ) / ( 2.0*(n-2.0) ); |
---|
127 | if ( s < sm ) |
---|
128 | { |
---|
129 | sm = s; |
---|
130 | im = i; jm = j; |
---|
131 | } |
---|
132 | } |
---|
133 | len1 = ( (n-2)*mtx[im][jm] + r[im] - r[jm] ) / (2*(n-2)); |
---|
134 | len2 = ( (n-2)*mtx[im][jm] - r[im] + r[jm] ) / (2*(n-2)); |
---|
135 | |
---|
136 | #if DEBUG |
---|
137 | fprintf( stderr, "STEP-%3d %3d: L = %5.5f\n", m+1, im+1, len1 ); |
---|
138 | fprintf( stderr, " %3d: L = %5.5f\n", jm+1, len2 ); |
---|
139 | #endif |
---|
140 | |
---|
141 | totallen += len1; |
---|
142 | totallen += len2; |
---|
143 | |
---|
144 | dis[m][0] = len1; |
---|
145 | dis[m][1] = len2; |
---|
146 | |
---|
147 | for( l=0, count=0; l<nseq; l++ ) |
---|
148 | if( par[im][l] > 0 ) |
---|
149 | { |
---|
150 | topol[m][0][count] = l; |
---|
151 | count++; |
---|
152 | } |
---|
153 | mem[m][0] = count; |
---|
154 | for( l=0, count=0; l<nseq; l++ ) |
---|
155 | if( par[jm][l] > 0 ) |
---|
156 | { |
---|
157 | topol[m][1][count] = l; |
---|
158 | count++; |
---|
159 | } |
---|
160 | mem[m][1] = count; |
---|
161 | for( l=0; l<nseq; l++ ) |
---|
162 | par[im][l] += ( par[jm][l] > 0 ); |
---|
163 | if( n > 3 ) reduc( mtx, nseq, im, jm ); |
---|
164 | } |
---|
165 | for( i=0; i<nseq; i++ ) |
---|
166 | if( i!=im && i!=jm && mtx[MIN(i,im)][MAX(i,im)]<9999.9 ) |
---|
167 | break; |
---|
168 | len2 = ( mtx[MIN(i,im)][MAX(i,im)] - r[im] + r[i] ) / 2; |
---|
169 | |
---|
170 | /* |
---|
171 | printf(" %3d: L = %5.5f\n", i+1, len2 ); |
---|
172 | */ |
---|
173 | totallen += len2; |
---|
174 | |
---|
175 | dis[m][0] = len2; |
---|
176 | dis[m][1] = 0.0; |
---|
177 | for( l=0, count=0; l<nseq; l++ ) |
---|
178 | if( par[i][l] > 0 ) |
---|
179 | { |
---|
180 | topol[m][0][count] = l; |
---|
181 | count++; |
---|
182 | } |
---|
183 | mem[m][0] = count; |
---|
184 | /* |
---|
185 | printf( " total length == %f\n", totallen ); |
---|
186 | */ |
---|
187 | |
---|
188 | topolcpy( topol[nseq-2][1], topol[nseq-3][0], mem[nseq-2]+1, mem[nseq-3] ); |
---|
189 | topolcat( topol[nseq-2][1], topol[nseq-3][1], mem[nseq-2]+1, mem[nseq-3]+1 ); |
---|
190 | topolsort( mem[nseq-2][1], topol[nseq-2][1] ); |
---|
191 | |
---|
192 | if( topol[nseq-2][0][0] > topol[nseq-2][1][0] ) |
---|
193 | topolswap( topol[nseq-2][0], topol[nseq-2][1], mem[nseq-2], mem[nseq-2]+1 ); |
---|
194 | |
---|
195 | } |
---|