📄 mfsolver.cpp
字号:
#include "MFSolver.h"
#include "stdafx.h"
#include <fstream>
//#include <iostream>
#include <algorithm>
#include <strstream>
#include <cassert>
#include <cmath>
#include "C:\MATLAB6p5\extern\include\engine.h"
using namespace std;
#define SEGMENT_COUNT 5
#pragma warning(disable:4267)
MFSolver::MFSolver(const string &fn):
isOK(false)
{
int i = 0;
ifstream file(fn.c_str());
if (!file.is_open())
{
return;
}
string line,tmp;
// 4个可配置选项
getline(file,line);
istrstream is1(line.c_str(), line.size());
is1 >> tmp;
is1 >> max_load; // 最大载重量
/*
* 最大载重量是以磅为单位,而其它demand是以100pcs为单位的。
* 所以这里需要把max_load转换成以100pcs为单位的数值.
*/
max_load = max_load/474.2588252;
getline(file,line);
istrstream is2(line.c_str(), line.size());
is2 >> tmp;
is2 >> min_load; // 最小载重量
/*
* 最大载重量是以磅为单位,而其它demand是以100pcs为单位的。
* 所以这里需要把min_load转换成以100pcs为单位的数值.
*/
min_load = min_load/474.2588252;
getline(file,line);
istrstream is3(line.c_str(), line.size());
is3 >> tmp;
is3 >> speed; // 卡车时速
getline(file,line);
istrstream is4(line.c_str(), line.size());
is4 >> tmp;
is4 >> short_threshold; // 短程和长途路程的分界线
// 读取地包商/零售商的个数
int rdcNum, dealerNum;
getline(file,line);
istrstream iss1(line.c_str(), line.size());
iss1 >> tmp;
iss1 >> rdcNum;
getline(file,line);
istrstream iss2(line.c_str(), line.size());
iss2 >> tmp;
iss2 >> dealerNum;
// 读地包商数据
this->RDCSet.resize(rdcNum);
for (i = 0; i < rdcNum; ++i)
{
getline(file, line);
istrstream iss(line.c_str(), line.size());
RDC &rdc = RDCSet[i];
iss >> rdc.name;
iss >> rdc.x;
iss >> rdc.y;
iss >> rdc.s_cpm;
iss >> rdc.s_cph;
iss >> rdc.l_cpm;
iss >> rdc.l_cps;
iss >> rdc.storage_cost;
iss >> rdc.router_cost;
}
// 读零售商数据
this->dealerSet.resize(dealerNum);
for (i = 0; i < dealerNum; ++i)
{
getline(file, line);
istrstream iss(line.c_str(), line.size());
Dealer &dl = dealerSet[i];
iss >> dl.name;
iss >> dl.x;
iss >> dl.y;
iss >> dl.demand;
dl.times = (int)floor(dl.demand/max_load);
dl.demand -= dl.times*max_load;
}
// 初始化候选站点
for (i = 0; i < (int)dealerSet.size(); ++i)
{
Dealer &dl = dealerSet[i];
if (dl.demand > 0)
{
candidateSet.push_back(i);
}
if (dl.times > 0)
{
addSet.push_back(i);
}
}
// 初始化路径集合
for (i = 0; i < (int)RDCSet.size(); ++i)
{
pathSet.push_back(Path());
pathSet.back().cost = 0;
pathSet.back().demand = 0;
pathSet.back().distance = 0;
pathSet.back().length = 0;
pathSet.back().stops.push_back(i);
}
isOK = true;
}
MFSolver::~MFSolver()
{
}
void MFSolver::PrintResult(Engine *ep, CString &OutputBuf) const
{
double cost = 0;
double demand = 0;
double length = 0;
int num = 0;
CString tmp;
OutputBuf.Empty();
list<Path>::const_iterator it = pathSet.begin();
for (; it != pathSet.end(); ++it)
{// 数从第 i 个地包商出发的路径数
if (it->stops.size() <= 1) continue;
num+=1;
cost += it->cost;
demand += it->demand;
length += (it->length + it->distance);
}
tmp.Format("Total cost: %f\r\n", cost);
OutputBuf += tmp;
tmp.Format("Total number of RDCs: %d\r\n", RDCSet.size());
OutputBuf += tmp;
tmp.Format("Total number of dealers: %d\r\n", dealerSet.size());
OutputBuf += tmp;
tmp.Format("Total number of paths: %d\r\n", num);
OutputBuf += tmp;
tmp.Format("Total length of paths: %f\r\n", length);
OutputBuf += tmp;
tmp.Format("Average cost per path: %f\r\n", cost/num);
OutputBuf += tmp;
tmp.Format("Average cost per demand: %f\r\n", cost/demand);
OutputBuf += tmp;
tmp.Format("Average length per path: %f\r\n", length/num);
OutputBuf += tmp;
tmp.Format("Average demand per path: %f\r\n", demand/num);
OutputBuf += tmp;
tmp.Format("Average stops per path: %f\r\n", 1.0*dealerSet.size()/num);
OutputBuf += tmp;
OutputBuf += "\r\n";
for(int i = 0; i < RDCSet.size(); i++)
{
double rdc_demand = 0;
it = pathSet.begin();
for (; it != pathSet.end(); ++it)
{
if (it->stops.size() <= 1)
{
continue;
}
if( it->stops.front() == i )
{
rdc_demand += it->demand;
}
}
tmp.Format("Total demand of %s: %f\r\n", RDCSet[i].name.c_str(), rdc_demand);
OutputBuf += tmp;
}
OutputBuf += "\r\n";
it = pathSet.begin();
int pc = 1;
for (; it != pathSet.end(); ++it)
{
if (it->stops.size() == 1) continue;
tmp.Format("Path%03d:%d stop(s)\t%s", pc, it->stops.size()-1, RDCSet[it->stops.front()].name.c_str());
OutputBuf += tmp;
list<int>::const_iterator i = it->stops.begin();
for (++i; i != it->stops.end(); ++i)
{
const Dealer &d = dealerSet[*i];
tmp.Format("==>%s", d.name.c_str());
OutputBuf += tmp;
}
OutputBuf += "\r\n";
++pc;
}
tmp.Format("title('Total cost: %f');", cost);
engEvalString(ep, tmp);
}
void MFSolver::PrintInfo(Engine *ep) const
{
CString MatComLine;
int rdcNum = RDCSet.size();
int dlNum = dealerSet.size();
for (int i = 0; i < rdcNum; ++i)
{
const RDC &r = RDCSet[i];
MatComLine.Format("c%d = rand(1,3);", i);
engEvalString(ep, MatComLine);
MatComLine.Format("plot(%f,%f,'s','MarkerEdgeColor','k','MarkerFaceColor',c%d,'MarkerSize',10,'LineWidth',2);", r.x, r.y, i);
engEvalString(ep, MatComLine);
}
for (i = 0; i < dlNum; ++i)
{
const Dealer &d = dealerSet[i];
MatComLine.Format("plot(%f,%f,'p','color','k');", d.x, d.y);
engEvalString(ep, MatComLine);
}
}
double MFSolver::GetDistance(const Path &p, const Dealer &d) const
{
double x0,y0,x1,y1;
x0 = RDCSet[p.stops.front()].x;
y0 = RDCSet[p.stops.front()].y;
x1 = d.x;
y1 = d.y;
double dx = x1 - x0, dy = y1 - y0;
return 69*1.14*sqrt(dx*dx + dy*dy);
}
double MFSolver::GetLength(const Path &p, const Dealer &d) const
{
double x0,y0,x1,y1;
if (p.stops.size() == 1)
{
x0 = RDCSet[p.stops.back()].x;
y0 = RDCSet[p.stops.back()].y;
}
else
{
x0 = dealerSet[p.stops.back()].x;
y0 = dealerSet[p.stops.back()].y;
}
x1 = d.x;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -