一、算法要求
有一批集装箱要装上一艘载重量为c的轮船。其中集装箱i的重量为Wi。
确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
1. 思路
一种获取最优分配的贪婪方法是逐步分配任务。每步分配一件任务,且按照任务的非递减顺序进行分配。
若已经至少有一件任务分配给某台机器,则称这台机器是旧的;若机器非旧则它就是新的。
在选择机器时,遵循的贪婪法则为:根据欲分配任务的开始时间,若此时有旧的机器可用,则将任务分配给旧机器。否则,任务分配给新机器。
首先,按照任务时间区间递增排列(可以使用堆),然后,按照贪婪准则“先旧后新”将任务分配给机器。
二、完整代码
1. 主文件
main.cpp:
// Project2: 最优装载
#include <iostream>
#include <iomanip>
using namespace std;
const int N = 8; //货物总数量
template <class Type>
void Swap(Type& x, Type& y){
Type temp = x;
x = y;
y = temp;
}
template<class Type>
void SelectSort(Type w[], int* t, int n){
Type tempArray[N + 1], temp;
//将w拷贝到临时数组tempArray中
//void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1。
memcpy(tempArray, w, (n + 1) * sizeof(Type));
int min;
for (int i = 1; i <= n; i++){
t[i] = i;
}
for (int i = 1; i < n; i++){
min = i;
for (int j = i + 1; j <= n; j++){
if (tempArray[min] > tempArray[j]){
min = j;
}
}
Swap(tempArray[i], tempArray[min]);
Swap(t[i], t[min]);
}
}
template<class Type>
void Loading(int x[], Type w[], Type c, int n){
int* t = new int[n + 1];//存储排完序后w[]的原始索引
SelectSort(w, t, n);
for (int i = 1; i <= n; i++){
x[i] = 0;//初始化数组x[]
}
for (int i = 1; i <= n && w[t[i]] <= c; i++){
x[t[i]] = 1;
c -= w[t[i]];
}
}
int main(){
//n=8,c=400
//w[]=[100, 200, 50, 90, 150, 50, 20, 80]
int x[N + 1]; //选择数组x[]
float c = 400, //最大容量
w[] = { 0, 100, 200, 50, 90, 150, 50, 20, 80 }; //数组对齐
cout << "#The capacity of the ship is: " << c << endl;
cout << "#The weight of the items to be loaded is as follows: " << endl;
for (int i = 1; i <= N; i++){
cout << setw(4) << w[i] << " ";
}
cout << endl;
Loading(x, w, c, N);
cout << "\n#The result of the greedy algorithm is as follows:" << endl;
for (int i = 1; i <= N; i++){
cout << setw(4) << x[i] << " ";
}
cout << endl;
return 0;
}
2. 效果展示
输入:
输出:
—
三、补充
算法复杂度分析:
(1)时间复杂度:首先需要按古董重量排序,调用sort函数,其平均时间复杂度为O(nlogn),输入和贪心策略求解的两个for语句时间复杂度均为O(n),因此时间复杂度为O(n+nlog(n))。
(2)空间复杂度:程序中变量 tmp、ans等占用了一些辅助空间,这些辅助空间都是常数阶的,因此空间复杂度为O(1)。
文档供本人学习笔记使用,仅供参考。