gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Bug fix in NetworkSimplex (#234)
0 1 0
default
1 file changed with 7 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -1051,250 +1051,251 @@
1051 1051
    ///
1052 1052
    /// \pre \ref run() must be called before using this function.
1053 1053
    const PotentialMap& potentialMap() const {
1054 1054
      return *_potential_map;
1055 1055
    }
1056 1056

	
1057 1057
    /// @}
1058 1058

	
1059 1059
  private:
1060 1060

	
1061 1061
    // Initialize internal data structures
1062 1062
    bool init() {
1063 1063
      // Initialize result maps
1064 1064
      if (!_flow_map) {
1065 1065
        _flow_map = new FlowMap(_graph);
1066 1066
        _local_flow = true;
1067 1067
      }
1068 1068
      if (!_potential_map) {
1069 1069
        _potential_map = new PotentialMap(_graph);
1070 1070
        _local_potential = true;
1071 1071
      }
1072 1072

	
1073 1073
      // Initialize vectors
1074 1074
      _node_num = countNodes(_graph);
1075 1075
      _arc_num = countArcs(_graph);
1076 1076
      int all_node_num = _node_num + 1;
1077 1077
      int all_arc_num = _arc_num + _node_num;
1078 1078
      if (_node_num == 0) return false;
1079 1079

	
1080 1080
      _arc_ref.resize(_arc_num);
1081 1081
      _source.resize(all_arc_num);
1082 1082
      _target.resize(all_arc_num);
1083 1083

	
1084 1084
      _cap.resize(all_arc_num);
1085 1085
      _cost.resize(all_arc_num);
1086 1086
      _supply.resize(all_node_num);
1087 1087
      _flow.resize(all_arc_num);
1088 1088
      _pi.resize(all_node_num);
1089 1089

	
1090 1090
      _parent.resize(all_node_num);
1091 1091
      _pred.resize(all_node_num);
1092 1092
      _forward.resize(all_node_num);
1093 1093
      _thread.resize(all_node_num);
1094 1094
      _rev_thread.resize(all_node_num);
1095 1095
      _succ_num.resize(all_node_num);
1096 1096
      _last_succ.resize(all_node_num);
1097 1097
      _state.resize(all_arc_num);
1098 1098

	
1099 1099
      // Initialize node related data
1100 1100
      bool valid_supply = true;
1101 1101
      Flow sum_supply = 0;
1102 1102
      if (!_pstsup && !_psupply) {
1103 1103
        _pstsup = true;
1104 1104
        _psource = _ptarget = NodeIt(_graph);
1105 1105
        _pstflow = 0;
1106 1106
      }
1107 1107
      if (_psupply) {
1108 1108
        int i = 0;
1109 1109
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1110 1110
          _node_id[n] = i;
1111 1111
          _supply[i] = (*_psupply)[n];
1112 1112
          sum_supply += _supply[i];
1113 1113
        }
1114 1114
        valid_supply = (_ptype == GEQ && sum_supply <= 0) ||
1115 1115
                       (_ptype == LEQ && sum_supply >= 0);
1116 1116
      } else {
1117 1117
        int i = 0;
1118 1118
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1119 1119
          _node_id[n] = i;
1120 1120
          _supply[i] = 0;
1121 1121
        }
1122 1122
        _supply[_node_id[_psource]] =  _pstflow;
1123 1123
        _supply[_node_id[_ptarget]] = -_pstflow;
1124 1124
      }
1125 1125
      if (!valid_supply) return false;
1126 1126

	
1127 1127
      // Infinite capacity value
1128 1128
      Flow inf_cap =
1129 1129
        std::numeric_limits<Flow>::has_infinity ?
1130 1130
        std::numeric_limits<Flow>::infinity() :
1131 1131
        std::numeric_limits<Flow>::max();
1132 1132

	
1133 1133
      // Initialize artifical cost
1134 1134
      Cost art_cost;
1135 1135
      if (std::numeric_limits<Cost>::is_exact) {
1136 1136
        art_cost = std::numeric_limits<Cost>::max() / 4 + 1;
1137 1137
      } else {
1138 1138
        art_cost = std::numeric_limits<Cost>::min();
1139 1139
        for (int i = 0; i != _arc_num; ++i) {
1140 1140
          if (_cost[i] > art_cost) art_cost = _cost[i];
1141 1141
        }
1142 1142
        art_cost = (art_cost + 1) * _node_num;
1143 1143
      }
