#ifndef BIN_H
#define BIN_H
#include
#include
#include
using namespace std;
class Bin {
public:
Bin() = default;
Bin(double capacity )
{
this->capacity = capacity;
}
//向箱子中添加新物品并更新箱子信息
void addItem(double);
//获取剩余容量
double getResidualCap();
//获取箱子物品总容量
double getSum();
//获取箱子物品的数量
int getNum();
//得到箱子物品的容器
vector<double> &getItems();
double getWeight() {
return weight;
}
//容量
double getCap() {
return capacity;
}
//信息更新
void updateInfo();
void updateInfo(double, double);
//权重更新
void updateWeight(double, double);
//修改vector
void resetItems(vector<double> &);
//得到全部信息
void getAll() {
cout << "物品总和为:" << sum << endl;
cout << "剩余容量为:" << getResidualCap() << endl;
cout << "物品栏:";
for (auto c : items)
cout << c << " ";
cout << endl;
cout << "权重为:" << weight << '\n' << endl;
}
private:
//箱子总容量
double capacity = 150;
//箱子中的物品序列
vector items;
//箱子剩余容量
double residualCapacity = 150;
//所有物品和
double sum = 0;
//权重
double weight = 1.05;
};
//向箱子中添加物品,同时更新部分信息
inline void Bin::addItem(double a) {
items.push_back(a);
sum += a;
residualCapacity = 150 - sum;
}
//更新部分信息,不更新权重
inline void Bin::updateInfo() {
sum = 0;
for (int i = 0; i < (int)items.size(); ++i)
sum += items[i];
residualCapacity = 150 - sum;
}
//更新箱子全部信息
inline void Bin::updateInfo(double k, double t) {
//sum = 0;
//for (int i = 0; i < (int)items.size(); ++i)
// sum += items[i];
//residualCapacity = 150 - sum;
updateInfo();
weight = pow((1 + k*residualCapacity / capacity), t);
}
//获取箱子剩余容量
inline double Bin::getResidualCap() {
return residualCapacity;
}
//获取箱子所有物品总和
inline double Bin::getSum() {
return sum;
}
//获取箱子中物品数量
inline int Bin::getNum() {
return items.size();
}
//得到vector
inline vector &Bin::getItems() {
return items;
}
//更新权重
inline void Bin::updateWeight(double k, double t) {
weight = pow((1 + k*residualCapacity / capacity), t);
}
//修改vector
inline void Bin::resetItems(vector &v) {
items = v;
}
#endif
#ifndef FUNCTION_H
#define FUNCTION_H
#include<random>
#include<time.h>
#include "Bin.h"
class Function{
public:
//获取随机数
double getRandom();
//(0,1)交换
int swap01(vector<Bin> &bins, int i, int j, double K, double T, int ret, int &n);
};
inline double Function::getRandom() {
static default_random_engine e((int)time(nullptr));
static uniform_int_distribution<unsigned> u(0, 10000);
return u(e) / 10000.0;
}
inline int Function::swap01(vector<Bin> &bins, int i, int j, double K, double T, int ret, int &n) {
//double pro = bins[i].getResidualCap() / (bins[i].getResidualCap() + bins[j].getResidualCap());
double pro = 0.5;
double temp = getRandom();
if (ret == 1 || (ret != 0 && temp <= pro)) {
bins[i].updateInfo(K, T);
bins[j].updateInfo(K, T);
Bin alpha, beta;
int aN = bins[i].getItems().size();
int bN = bins[j].getItems().size();
for (int k = 0; k < aN; ++k)
alpha.addItem(bins[i].getItems()[k] * bins[i].getWeight());
for (int l = 0; l < bN; ++l)
beta.addItem(bins[j].getItems()[l] * bins[j].getWeight());
for (int q = 0; q < bN; ++q) {
auto bq = beta.getItems()[q];
auto jq = bins[j].getItems()[q];
auto li = bins[i].getSum();
auto lj = bins[j].getSum();
auto la = alpha.getSum();
auto lb = beta.getSum();
auto cap = bins[i].getCap();
//满足一定条件时,执行后续操作
if (li + jq <= cap &&
(la + bq)*(la + bq) + (lb - bq)*(lb - bq) - la*la - lb*lb >= 0) {
bins[i].addItem(jq);
swap(jq, bins[j].getItems()[bN - 1]);
bins[j].getItems().pop_back();
bN = bN - 1;
//没有空箱产生
if (bN != 0)
break;
else {
//问题会出现在这个地方吗?
swap(bins[j], bins[n - 1]);
/* bins[j].resetItems(bins[n - 1].getItems());
bins[j].updateInfo(K, T);*/
bins.pop_back();
n = n - 1;
break;
}
}
else
continue;
}
return 0;
}
return 2;
}
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "Bin.h"
#include "Function.h"
using namespace std;
int main() {
//物品数量
int N = 250;
//变形系数
double K = 0.05;
//最大循环
int nloop = 50;
//初始温度,降温系数
double T = 1, Tred = 0.95;
//箱子序列,将 100 80 40 24 23 这5个物品装入5个箱子
vector<Bin> bins;
int tempData = 0;
string line = "100 80 40 24 23";
istringstream iss(line);
while (iss >> tempData) {
Bin bin;
bin.addItem(tempData);
bins.push_back(bin);
}
//检查初始箱子信息
for (size_t i = 0; i < bins.size(); ++i)
bins[i].getAll();
cout << "---------------" << endl;
int lowerBound = 2;
int n = bins.size();
int ncom = n;
Function f;
for (int iLoop = 0; iLoop < nloop; ++iLoop) {
for (int i = 0; i < n - 1; ++i) {
for (int j = i + 1; j < n; ++j) {
f.swap01(bins, i, j, K, T, 2, n);
if (ncom != n || n == lowerBound)
break;
}
if (n <= lowerBound)
break;
}
if (n <= lowerBound)
break;
T *= Tred;
}
for (size_t i = 0; i < bins.size(); ++i)
bins[i].getAll();
return 0;
}
问题描述:5个物品放入了5个箱子中,通过01交换(即把后面箱子里的物品放入前一个箱子中去),如果生成了空箱子,那么丢掉空箱子。最后让箱子数最小。
bug:某些时候,最后得到的箱子中,物品已经不是原来的物品了。或者说,物品的总和发生了异常变化。原先的总和是267,到最后不应该发生变化的。
希望前辈们指点。