gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge bugfix #368
0 1 0
merge default
1 file changed with 2 insertions and 2 deletions:
↑ Collapse diff ↑
Show white space 192 line context
... ...
@@ -984,193 +984,193 @@
984 984
      return c;
985 985
    }
986 986

	
987 987
#ifndef DOXYGEN
988 988
    Cost totalCost() const {
989 989
      return totalCost<Cost>();
990 990
    }
991 991
#endif
992 992

	
993 993
    /// \brief Return the flow on the given arc.
994 994
    ///
995 995
    /// This function returns the flow on the given arc.
996 996
    ///
997 997
    /// \pre \ref run() must be called before using this function.
998 998
    Value flow(const Arc& a) const {
999 999
      return _flow[_arc_id[a]];
1000 1000
    }
1001 1001

	
1002 1002
    /// \brief Return the flow map (the primal solution).
1003 1003
    ///
1004 1004
    /// This function copies the flow value on each arc into the given
1005 1005
    /// map. The \c Value type of the algorithm must be convertible to
1006 1006
    /// the \c Value type of the map.
1007 1007
    ///
1008 1008
    /// \pre \ref run() must be called before using this function.
1009 1009
    template <typename FlowMap>
1010 1010
    void flowMap(FlowMap &map) const {
1011 1011
      for (ArcIt a(_graph); a != INVALID; ++a) {
1012 1012
        map.set(a, _flow[_arc_id[a]]);
1013 1013
      }
1014 1014
    }
1015 1015

	
1016 1016
    /// \brief Return the potential (dual value) of the given node.
1017 1017
    ///
1018 1018
    /// This function returns the potential (dual value) of the
1019 1019
    /// given node.
1020 1020
    ///
1021 1021
    /// \pre \ref run() must be called before using this function.
1022 1022
    Cost potential(const Node& n) const {
1023 1023
      return _pi[_node_id[n]];
1024 1024
    }
1025 1025

	
1026 1026
    /// \brief Return the potential map (the dual solution).
1027 1027
    ///
1028 1028
    /// This function copies the potential (dual value) of each node
1029 1029
    /// into the given map.
1030 1030
    /// The \c Cost type of the algorithm must be convertible to the
1031 1031
    /// \c Value type of the map.
1032 1032
    ///
1033 1033
    /// \pre \ref run() must be called before using this function.
1034 1034
    template <typename PotentialMap>
1035 1035
    void potentialMap(PotentialMap &map) const {
1036 1036
      for (NodeIt n(_graph); n != INVALID; ++n) {
1037 1037
        map.set(n, _pi[_node_id[n]]);
1038 1038
      }
1039 1039
    }
1040 1040

	
1041 1041
    /// @}
1042 1042

	
1043 1043
  private:
1044 1044

	
1045 1045
    // Initialize internal data structures
1046 1046
    bool init() {
1047 1047
      if (_node_num == 0) return false;
1048 1048

	
1049 1049
      // Check the sum of supply values
1050 1050
      _sum_supply = 0;
1051 1051
      for (int i = 0; i != _node_num; ++i) {
1052 1052
        _sum_supply += _supply[i];
1053 1053
      }
1054 1054
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
1055 1055
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
1056 1056

	
1057 1057
      // Remove non-zero lower bounds
1058 1058
      if (_have_lower) {
1059 1059
        for (int i = 0; i != _arc_num; ++i) {
1060 1060
          Value c = _lower[i];
1061 1061
          if (c >= 0) {
1062 1062
            _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
1063 1063
          } else {
1064 1064
            _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
1065 1065
          }
1066 1066
          _supply[_source[i]] -= c;
1067 1067
          _supply[_target[i]] += c;
1068 1068
        }
1069 1069
      } else {
1070 1070
        for (int i = 0; i != _arc_num; ++i) {
1071 1071
          _cap[i] = _upper[i];
1072 1072
        }
1073 1073
      }
1074 1074

	
1075 1075
      // Initialize artifical cost
1076 1076
      Cost ART_COST;
1077 1077
      if (std::numeric_limits<Cost>::is_exact) {
1078 1078
        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
1079 1079
      } else {
1080
        ART_COST = std::numeric_limits<Cost>::min();
1080
        ART_COST = 0;
1081 1081
        for (int i = 0; i != _arc_num; ++i) {
1082 1082
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1083 1083
        }
1084 1084
        ART_COST = (ART_COST + 1) * _node_num;
1085 1085
      }
1086 1086

	
1087 1087
      // Initialize arc maps
1088 1088
      for (int i = 0; i != _arc_num; ++i) {
1089 1089
        _flow[i] = 0;
1090 1090
        _state[i] = STATE_LOWER;
1091 1091
      }
1092 1092

	
1093 1093
      // Set data for the artificial root node
1094 1094
      _root = _node_num;
1095 1095
      _parent[_root] = -1;
1096 1096
      _pred[_root] = -1;
1097 1097
      _thread[_root] = 0;
1098 1098
      _rev_thread[0] = _root;
1099 1099
      _succ_num[_root] = _node_num + 1;
1100 1100
      _last_succ[_root] = _root - 1;
1101 1101
      _supply[_root] = -_sum_supply;
1102 1102
      _pi[_root] = 0;
1103 1103

	
1104 1104
      // Add artificial arcs and initialize the spanning tree data structure
1105 1105
      if (_sum_supply == 0) {
1106 1106
        // EQ supply constraints
1107 1107
        _search_arc_num = _arc_num;
1108 1108
        _all_arc_num = _arc_num + _node_num;
1109 1109
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1110 1110
          _parent[u] = _root;
1111 1111
          _pred[u] = e;
1112 1112
          _thread[u] = u + 1;
1113 1113
          _rev_thread[u + 1] = u;
1114 1114
          _succ_num[u] = 1;
1115 1115
          _last_succ[u] = u;
1116 1116
          _cap[e] = INF;
1117 1117
          _state[e] = STATE_TREE;
1118 1118
          if (_supply[u] >= 0) {
1119 1119
            _forward[u] = true;
1120 1120
            _pi[u] = 0;
1121 1121
            _source[e] = u;
1122 1122
            _target[e] = _root;
1123 1123
            _flow[e] = _supply[u];
1124 1124
            _cost[e] = 0;
1125 1125
          } else {
1126 1126
            _forward[u] = false;
1127 1127
            _pi[u] = ART_COST;
1128 1128
            _source[e] = _root;
1129 1129
            _target[e] = u;
1130 1130
            _flow[e] = -_supply[u];
1131 1131
            _cost[e] = ART_COST;
1132 1132
          }
1133 1133
        }
1134 1134
      }