1144 1144

	
1145 1145
      // Run Circulation to check if a feasible solution exists
1146 1146
      typedef ConstMap<Arc, Flow> ConstArcMap;
1147
      ConstArcMap zero_arc_map(0), inf_arc_map(inf_cap);
1147 1148
      FlowNodeMap *csup = NULL;
1148 1149
      bool local_csup = false;
1149 1150
      if (_psupply) {
1150 1151
        csup = _psupply;
1151 1152
      } else {
1152 1153
        csup = new FlowNodeMap(_graph, 0);
1153 1154
        (*csup)[_psource] =  _pstflow;
1154 1155
        (*csup)[_ptarget] = -_pstflow;
1155 1156
        local_csup = true;
1156 1157
      }
1157 1158
      bool circ_result = false;
1158 1159
      if (_ptype == GEQ || (_ptype == LEQ && sum_supply == 0)) {
1159 1160
        // GEQ problem type
1160 1161
        if (_plower) {
1161 1162
          if (_pupper) {
1162 1163
            Circulation<GR, FlowArcMap, FlowArcMap, FlowNodeMap>
1163 1164
              circ(_graph, *_plower, *_pupper, *csup);
1164 1165
            circ_result = circ.run();
1165 1166
          } else {
1166 1167
            Circulation<GR, FlowArcMap, ConstArcMap, FlowNodeMap>
1167
              circ(_graph, *_plower, ConstArcMap(inf_cap), *csup);
1168
              circ(_graph, *_plower, inf_arc_map, *csup);
1168 1169
            circ_result = circ.run();
1169 1170
          }
1170 1171
        } else {
1171 1172
          if (_pupper) {
1172 1173
            Circulation<GR, ConstArcMap, FlowArcMap, FlowNodeMap>
1173
              circ(_graph, ConstArcMap(0), *_pupper, *csup);
1174
              circ(_graph, zero_arc_map, *_pupper, *csup);
1174 1175
            circ_result = circ.run();
1175 1176
          } else {
1176 1177
            Circulation<GR, ConstArcMap, ConstArcMap, FlowNodeMap>
1177
              circ(_graph, ConstArcMap(0), ConstArcMap(inf_cap), *csup);
1178
              circ(_graph, zero_arc_map, inf_arc_map, *csup);
1178 1179
            circ_result = circ.run();
1179 1180
          }
1180 1181
        }
1181 1182
      } else {
1182 1183
        // LEQ problem type
1183 1184
        typedef ReverseDigraph<const GR> RevGraph;
1184 1185
        typedef NegMap<FlowNodeMap> NegNodeMap;
1185 1186
        RevGraph rgraph(_graph);
1186 1187
        NegNodeMap neg_csup(*csup);
1187 1188
        if (_plower) {
1188 1189
          if (_pupper) {
1189 1190
            Circulation<RevGraph, FlowArcMap, FlowArcMap, NegNodeMap>
1190 1191
              circ(rgraph, *_plower, *_pupper, neg_csup);
1191 1192
            circ_result = circ.run();
1192 1193
          } else {
1193 1194
            Circulation<RevGraph, FlowArcMap, ConstArcMap, NegNodeMap>
1194
              circ(rgraph, *_plower, ConstArcMap(inf_cap), neg_csup);
1195
              circ(rgraph, *_plower, inf_arc_map, neg_csup);
1195 1196
            circ_result = circ.run();
1196 1197
          }
1197 1198
        } else {
1198 1199
          if (_pupper) {
1199 1200
            Circulation<RevGraph, ConstArcMap, FlowArcMap, NegNodeMap>
1200
              circ(rgraph, ConstArcMap(0), *_pupper, neg_csup);
1201
              circ(rgraph, zero_arc_map, *_pupper, neg_csup);
1201 1202
            circ_result = circ.run();
1202 1203
          } else {
1203 1204
            Circulation<RevGraph, ConstArcMap, ConstArcMap, NegNodeMap>
1204
              circ(rgraph, ConstArcMap(0), ConstArcMap(inf_cap), neg_csup);
1205
              circ(rgraph, zero_arc_map, inf_arc_map, neg_csup);
1205 1206
            circ_result = circ.run();
1206 1207
          }
1207 1208
        }
1208 1209
      }
1209 1210
      if (local_csup) delete csup;
1210 1211
      if (!circ_result) return false;
1211 1212

	
1212 1213
      // Set data for the artificial root node
