00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <algorithm>
00015 #include <cstring>
00016 #include <functional>
00017 #include "base/stringprintf.h"
00018 #include "util/const_int_array.h"
00019 #include "util/bitset.h"
00020
00021 namespace operations_research {
00022 ConstIntArray::ConstIntArray(const std::vector<int64>& data)
00023 : data_(new std::vector<int64>(data)),
00024 scanned_(false),
00025 status_(0) {}
00026
00027 ConstIntArray::ConstIntArray(const std::vector<int>& data)
00028 : data_(new std::vector<int64>(data.size())),
00029 scanned_(false),
00030 status_(0) {
00031 for (int i = 0; i < data.size(); ++i) {
00032 (*data_)[i] = data[i];
00033 }
00034 }
00035
00036 ConstIntArray::ConstIntArray(const int64 * const data, int size)
00037 : data_(new std::vector<int64>(size)), scanned_(false), status_(0) {
00038 CHECK_GT(size, 0);
00039 CHECK_NOTNULL(data);
00040 memcpy((data_->data()), data, size * sizeof(*data));
00041 }
00042
00043 ConstIntArray::ConstIntArray(const int * const data, int size)
00044 : data_(new std::vector<int64>(size)), scanned_(false), status_(0) {
00045 CHECK_GT(size, 0);
00046 CHECK_NOTNULL(data);
00047 for (int i = 0; i < size; ++i) {
00048 (*data_)[i] = data[i];
00049 }
00050 }
00051
00052 ConstIntArray::ConstIntArray(std::vector<int64>* data)
00053 : data_(data), scanned_(false), status_(0) {
00054 CHECK_GT(data->size(), 0);
00055 }
00056
00057 ConstIntArray::~ConstIntArray() {}
00058
00059 std::vector<int64>* ConstIntArray::Release() {
00060 return data_.release();
00061 }
00062
00063 int ConstIntArray::size() const {
00064 CHECK_NOTNULL(data_.get());
00065 return data_->size();
00066 }
00067
00068 std::vector<int64>* ConstIntArray::SortedCopy(bool increasing) const {
00069 std::vector<int64>* new_data = new std::vector<int64>(*data_);
00070 if (increasing) {
00071 std::sort(new_data->begin(), new_data->end());
00072 } else {
00073 std::sort(new_data->begin(), new_data->end(), std::greater<int64>());
00074 }
00075 return new_data;
00076 }
00077
00078 std::vector<int64>* ConstIntArray::Copy() const {
00079 return new std::vector<int64>(*data_);
00080 }
00081
00082 std::vector<int64>*
00083 ConstIntArray::SortedCopyWithoutDuplicates(bool increasing) const {
00084 std::vector<int64>* new_data = new std::vector<int64>(*data_);
00085 if (increasing) {
00086 std::sort(new_data->begin(), new_data->end());
00087 } else {
00088 std::sort(new_data->begin(), new_data->end(), std::greater<int64>());
00089 }
00090 int duplicates = 0;
00091 for (int i = 0; i < data_->size() - 1; ++i) {
00092 duplicates += (*new_data)[i] == (*new_data)[i + 1];
00093 }
00094 if (duplicates == 0) {
00095 return new_data;
00096 } else {
00097 const int final_size = data_->size() - duplicates;
00098 std::vector<int64>* final_data = new std::vector<int64>(final_size);
00099 (*final_data)[0] = (*new_data)[0];
00100 int counter = 1;
00101 for (int i = 1; i < data_->size(); ++i) {
00102 if ((*new_data)[i] != (*new_data)[i - 1]) {
00103 (*final_data)[counter++] = (*new_data)[i];
00104 }
00105 }
00106 CHECK_EQ(final_size, counter);
00107 delete new_data;
00108 return final_data;
00109 }
00110 }
00111
00112 bool ConstIntArray::Equals(const ConstIntArray& other) const {
00113 if (data_->size() != other.data_->size()) {
00114 return false;
00115 }
00116 for (int i = 0; i < data_->size(); ++i) {
00117 if ((*data_)[i] != other[i]) {
00118 return false;
00119 }
00120 }
00121 return true;
00122 }
00123
00124 bool ConstIntArray::HasProperty(Property info) {
00125 const int kBitsInChar = 8;
00126 DCHECK_GE(info, 0);
00127 DCHECK_LT(info, kBitsInChar * sizeof(status_));
00128 CHECK_NOTNULL(data_.get());
00129 if (!scanned_) {
00130 Scan();
00131 }
00132 return IsBitSet64(&status_, info);
00133 }
00134
00135 void ConstIntArray::AndProperty(Property info, bool value) {
00136 if (!value) {
00137 ClearBit64(&status_, info);
00138 }
00139 }
00140
00141 void ConstIntArray::Scan() {
00142 DCHECK(!scanned_);
00143 status_ = IntervalDown64(NUM_PROPERTY);
00144 scanned_ = true;
00145 if (data_.get() == NULL) {
00146 return;
00147 }
00148 const int64 first = (*data_)[0];
00149 AndProperty(IS_POSITIVE, first > 0);
00150 AndProperty(IS_NEGATIVE, first < 0);
00151 AndProperty(IS_NEGATIVE_OR_NULL, first <= 0);
00152 AndProperty(IS_POSITIVE_OR_NULL, first >= 0);
00153 AndProperty(IS_BOOLEAN, first == 0 || first == 1);
00154
00155 for (int i = 1; i < data_->size(); ++i) {
00156 const int64 previous = (*data_)[i - 1];
00157 const int64 current = (*data_)[i];
00158 AndProperty(IS_CONSTANT, current == previous);
00159 AndProperty(IS_DECREASING, previous >= current);
00160 AndProperty(IS_STRICTLY_DECREASING, previous > current);
00161 AndProperty(IS_INCREASING, previous <= current);
00162 AndProperty(IS_STRICTLY_INCREASING, previous < current);
00163 AndProperty(IS_BOOLEAN, current == 0 || current == 1);
00164 AndProperty(IS_POSITIVE, current > 0);
00165 AndProperty(IS_NEGATIVE, current < 0);
00166 AndProperty(IS_NEGATIVE_OR_NULL, current <= 0);
00167 AndProperty(IS_POSITIVE_OR_NULL, current >= 0);
00168 if (!status_) {
00169 break;
00170 }
00171 }
00172 }
00173
00174 string ConstIntArray::DebugString() const {
00175 if (data_.get() == NULL) {
00176 return "Released ConstIntArray";
00177 }
00178 string result = "[";
00179 for (int i = 0; i < data_->size(); ++i) {
00180 if (i != 0) {
00181 result.append(", ");
00182 }
00183 StringAppendF(&result, "%lld", (*data_)[i]);
00184 }
00185 result.append("]");
00186 return result;
00187 }
00188 }