⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfsolver.cpp

📁 研究多个dc对应多个dealer时得物流配送系统的优化问题
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -