VRP--车辆路径问题 c++

【问题说明】
通过实际案例描述,根据配送点和业务需求量,进行最优路线的计算。由物流中心点出发,配送多个客户点后再回到起点,根据车辆数量,承载限制,不同车辆服务成本、运行里程限制等条件选择最优运输路径(总里程最短),使成本最小化,配送订单最大化,满载率最大化(如由一个配送中心向各个销售点配送货物,通过算法确定配送中心每辆车的配送方案,包括配送至哪个客户,配送量,下一个配送目的地)。

【测试数据和说明】
某物流中心有5台配送车辆,车辆的最大载重均为8T,一次配送的最大行驶距离都为50KM,需要向20个客户送货,物流中心和20个客户的坐标及其客户的需求量随机产生,其中,物流中心的坐标为(14.2KM,13.1km),要求合理安排车辆的配送路线和载重量,使配送总里程最短。
客户点 横坐标x(km) 纵坐标y(km) 需求量q(t)
1 12.8 8.5 0.1
2 18.4 3.4 0.4
3 15.4 16.6 1.2
4 18.9 15.2 1.5
5 15.5 11.6 0.8
6 3.9 10.6 1.3
7 10.6 7.6 1.7
8 8.6 8.4 0.6
9 12.5 2.1 1.2
10 13.8 5.2 0.4
11 6.7 16.9 0.9
12 14.8 2.6 1.3
13 1.8 8.7 1.3
14 17.1 11 1.9
15 7.4 1 1.7
16 0.2 2.8 1.1
17 11.9 19.8 1.5
18 13.2 15.1 1.6
19 6.4 5.6 1.7
20 9.6 14.8 1.5
说明:各客户相互之间和物流中心与客户之间的距离均采用直线距离

1.传统贪心算法

#include 
#include 
#include 
#include 

using namespace std;

double map[21][3] = {14.2,13.1,0,12.8,8.5,0.1,18.4,3.4,0.4,15.4,16.6,1.2,18.9,15.2,1.5,15.5,11.6,0.8,3.9,10.6,1.3,10.6,7.6,1.7,8.6,8.4,1.6,12.5,2.1,1.2,13.8,5.2,0.4,6.7,16.9,0.9,14.8,2.6,1.3,1.8,8.7,1.3,17.1,11,1.9,7.4,1,1.7,0.2,2.8,1.1,11.9,19.8,1.5,13.2,15.1,1.6,6.4,5.6,1.7,9.6,14.8,1.5};

// Is visited?
bool flag[21] = {false};


double Dist(double x1, double y1, double x2, double y2) {
    return (double)pow((pow((x2 - x1), 2) + pow((y2 - y1), 2)), 0.5);
}

// Dist Matrix
void Graph(double distances[21][21]) {
    for (int i = 0; i < 21; i++) {
        for (int j = i + 1; j < 21; j++) {
            distances[i][j] = Dist(map[i][0], map[i][1], map[j][0], map[j][1]);
            distances[j][i] = distances[i][j];
        }
        distances[i][i] = 10000;
    }
}

// Index of Min Every Row
int SeletMin(double distances[21][21], int row, double sum) {
    double min = 10000;
    int minIndex = 22;
    for (int i = 0; i < 21; i++) {
        if (!flag[i] && distances[row][i] < min)
        {
            min = distances[row][i];
            minIndex = i;
        }
    }
    if (minIndex == 22) {
        return -1;
    }
    return minIndex;
}

int main(void) {
    double distances[21][21] = {{0}, {0}};
    Graph(distances);
    double sum_all;
    flag[0] = true;
    for (int i = 0;i< 5;++i)
    {
        double sum = 0;
        double weight = 0;
        int minIndex = 0,finish = 0;
        while ((sum + distances[0][finish]) <= 50 || finish== 0)
            {
                minIndex = SeletMin(distances, minIndex,sum);
                if (minIndex == -1)
                {
                    break;
                }
                if (sum + distances[finish][minIndex] + distances[0][minIndex]>50)
                {
                    break;
                }
                if (weight + map[minIndex][2]>8)
                    break;
                weight += map[minIndex][2];
                cout << minIndex <<' ';
                flag[minIndex] = true;
                sum += distances[finish][minIndex];
                finish = minIndex;
            }
        if(sum != 0)
            {
                sum = sum + distances[0][finish];
                cout << endl;
                cout << sum<< endl;
                cout << weight << endl;
            }
        sum_all += sum;

    }
    cout << sum_all;
    return 0;
}

