1. /**************************************************************************
  2. IMPLICIT.C of ZIB optimizer MCF, SPEC version
  3. This software was developed at ZIB Berlin. Maintenance and revisions
  4. solely on responsibility of Andreas Loebel
  5. Dr. Andreas Loebel
  6. Ortlerweg 29b, 12207 Berlin
  7. Konrad-Zuse-Zentrum fuer Informationstechnik Berlin (ZIB)
  8. Scientific Computing - Optimization
  9. Takustr. 7, 14195 Berlin-Dahlem
  10. Copyright (c) 1998-2000 ZIB.
  11. Copyright (c) 2000-2002 ZIB & Loebel.
  12. Copyright (c) 2003-2005 Andreas Loebel.
  13. **************************************************************************/
  14. /* LAST EDIT: Thu Feb 17 21:45:45 2005 by Andreas Loebel (boss.local.de) */
  15. /* $Id: implicit.c,v 1.20 2005/02/17 21:43:12 bzfloebe Exp $ */
  16. #include "implicit.h"
  17. #ifdef _PROTO_
  18. long resize_prob( network_t *net )
  19. #else
  20. long resize_prob( net )
  21. network_t *net;
  22. #endif
  23. {
  24. arc_t *arc;
  25. node_t *node, *stop, *root;
  26. size_t off;
  27. assert( net->max_new_m >= 3 );
  28. net->max_m += net->max_new_m;
  29. net->max_residual_new_m += net->max_new_m;
  30. #if defined AT_HOME
  31. printf( "\nresize arcs to %4ld MB (%ld elements a %d B)\n\n",
  32. net->max_m * sizeof(arc_t) / 0x100000,
  33. net->max_m,
  34. sizeof(arc_t) );
  35. fflush( stdout );
  36. #endif
  37. arc = (arc_t *) realloc( net->arcs, net->max_m * sizeof(arc_t) );
  38. if( !arc )
  39. {
  40. printf( "network %s: not enough memory\n", net->inputfile );
  41. fflush( stdout );
  42. return -1;
  43. }
  44. off = (size_t)arc - (size_t)net->arcs;
  45. net->arcs = arc;
  46. net->stop_arcs = arc + net->m;
  47. root = node = net->nodes;
  48. for( node++, stop = (void *)net->stop_nodes; node < stop; node++ )
  49. if( node->pred != root )
  50. node->basic_arc = (arc_t *)((size_t)node->basic_arc + off);
  51. return 0;
  52. }
  53. #ifdef _PROTO_
  54. void insert_new_arc( arc_t *new, long newpos, node_t *tail, node_t *head,
  55. cost_t cost, cost_t red_cost )
  56. #else
  57. void insert_new_arc( new, newpos, tail, head, cost, red_cost )
  58. arc_t *new;
  59. long newpos;
  60. node_t *tail;
  61. node_t *head;
  62. cost_t cost;
  63. cost_t red_cost;
  64. #endif
  65. {
  66. long pos;
  67. new[newpos].tail = tail;
  68. new[newpos].head = head;
  69. new[newpos].org_cost = cost;
  70. new[newpos].cost = cost;
  71. new[newpos].flow = (flow_t)red_cost;
  72. pos = newpos+1;
  73. while( pos-1 && red_cost > (cost_t)new[pos/2-1].flow )
  74. {
  75. new[pos-1].tail = new[pos/2-1].tail;
  76. new[pos-1].head = new[pos/2-1].head;
  77. new[pos-1].cost = new[pos/2-1].cost;
  78. new[pos-1].org_cost = new[pos/2-1].cost;
  79. new[pos-1].flow = new[pos/2-1].flow;
  80. pos = pos/2;
  81. new[pos-1].tail = tail;
  82. new[pos-1].head = head;
  83. new[pos-1].cost = cost;
  84. new[pos-1].org_cost = cost;
  85. new[pos-1].flow = (flow_t)red_cost;
  86. }
  87. return;
  88. }
  89. #ifdef _PROTO_
  90. void replace_weaker_arc( network_t *net, arc_t *new, node_t *tail, node_t *head,
  91. cost_t cost, cost_t red_cost )
  92. #else
  93. void replace_weaker_arc( net, new, tail, head, cost, red_cost )
  94. network *net;
  95. arc_t *new;
  96. node_t *tail;
  97. node_t *head;
  98. cost_t cost;
  99. cost_t red_cost;
  100. #endif
  101. {
  102. long pos;
  103. long cmp;
  104. new[0].tail = tail;
  105. new[0].head = head;
  106. new[0].org_cost = cost;
  107. new[0].cost = cost;
  108. new[0].flow = (flow_t)red_cost;
  109. pos = 1;
  110. cmp = (new[1].flow > new[2].flow) ? 2 : 3;
  111. while( cmp <= net->max_residual_new_m && red_cost < new[cmp-1].flow )
  112. {
  113. new[pos-1].tail = new[cmp-1].tail;
  114. new[pos-1].head = new[cmp-1].head;
  115. new[pos-1].cost = new[cmp-1].cost;
  116. new[pos-1].org_cost = new[cmp-1].cost;
  117. new[pos-1].flow = new[cmp-1].flow;
  118. new[cmp-1].tail = tail;
  119. new[cmp-1].head = head;
  120. new[cmp-1].cost = cost;
  121. new[cmp-1].org_cost = cost;
  122. new[cmp-1].flow = (flow_t)red_cost;
  123. pos = cmp;
  124. cmp *= 2;
  125. if( cmp + 1 <= net->max_residual_new_m )
  126. if( new[cmp-1].flow < new[cmp].flow )
  127. cmp++;
  128. }
  129. return;
  130. }
  131. #if defined AT_HOME
  132. #include
  133. double Get_Time( void )
  134. {
  135. struct timeval tp;
  136. struct timezone tzp;
  137. if( gettimeofday( &tp, &tzp ) == 0 )
  138. return (double)(tp.tv_sec) + (double)(tp.tv_usec)/1.0e6;
  139. else
  140. return 0.0;
  141. }
  142. static double wall_time = 0;
  143. #endif
  144. #ifdef _PROTO_
  145. long price_out_impl( network_t *net )
  146. #else
  147. long price_out_impl( net )
  148. network_t *net;
  149. #endif
  150. {
  151. long i;
  152. long trips;
  153. long new_arcs = 0;
  154. long resized = 0;
  155. long latest;
  156. long min_impl_duration = 15;
  157. register cost_t bigM = net->bigM;
  158. register cost_t head_potential;
  159. register cost_t arc_cost = 30;
  160. register cost_t red_cost;
  161. register cost_t bigM_minus_min_impl_duration;
  162. register arc_t *arcout, *arcin, *arcnew, *stop;
  163. register arc_t *first_of_sparse_list;
  164. register node_t *tail, *head;
  165. #if defined AT_HOME
  166. wall_time -= Get_Time();
  167. #endif
  168. bigM_minus_min_impl_duration = (cost_t)bigM - min_impl_duration;
  169. if( net->n_trips <= MAX_NB_TRIPS_FOR_SMALL_NET )
  170. {
  171. if( net->m + net->max_new_m > net->max_m
  172. &&
  173. (net->n_trips*net->n_trips)/2 + net->m > net->max_m
  174. )
  175. {
  176. resized = 1;
  177. if( resize_prob( net ) )
  178. return -1;
  179. refresh_neighbour_lists( net );
  180. }
  181. }
  182. #if !defined SPEC_STATIC
  183. else
  184. {
  185. if( net->m + net->max_new_m > net->max_m
  186. &&
  187. (net->n_trips*net->n_trips)/2 + net->m > net->max_m
  188. )
  189. {
  190. resized = 1;
  191. if( resize_prob( net ) )
  192. return -1;
  193. refresh_neighbour_lists( net );
  194. }
  195. }
  196. #endif
  197. arcnew = net->stop_arcs;
  198. trips = net->n_trips;
  199. arcout = net->arcs;
  200. for( i = 0; i < trips && arcout[1].ident == FIXED; i++, arcout += 3 );
  201. first_of_sparse_list = (arc_t *)NULL;
  202. for( ; i < trips; i++, arcout += 3 )
  203. {
  204. if( arcout[1].ident != FIXED )
  205. {
  206. arcout->head->firstout->head->arc_tmp = first_of_sparse_list;
  207. first_of_sparse_list = arcout + 1;
  208. }
  209. if( arcout->ident == FIXED )
  210. continue;
  211. head = arcout->head;
  212. latest = head->time - arcout->org_cost
  213. + (long)bigM_minus_min_impl_duration;
  214. head_potential = head->potential;
  215. arcin = first_of_sparse_list->tail->arc_tmp;
  216. while( arcin )
  217. {
  218. tail = arcin->tail;
  219. if( tail->time + arcin->org_cost > latest )
  220. {
  221. arcin = tail->arc_tmp;
  222. continue;
  223. }
  224. red_cost = arc_cost - tail->potential + head->potential;
  225. if( red_cost < 0 )
  226. {
  227. if( new_arcs < net->max_residual_new_m )
  228. {
  229. insert_new_arc( arcnew, new_arcs, tail, head,
  230. arc_cost, red_cost );
  231. new_arcs++;
  232. }
  233. else if( (cost_t)arcnew[0].flow > red_cost )
  234. replace_weaker_arc( net, arcnew, tail, head,
  235. arc_cost, red_cost );
  236. }
  237. arcin = tail->arc_tmp;
  238. }
  239. }
  240. if( new_arcs )
  241. {
  242. arcnew = net->stop_arcs;
  243. net->stop_arcs += new_arcs;
  244. stop = (void *)net->stop_arcs;
  245. if( resized )
  246. {
  247. for( ; arcnew != stop; arcnew++ )
  248. {
  249. arcnew->flow = (flow_t)0;
  250. arcnew->ident = AT_LOWER;
  251. }
  252. }
  253. else
  254. {
  255. for( ; arcnew != stop; arcnew++ )
  256. {
  257. arcnew->flow = (flow_t)0;
  258. arcnew->ident = AT_LOWER;
  259. arcnew->nextout = arcnew->tail->firstout;
  260. arcnew->tail->firstout = arcnew;
  261. arcnew->nextin = arcnew->head->firstin;
  262. arcnew->head->firstin = arcnew;
  263. }
  264. }
  265. net->m += new_arcs;
  266. net->m_impl += new_arcs;
  267. net->max_residual_new_m -= new_arcs;
  268. }
  269. #if defined AT_HOME
  270. wall_time += Get_Time();
  271. printf( "total time price_out_impl(): %0.0f\n", wall_time );
  272. #endif
  273. return new_arcs;
  274. }
  275. #ifdef _PROTO_
  276. long suspend_impl( network_t *net, cost_t threshold, long all )
  277. #else
  278. long suspend_impl( net, threshold, all )
  279. network_t *net;
  280. cost_t threshold;
  281. long all;
  282. #endif
  283. {
  284. long susp;
  285. cost_t red_cost;
  286. arc_t *new_arc, *arc;
  287. void *stop;
  288. if( all )
  289. susp = net->m_impl;
  290. else
  291. {
  292. stop = (void *)net->stop_arcs;
  293. new_arc = &(net->arcs[net->m - net->m_impl]);
  294. for( susp = 0, arc = new_arc; arc < (arc_t *)stop; arc++ )
  295. {
  296. if( arc->ident == AT_LOWER )
  297. red_cost = arc->cost - arc->tail->potential
  298. + arc->head->potential;
  299. else
  300. {
  301. red_cost = (cost_t)-2;
  302. if( arc->ident == BASIC )
  303. {
  304. if( arc->tail->basic_arc == arc )
  305. arc->tail->basic_arc = new_arc;
  306. else
  307. arc->head->basic_arc = new_arc;
  308. }
  309. }
  310. if( red_cost > threshold )
  311. susp++;
  312. else
  313. {
  314. *new_arc = *arc;
  315. new_arc++;
  316. }
  317. }
  318. }
  319. #if defined AT_HOME
  320. printf( "\nremove %ld arcs\n\n", susp );
  321. fflush( stdout );
  322. #endif
  323. if( susp )
  324. {
  325. net->m -= susp;
  326. net->m_impl -= susp;
  327. net->stop_arcs -= susp;
  328. net->max_residual_new_m += susp;
  329. refresh_neighbour_lists( net );
  330. }
  331. return susp;
  332. }