Capacitated Facility Location Problem

小编 2026-06-28 阅读:988 评论:0
Capacitated Facility Location Problem Suppose there are n facilities and m customers. We wish to...

Capacitated Facility Location Problem

Suppose there are n facilities and m customers. We wish to choose:
(1) which of the n facilities to open
(2) the assignment of customers to facilities
The objective is to minimize the sum of the opening cost and the assignment cost.
The total demand assigned to a facility must not exceed its capacity.

There are currently 71 data files. The format of these data files is:
|J| |I|
s_1 f_1
s_2 f_2

s_|J| f_|J|
d_1 d_2 d_3 … d_|I|
c_{11} c_{12} c_{13} … c_{1|I|}
c_{21} c_{22} c_{23} … c_{2|I|}
… … … …
c_{|J|1} c_{|J|2} c_{|J|3} … c_{|J||I|}
where:
|J| is the number of potential facility locations;
|I| is the number of customers;
s_j (j=1,…,|J|) is the capacity of facility j;
f_j (j=1,…,|J|) is the fixed cost of opening facility j;
d_i (i=1,…,|I|) is the demand of customer i;
c_{ji} (j=1,…,|J|), (i=1,…,|I|) is the cost of allocating all the demand of customer i to facility j.

算法如下

//测试文件与结果文件的读写
#ifndef _FILE_H_
#define _FILE_H_

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <string.h>
#include <sstream>
using namespace std;