VRP--车辆路径问题 c++_第1张图片

2.变种贪心算法

每次将最近距离的客户点分配给车。

#include 
#include 
#include 
#include 

using namespace std;

double map[21][3] = {14.2,13.1,0,12.8,8.5,0.1,18.4,3.4,0.4,15.4,16.6,1.2,18.9,15.2,1.5,15.5,11.6,0.8,3.9,10.6,1.3,10.6,7.6,1.7,8.6,8.4,1.6,12.5,2.1,1.2,13.8,5.2,0.4,6.7,16.9,0.9,14.8,2.6,1.3,1.8,8.7,1.3,17.1,11,1.9,7.4,1,1.7,0.2,2.8,1.1,11.9,19.8,1.5,13.2,15.1,1.6,6.4,5.6,1.7,9.6,14.8,1.5};

// Is visited?
bool flag[21] = {false};


double Dist(double x1, double y1, double x2, double y2) {
    return (double)pow((pow((x2 - x1), 2) + pow((y2 - y1), 2)), 0.5);
}

// Dist Matrix
void Graph(double distances[21][21]) {
    for (int i = 0; i < 21; i++) {
        for (int j = i + 1; j < 21; j++) {
            distances[i][j] = Dist(map[i][0], map[i][1], map[j][0], map[j][1]);
            distances[j][i] = distances[i][j];
        }
        distances[i][i] = 10000;
    }
}

// Index of Min Every Row
int SeletMin(double distances[21][21], int row, double sum) {
    double min = 10000;
    int minIndex = 22;
    for (int i = 0; i < 21; i++) {
        if (!flag[i] && distances[row][i] < min) {
            min = distances[row][i];
            minIndex = i;
        }
    }
    if (minIndex == 22) {
        return -1;
    }
    return minIndex;
}

int main(void) {
    double distances[21][21] = {{0}, {0}};
    Graph(distances);
    double sum_all = 0;
    flag[0] = true;

    double sum[5] = {0};
    double weight[5] = {0};
    int minIndex[5] = {0};
    int finish[5] = {0};

    int route[5][20] = {{0}, {0}};

    int count = 20;

    while (count > 0) {
        //every vihicle one step
        for (int i = 0; i < 5; i++) {
            if ((sum[i] + distances[0][finish[i]]) <= 50 || finish[i] == 0) {
                minIndex[i] = SeletMin(distances, minIndex[i], sum[i]);
            }
            if (minIndex[i] == -1) {
                break;
            }
            if (sum[i] + distances[finish[i]][minIndex[i]] + distances[0][minIndex[i]]>50) {
                break;
            }
            if (weight[i] + map[minIndex[i]][2] > 8) {
                break;
            }
            flag[minIndex[i]] = true;
            count--;
            cout << "第" << i << "辆车选择" << minIndex[i] << endl;
            weight[i] += map[minIndex[i]][2];
            sum[i] += distances[finish[i]][minIndex[i]];
            finish[i] = minIndex[i];
        }
    }
    
    for (int i = 0; i < 5; i++) {

        sum[i] += distances[0][finish[i]];
        cout << "第" << i << "辆车路径为" << sum[i] << endl;
        sum_all += sum[i];
        cout << "第" << i << "辆车重量为" << weight[i] << endl;
    }
    cout << sum_all << endl;

//    for(int i=0;i<21;i++)
//    {
//        for(int j=0;j<21;j++)
//        {
//            cout <<"["<< i << "][" << j << "]" << distances[i][j] <<"   ";
//        }
//        cout<50) {
        //        break;
        //    }
        //    if (weight[i] + map[minIndex[i]][2] > 8) {
        //        break;
        //    }
        //    weight[i] += map[minIndex[i]][2];
        //    cout << minIndex[i] <<' ';
        //    flag[minIndex[i]] = true;
        //    sum[i] += distances[finish[i]][minIndex[i]];
        //    finish[i] = minIndex[i];
        //}
        //if(sum[i] != 0) {
        //    sum[i] = sum[i] + distances[0][finish[i]];
        //    cout << endl;
        //    cout << sum[i] << endl;
        //    cout << weight[i] << endl;
        //}
        //sum_all += sum[i];
    return 0;
}

VRP--车辆路径问题 c++_第2张图片

你可能感兴趣的:(٩,计算机算法设计,و,算法)