1135 1135
      else if (_sum_supply > 0) {
1136 1136
        // LEQ supply constraints
1137 1137
        _search_arc_num = _arc_num + _node_num;
1138 1138
        int f = _arc_num + _node_num;
1139 1139
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1140 1140
          _parent[u] = _root;
1141 1141
          _thread[u] = u + 1;
1142 1142
          _rev_thread[u + 1] = u;
1143 1143
          _succ_num[u] = 1;
1144 1144
          _last_succ[u] = u;
1145 1145
          if (_supply[u] >= 0) {
1146 1146
            _forward[u] = true;
1147 1147
            _pi[u] = 0;
1148 1148
            _pred[u] = e;
1149 1149
            _source[e] = u;
1150 1150
            _target[e] = _root;
1151 1151
            _cap[e] = INF;
1152 1152
            _flow[e] = _supply[u];
1153 1153
            _cost[e] = 0;
1154 1154
            _state[e] = STATE_TREE;
1155 1155
          } else {
1156 1156
            _forward[u] = false;
1157 1157
            _pi[u] = ART_COST;
1158 1158
            _pred[u] = f;
1159 1159
            _source[f] = _root;
1160 1160
            _target[f] = u;
1161 1161
            _cap[f] = INF;
1162 1162
            _flow[f] = -_supply[u];
1163 1163
            _cost[f] = ART_COST;
1164 1164
            _state[f] = STATE_TREE;
1165 1165
            _source[e] = u;
1166 1166
            _target[e] = _root;
1167 1167
            _cap[e] = INF;
1168 1168
            _flow[e] = 0;
1169 1169
            _cost[e] = 0;
1170 1170
            _state[e] = STATE_LOWER;
1171 1171
            ++f;
1172 1172
          }
1173 1173
        }
1174 1174
        _all_arc_num = f;
1175 1175
      }
1176 1176
      else {
... ...
@@ -1496,126 +1496,126 @@
1496 1496
          }
1497 1497
        }
1498 1498
      } else {
1499 1499
        // Find the min. cost outgoing arc for each supply node
1500 1500
        for (int i = 0; i != int(supply_nodes.size()); ++i) {
1501 1501
          Node u = supply_nodes[i];
1502 1502
          Cost c, min_cost = std::numeric_limits<Cost>::max();
1503 1503
          Arc min_arc = INVALID;
1504 1504
          for (OutArcIt a(_graph, u); a != INVALID; ++a) {
1505 1505
            c = _cost[_arc_id[a]];
1506 1506
            if (c < min_cost) {
1507 1507
              min_cost = c;
1508 1508
              min_arc = a;
1509 1509
            }
1510 1510
          }
1511 1511
          if (min_arc != INVALID) {
1512 1512
            arc_vector.push_back(_arc_id[min_arc]);
1513 1513
          }
1514 1514
        }
1515 1515
      }
1516 1516

	
1517 1517
      // Perform heuristic initial pivots
1518 1518
      for (int i = 0; i != int(arc_vector.size()); ++i) {
1519 1519
        in_arc = arc_vector[i];
1520 1520
        if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -
1521 1521
            _pi[_target[in_arc]]) >= 0) continue;
1522 1522
        findJoinNode();
1523 1523
        bool change = findLeavingArc();
1524 1524
        if (delta >= MAX) return false;
1525 1525
        changeFlow(change);
1526 1526
        if (change) {
1527 1527
          updateTreeStructure();
1528 1528
          updatePotential();
1529 1529
        }
1530 1530
      }
1531 1531
      return true;
1532 1532
    }
1533 1533

	
1534 1534
    // Execute the algorithm
1535 1535
    ProblemType start(PivotRule pivot_rule) {
1536 1536
      // Select the pivot rule implementation
1537 1537
      switch (pivot_rule) {
1538 1538
        case FIRST_ELIGIBLE:
1539 1539
          return start<FirstEligiblePivotRule>();
1540 1540
        case BEST_ELIGIBLE:
1541 1541
          return start<BestEligiblePivotRule>();
1542 1542
        case BLOCK_SEARCH:
1543 1543
          return start<BlockSearchPivotRule>();
1544 1544
        case CANDIDATE_LIST:
1545 1545
          return start<CandidateListPivotRule>();
1546 1546
        case ALTERING_LIST:
1547 1547
          return start<AlteringListPivotRule>();
1548 1548
      }
1549 1549
      return INFEASIBLE; // avoid warning
1550 1550
    }
1551 1551

	
1552 1552
    template <typename PivotRuleImpl>
1553 1553
    ProblemType start() {
1554 1554
      PivotRuleImpl pivot(*this);
1555 1555

	
1556 1556
      // Perform heuristic initial pivots
1557 1557
      if (!initialPivots()) return UNBOUNDED;
1558 1558

	
1559 1559
      // Execute the Network Simplex algorithm
1560 1560
      while (pivot.findEnteringArc()) {
1561 1561
        findJoinNode();
1562 1562
        bool change = findLeavingArc();
1563 1563
        if (delta >= MAX) return UNBOUNDED;
1564 1564
        changeFlow(change);
1565 1565
        if (change) {
1566 1566
          updateTreeStructure();
1567 1567
          updatePotential();
1568 1568
        }
1569 1569
      }
1570 1570

	
1571 1571
      // Check feasibility
1572 1572
      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
1573 1573
        if (_flow[e] != 0) return INFEASIBLE;
1574 1574
      }
1575 1575

	
1576 1576
      // Transform the solution and the supply map to the original form
1577 1577
      if (_have_lower) {
1578 1578
        for (int i = 0; i != _arc_num; ++i) {
1579 1579
          Value c = _lower[i];
1580 1580
          if (c != 0) {
1581 1581
            _flow[i] += c;
1582 1582
            _supply[_source[i]] += c;
1583 1583
            _supply[_target[i]] -= c;
1584 1584
          }
1585 1585
        }
1586 1586
      }
1587 1587

	
1588 1588
      // Shift potentials to meet the requirements of the GEQ/LEQ type
1589 1589
      // optimality conditions
1590 1590
      if (_sum_supply == 0) {
1591 1591
        if (_stype == GEQ) {
1592
          Cost max_pot = std::numeric_limits<Cost>::min();
1592
          Cost max_pot = -std::numeric_limits<Cost>::max();
1593 1593
          for (int i = 0; i != _node_num; ++i) {
1594 1594
            if (_pi[i] > max_pot) max_pot = _pi[i];
1595 1595
          }
1596 1596
          if (max_pot > 0) {
1597 1597
            for (int i = 0; i != _node_num; ++i)
1598 1598
              _pi[i] -= max_pot;
1599 1599
          }
1600 1600
        } else {
1601 1601
          Cost min_pot = std::numeric_limits<Cost>::max();
1602 1602
          for (int i = 0; i != _node_num; ++i) {
1603 1603
            if (_pi[i] < min_pot) min_pot = _pi[i];
1604 1604
          }
1605 1605
          if (min_pot < 0) {
1606 1606
            for (int i = 0; i != _node_num; ++i)
1607 1607
              _pi[i] -= min_pot;
1608 1608
          }
1609 1609
        }
1610 1610
      }
1611 1611

	
1612 1612
      return OPTIMAL;
1613 1613
    }
1614 1614

	
1615 1615
  }; //class NetworkSimplex
1616 1616

	
1617 1617
  ///@}
1618 1618

	
1619 1619
} //namespace lemon
1620 1620

	
1621 1621
#endif //LEMON_NETWORK_SIMPLEX_H
0 comments (0 inline)