1. #include <iostream>
  2. #include <cstdio>
  3. #include <vector>
  4. #include <queue>
  5. #include <cstdio>
  6. #include <algorithm>
  7. #include <cstring>
  8. #include <sstream>
  9.  
  10. #define MAXN 256
  11.  
  12. using namespace std;
  13.  
  14. const int maxiterruim = 10000; /* Número máximo de iterações sem nenhuma melhora */
  15. const int maxiter = 50000; /* Número máximo de iterações */
  16. const double e = 0.05; /* Tamanho máximo do grupo = (1+e)*N/k */
  17. const double fatortaboo = 0.4; /* O tamanho da lista taboo é N * fatortaboo */
  18. const int maxncand = 100; /* Número máximo de vértices candidatos a mover */
  19.  
  20. int nvertice;
  21. int adj[MAXN][MAXN], peso[MAXN][MAXN];
  22. int pesosoma[MAXN];
  23.  
  24. /* Inicializa com uma partição aleatória */
  25. vector <int> particao_inicial(int k, int& custo, vector <int>& contrib, vector <int>& tamgrupo)
  26. {
  27. const int n = nvertice;
  28. vector <int> particao = vector <int> (n, -1);
  29.  
  30. if (tamgrupo.size() != k)
  31. tamgrupo = vector <int> (k, 0);
  32.  
  33. /* Vértices sem partição atribuída */
  34. vector <int> faltam = vector <int> (n, -1);
  35. for (int i = 0; i < n; i++)
  36. faltam[i] = i;
  37.  
  38. /* Atribuindo aleatoriamente */
  39. for (int i = 0; i < k; i++) {
  40. int tam = n/k;
  41. if (i < (n%k))
  42. tam ++;
  43. for (int j = 0; j < tam; j++) {
  44. int escolhe = rand()%faltam.size();
  45. particao[faltam[escolhe]] = i;
  46.  
  47. swap(faltam[escolhe], faltam[faltam.size()-1]);
  48. faltam.pop_back();
  49. }
  50. tamgrupo[i] = tam;
  51. }
  52.  
  53. /* Custo da solução */
  54. if (contrib.size() != n)
  55. contrib = vector <int> (n, 0);
  56.  
  57. custo = 0;
  58. for (int i = 0; i < n; i++)
  59. for (int j = 0; j < n; j++)
  60. if (particao[i] != particao[j] && adj[i][j]) {
  61. custo += peso[i][j];
  62. contrib[i] += peso[i][j];
  63. }
  64. custo /= 2; /* Cada arestra foi contada duas vezes */
  65.  
  66. return particao;
  67. }
  68.  
  69. /* Qual a diferença de custo total se mover o vértice "i" do grupo atual "anterior" para o grupo "novo" */
  70. int movimento(int i, int novo, vector <int>& particao)
  71. {
  72. int ret = 0;
  73. for (int k = 0; k < nvertice; k++) {
  74. if (particao[k] == particao[i])
  75. ret += adj[i][k];
  76. if (particao[k] == novo)
  77. ret -= adj[i][k];
  78. }
  79.  
  80. return ret;
  81. }
  82.  
  83. void atualizar_contrib(int i, int novo, vector <int>& particao, vector <int>& contrib)
  84. {
  85. for (int k = 0; k < nvertice; k++) {
  86. if (particao[k] == particao[i]) {
  87. contrib[i] += adj[i][k];
  88. contrib[k] += adj[i][k];
  89. }
  90. if (particao[k] == novo) {
  91. contrib[i] -= adj[i][k];
  92. contrib[k] -= adj[i][k];
  93. }
  94. }
  95. }
  96.  
  97. vector <int> taboo_search_k_partition(int k, int& custo)
  98. {
  99. const int n = nvertice;
  100.  
  101. vector <int> melhor; /* Melhor solução */
  102. int customelhor; /* Custo dela */
  103.  
  104. vector <int> atual; /* Solução atual */
  105. int custoatual; /* E o custo dela */
  106.  
  107. int iter = 1, ultimamelhora = 1; /* Iteração atual e última vez que a solução melhorou */
  108.  
  109. vector <int> contrib(n, 0); /* Com quanto cada vértice contribue para o peso total da solução */
  110. deque <int> listataboo; /* Vértices que temporariamente não podem ser movidos (vértices taboo) */
  111. vector <int> taboo(n, 0); /* Se pertence a lista taboo ou não */
  112. const int T = (int)(n * fatortaboo); /* Tamanho da lista taboo */
  113.  
  114. vector <int> tamgrupo(n, 0); /* Tamanho de cada grupo */
  115. const int maxgtam = (int)((1.0+e)*n/k); /* Tamanho máximo de cada grupo */
  116.  
  117. atual = particao_inicial(k, custoatual, contrib, tamgrupo);
  118. melhor = atual;
  119. customelhor = custoatual;
  120.  
  121. printf("Custo inicial: %d\n", custoatual);
  122.  
  123. while (iter-ultimamelhora <= maxiterruim && iter <= maxiter) {
  124. vector <pair <double, int> > potcands; /* Candidatos em potencial */
  125.  
  126. for (int i = 0; i < n; i++)
  127. if (!taboo[i])
  128. potcands.push_back(make_pair(1.0*contrib[i]/pesosoma[i], i));
  129.  
  130. partial_sort(potcands.begin(), min(potcands.end(), potcands.begin()+maxncand), potcands.end(), greater <pair <int, int> >());
  131.  
  132. int mindiff = 2000000000; /* Inf */
  133. int ncand = min((int)potcands.size(), maxncand);
  134. pair <int, int> best = make_pair(-1, -1);
  135.  
  136. for (int i = 0; i < ncand; i++) {
  137. int cand = potcands[i].second;
  138. for (int j = 0; j < k; j++)
  139. if (tamgrupo[j] < maxgtam) {
  140. int diff = movimento(cand, j, atual);
  141. if (diff < mindiff) {
  142. mindiff = diff;
  143. best = make_pair(cand, j);
  144. }
  145. }
  146. }
  147.  
  148. if (best == make_pair(-1, -1)){
  149. printf("\n");
  150. printf("Sem movimentos.\n");
  151. break;
  152. }
  153.  
  154. int i = best.first, j = best.second;
  155. int anterior = atual[i];
  156.  
  157. int diff = movimento(i, j, atual);
  158. custoatual += diff;
  159. atual[i] = j;
  160. if (custoatual < customelhor) {
  161. customelhor = custoatual;
  162. melhor = atual;
  163. ultimamelhora = iter;
  164. printf("\nMELHORA: Custo atual: %d (iteracao %d)\n", custoatual, iter);
  165. }
  166. tamgrupo[anterior] --;
  167. tamgrupo[j] ++;
  168.  
  169. taboo[i] = 1;
  170. listataboo.push_back(i);
  171. if ((int)listataboo.size() > T) {
  172. int v = listataboo.front();
  173. listataboo.pop_front();
  174. taboo[v] = 0;
  175. }
  176.  
  177. atualizar_contrib(i, j, atual, contrib);
  178.  
  179. if (diff) {
  180. printf(" %lld ", custoatual);
  181. fflush(stdout);
  182. }
  183.  
  184. iter ++;
  185. }
  186. printf("\n");
  187. if (iter-ultimamelhora > maxiterruim)
  188. printf("Muito tempo sem melhora.\n");
  189. if (iter > maxiter)
  190. printf("Numero maximo de iteracoes atingido.\n");
  191.  
  192. custo = customelhor;
  193.  
  194. return melhor;
  195. }
  196.  
  197. char line[10240000];
  198. int main(int argc, char ** argv)
  199. {
  200. int k;
  201. printf("Teste.\n");
  202. system("pause");
  203. FILE * fin = fopen("input", "r");
  204. if (fin == NULL) {
  205. printf("Err.\n");
  206. system("pause");
  207. return 0;
  208.  
  209. }
  210. /* Tenta ai */
  211.  
  212. printf("ok.\n");
  213.  
  214. #if 1
  215. int narestra;
  216. fgets(line, 1024, fin);
  217. sscanf(line, "%d %d", &nvertice, &narestra);
  218.  
  219. const int n = nvertice;
  220.  
  221. memset(adj, 0, sizeof(adj));
  222. for (int i = 0; i < n; i++) {
  223. fgets(line, 1024, fin);
  224. istringstream iss(line);
  225. int j;
  226. pesosoma[i] = 0;
  227. while (iss >> j) {
  228. adj[i][j-1] = 1;
  229. pesosoma[i] += 1;
  230. }
  231. }
  232. for (int i = 0; i < n; i++)
  233. for (int j = 0; j < n; j++)
  234. if (adj[i][j])
  235. peso[i][j] = 1;
  236. else
  237. peso[i][j] = 0;
  238.  
  239. k = 10;
  240. #else /* Depois tem que atualizar isto aqui tambm */
  241. scanf("%d %d", &nvertice, &k);
  242.  
  243. const int n = nvertice;
  244.  
  245. for (int i = 0; i < n; i++)
  246. for (int j = 0; j < n; j++)
  247. scanf("%d", &adj[i][j]);
  248.  
  249. for (int i = 0; i < n; i++) {
  250. pesosoma[i] = 0;
  251. for (int j = 0; j < n; j++) {
  252. scanf("%d", &peso[i][j]);
  253. pesosoma[i] += peso[i][j];
  254. }
  255. }
  256. #endif
  257.  
  258. printf("Lido.\n");
  259. system("pause");
  260.  
  261. srand(time(NULL));
  262.  
  263. int custo;
  264. vector <int> part = taboo_search_k_partition(k, custo);
  265.  
  266. for (int j = 0; j < k; j++) {
  267. int tam = 0;
  268.  
  269. for (int i = 0; i < n; i++)
  270. if (part[i] == j)
  271. tam ++;
  272.  
  273. printf("Grupo %d (tamanho = %d):", j+1, tam);
  274. for (int i = 0; i < n; i++)
  275. if (part[i] == j)
  276. printf(" %d", i+1);
  277. printf("\n");
  278. }
  279. printf("Custo total: %lld\n", custo);
  280. while (1) {}
  281.  
  282. system("sleep 10");
  283. system("pause");
  284.  
  285. return 0;
  286. }
  287.