1213 1214
      _root = _node_num;
1214 1215
      _parent[_root] = -1;
1215 1216
      _pred[_root] = -1;
1216 1217
      _thread[_root] = 0;
1217 1218
      _rev_thread[0] = _root;
1218 1219
      _succ_num[_root] = all_node_num;
1219 1220
      _last_succ[_root] = _root - 1;
1220 1221
      _supply[_root] = -sum_supply;
1221 1222
      if (sum_supply < 0) {
1222 1223
        _pi[_root] = -art_cost;
1223 1224
      } else {
1224 1225
        _pi[_root] = art_cost;
1225 1226
      }
1226 1227

	
1227 1228
      // Store the arcs in a mixed order
1228 1229
      int k = std::max(int(sqrt(_arc_num)), 10);
1229 1230
      int i = 0;
1230 1231
      for (ArcIt e(_graph); e != INVALID; ++e) {
1231 1232
        _arc_ref[i] = e;
1232 1233
        if ((i += k) >= _arc_num) i = (i % k) + 1;
1233 1234
      }
1234 1235

	
1235 1236
      // Initialize arc maps
1236 1237
      if (_pupper && _pcost) {
1237 1238
        for (int i = 0; i != _arc_num; ++i) {
1238 1239
          Arc e = _arc_ref[i];
1239 1240
          _source[i] = _node_id[_graph.source(e)];
1240 1241
          _target[i] = _node_id[_graph.target(e)];
1241 1242
          _cap[i] = (*_pupper)[e];
1242 1243
          _cost[i] = (*_pcost)[e];
1243 1244
          _flow[i] = 0;
1244 1245
          _state[i] = STATE_LOWER;
1245 1246
        }
1246 1247
      } else {
1247 1248
        for (int i = 0; i != _arc_num; ++i) {
1248 1249
          Arc e = _arc_ref[i];
1249 1250
          _source[i] = _node_id[_graph.source(e)];
1250 1251
          _target[i] = _node_id[_graph.target(e)];
1251 1252
          _flow[i] = 0;
1252 1253
          _state[i] = STATE_LOWER;
1253 1254
        }
1254 1255
        if (_pupper) {
1255 1256
          for (int i = 0; i != _arc_num; ++i)
1256 1257
            _cap[i] = (*_pupper)[_arc_ref[i]];
1257 1258
        } else {
1258 1259
          for (int i = 0; i != _arc_num; ++i)
1259 1260
            _cap[i] = inf_cap;
1260 1261
        }
1261 1262
        if (_pcost) {
1262 1263
          for (int i = 0; i != _arc_num; ++i)
1263 1264
            _cost[i] = (*_pcost)[_arc_ref[i]];
1264 1265
        } else {
1265 1266
          for (int i = 0; i != _arc_num; ++i)
1266 1267
            _cost[i] = 1;
1267 1268
        }
1268 1269
      }
1269 1270
      
1270 1271
      // Remove non-zero lower bounds
1271 1272
      if (_plower) {
1272 1273
        for (int i = 0; i != _arc_num; ++i) {
1273 1274
          Flow c = (*_plower)[_arc_ref[i]];
1274 1275
          if (c != 0) {
1275 1276
            _cap[i] -= c;
1276 1277
            _supply[_source[i]] -= c;
1277 1278
            _supply[_target[i]] += c;
1278 1279
          }
1279 1280
        }
1280 1281
      }
1281 1282

	
1282 1283
      // Add artificial arcs and initialize the spanning tree data structure
1283 1284
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1284 1285
        _thread[u] = u + 1;
1285 1286
        _rev_thread[u + 1] = u;
1286 1287
        _succ_num[u] = 1;
1287 1288
        _last_succ[u] = u;
1288 1289
        _parent[u] = _root;
1289 1290
        _pred[u] = e;
1290 1291
        _cost[e] = art_cost;
1291 1292
        _cap[e] = inf_cap;
1292 1293
        _state[e] = STATE_TREE;
1293 1294
        if (_supply[u] > 0 || (_supply[u] == 0 && sum_supply <= 0)) {
1294 1295
          _flow[e] = _supply[u];
1295 1296
          _forward[u] = true;
1296 1297
          _pi[u] = -art_cost + _pi[_root];
1297 1298
        } else {
1298 1299
          _flow[e] = -_supply[u];
1299 1300
          _forward[u] = false;
1300 1301
          _pi[u] = art_cost + _pi[_root];
0 comments (0 inline)