//字符串分割
vector<string> split(const string& str, const string& delim) {
	vector<string> res;
	if(\"\" == str) return res;
	char * strs = new char[str.length() + 1];
	strcpy(strs, str.c_str()); 
	char * d = new char[delim.length() + 1];
	strcpy(d, delim.c_str());
	char *p = strtok(strs, d);
	while(p) {
		string s = p;
		res.push_back(s);
		p = strtok(NULL, d);
	}
	return res;
}

//测试数据获取
void getData(string path, int &fnum, int &cnum, vector<int> &_capacity, vector<int> &_open_cost, vector<int> &_demand, vector<int> &_ass_cost) {
    ifstream in(path);
    if (!in.is_open()) {
        cout << \"open error!\" << endl;
    }
    string str;
    getline(in, str);
    vector<string> sv;
    sv = split(str, \" \");
    int num[2];
    stringstream ss;
    for (int i = 0; i < 2; i++) {
        ss << sv[i];
        ss >> num[i];
        ss.clear();
    }
    int capacity[num[0]], open_cost[num[0]];
    for (int i = 0; i < num[0]; i++) {
        getline(in, str);
        sv = split(str, \" \");
        ss << sv[0];
        ss >> capacity[i];
        _capacity.push_back(capacity[i]);
        ss.clear();
        ss << sv[1];
        ss >> open_cost[i];
        _open_cost.push_back(open_cost[i]);
        ss.clear();
    }
    
    int demand[num[1]], flag = (num[1]+9)/10;
    for (int i = 0; i < flag; i++) {
        getline(in, str);
        int pos;
        if((pos = str.find(\".\")) != string::npos) {
            sv = split(str, \".\");
        }
        else {
            sv = split(str, \" \"); 
        }

        for (int j = 0; j < sv.size(); j++) {
            ss << sv[j];
            ss >> demand[i*10+j];
            _demand.push_back(demand[i*10+j]);
            ss.clear();
        }
    }

    flag = (num[0]*num[1]+9)/10;
    int ass_cost[num[0]*num[1]];
    for (int i = 0; i < flag; i++) {
        getline(in, str);
        int pos;
        if((pos = str.find(\".\")) != string::npos) {
            sv = split(str, \".\");
        }
        else {
            sv = split(str, \" \"); 
        }
        for (int j = 0; j < sv.size(); j++) {
            ss << sv[j];
            ss >> ass_cost[i*10+j];
            _ass_cost.push_back(ass_cost[i*10+j]);
            ss.clear();
        }
    }

    fnum = num[0];
    cnum = num[1];

    in.close();
}

//67号测试文件读取
void get67Data(string path, int &fnum, int &cnum, vector<int> &_capacity, vector<int> &_open_cost, vector<int> &_demand, vector<int> &_ass_cost) {
    ifstream in(path);
    if (!in.is_open()) {
        cout << \"open error!\" << endl;
    }
    string str;
    getline(in, str);
    vector<string> sv;
    sv = split(str, \" \");
    int num[2];
    stringstream ss;
    for (int i = 0; i < 2; i++) {
        ss << sv[i];
        ss >> num[i];
        ss.clear();
    }
    //cout << num[0] << \" \" << num[1] << endl;
    int capacity[num[0]], open_cost[num[0]];
    for (int i = 0; i < num[0]; i++) {
        getline(in, str);
        sv = split(str, \" \");
        ss << sv[0];
        ss >> capacity[i];
        _capacity.push_back(capacity[i]);
        ss.clear();
        ss << sv[1];
        ss >> open_cost[i];
        _open_cost.push_back(open_cost[i]);
        ss.clear();
    }
    
    int _size = 0;
    int demand[num[1]], flag = 40;
    for (int i = 0; i < flag; i++) {
        getline(in, str);
        int pos;
        if((pos = str.find(\".\")) != string::npos) {
            sv = split(str, \".\");
        }
        else {
            sv = split(str, \" \"); 
        }

        for (int j = 0; j < sv.size(); j++) {
            ss << sv[j];
            ss >> demand[_size];
            _demand.push_back(demand[_size]);
            _size++;
            ss.clear();
        }
    }

    flag = 1200;
    int ass_cost[num[0]*num[1]];
    _size = 0;
    for (int i = 0; i < flag; i++) {
        getline(in, str);
        int pos;
        if((pos = str.find(\".\")) != string::npos) {
            sv = split(str, \".\");
        }
        else {
            sv = split(str, \" \"); 
        }
        for (int j = 0; j < sv.size(); j++) {
            ss << sv[j];
            ss >> ass_cost[_size];
            _ass_cost.push_back(ass_cost[_size]);
            _size++;
            ss.clear();
        }
    }

    fnum = num[0];
    cnum = num[1];

    in.close();
}

//两个结果文件写入
void writeData(string str, int flag) {
    if (flag == 0) {
        ofstream out(\"result/time.txt\", ios::app);
        if (out.is_open()) {
            out << str;
            out << \"\\n\";
        }
        out.close();
    }
    else if (flag == 1) {
        ofstream out(\"result/answer.txt\", ios::app);
        if (out.is_open()) {
            out << str;
            out << \"\\n\";
        }
        out.close();
    }
}

#endif
//main.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <string.h>
#include <sstream>
#include <algorithm>
#include <ctime>
#include \"file.h\"
#include <windows.h>
using namespace std;
//设施
struct facility {
    int capacity;			//设施容量
    int remain_capacity;		//剩余容量
    int open_cost;			//开启设施的开销
    bool isopen = false;		//设施是否打开
};
//客户开销
struct cost{
    int cost;		//客户开销
    int facility;	//对应的设施
};
//客户
struct customer {
    int demand;				//客户对设施容量的需求
    vector<cost> cost;		//客户开销
    int facilityIndex = 0;	//客户所选择的设施编号(主要用于输出结果)
};
//核心算法
int greedy(int fnum, int cnum, facility fac[], customer cus[]) {
    int min_cost = 0;		//最小开销总和
    for (int i = 0; i < cnum; i++) {	//遍历所有客户
        for (int j = 0; j < fnum; j++) {	//遍历所有的设施
        	//找到最小开销的设施编号
            int facilityIndex = cus[i].cost[j].facility;
            //判断设施容量是否足够
            if (fac[facilityIndex].remain_capacity >= cus[i].demand) {
            	//判断设施是否已经启动
                if (!fac[facilityIndex].isopen) {
                		//未启动则启动设施,并计算启动设施的开销
                    fac[facilityIndex].isopen = true;
                    min_cost += fac[facilityIndex].open_cost;
                }
                //计算开销总和
                min_cost += cus[i].cost[j].cost;
                //剩余容量减小
                fac[facilityIndex].remain_capacity -= cus[i].demand;
                cus[i].facilityIndex = facilityIndex;
                break;	//退出循环
            }
        }
    }
    return min_cost;
}
//用于结构体对比排序
bool compare(const cost &a, const cost &b) {
     return a.cost < b.cost;
}
//int转string
void intToStr(const int &int_temp,string &string_temp) {  
        stringstream stream;  
        stream<<int_temp;  
        string_temp=stream.str();
}

int main() {
    /*string path;
    cout << \"please input the file path: \";
    cin >> path;
    string _path = \"instances/\"+path;*/
    int run = 1;
    //循环测试71个数据样例
    while (run < 72) {
        //获取文件路径
        stringstream ss;
        string temp;
        ss << run;
        ss >> temp;
        ss.clear();
        string path = \"instances/p\"+temp;
        //获取文件数据
        int fnum;
        int cnum;
        vector<int> capacity;
        vector<int> open_cost;
        vector<int> demand;
        vector<int> ass_cost;
        if (run == 67) {
            get67Data(path, fnum, cnum, capacity, open_cost, demand, ass_cost);
        }
        else { 
            getData(path, fnum, cnum, capacity, open_cost, demand, ass_cost);
        }
        //计时器
        LARGE_INTEGER BegainTime;     
        LARGE_INTEGER EndTime;     
        LARGE_INTEGER Frequency;     
        QueryPerformanceFrequency(&Frequency);     
        QueryPerformanceCounter(&BegainTime);
        //初始化设施
        facility fac[fnum];
        for (int i = 0; i < fnum; i++) {
            fac[i].capacity = capacity[i];
            fac[i].remain_capacity =@font-face {
				font-family: "autolinktags";
				src: url("https://www.seowoai.com/zb_users/plugin/AutoLinkTags/style/fonts/iconfont.woff2") format("woff2"),
				url("https://www.seowoai.com/zb_users/plugin/AutoLinkTags/style/fonts/iconfont.woff") format("woff"),
				url("https://www.seowoai.com/zb_users/plugin/AutoLinkTags/style/fonts/iconfont.ttf") format("truetype");
				font-weight:normal;
				font-style:normal;
			}.tagslink::after { content:"\e613"; margin:2px 0 0 0px; font-size:12px; font-family:"autolinktags"; display:inline-block; vertical-align:top; }															
版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
标签列表