# 回溯法 -- 装载问题

(1)首先将第一艘轮船尽可能装满；
(2)将剩余的集装箱装上第二艘轮船。

``````using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 装载问题
{
{
static int n;             // 集装箱数
static int[] weight;      // 集装箱重量数组
static int limitWeight;   // 第一艘轮船的载重量
static int currentWeight; // 当前载重量
static int bestWeight;    // 当前最优载重量
static int remainWeight;  // 剩余集装箱重量
static int[] x;           // 当前解
static int[] bestx;       // 当前最优解

/// <summary>
/// 使用回溯法求解装载问题，调用递归方法backtrack(0)实现回溯搜索。
/// </summary>
/// <param name="weightArray">重量数组</param>
/// <param name="c1Weight">轮船c1的载重量</param>
/// <param name="_x">[返回]最优解</param>
/// <returns>返回不超过c1Weight的最大子集和</returns>
public static int maxLoading(int[] weightArray, int c1Weight, out int[] _x)
{
/* 初始化数据成员 */
n = weightArray.Length - 1;
weight = weightArray;
limitWeight = c1Weight;
currentWeight = 0;
bestWeight = 0;
x = new int[n + 1];
_x = new int[n + 1];
bestx = _x;

/* 初始化剩余集装箱的重量 */
foreach(int elem in weight)
{
remainWeight += elem;
}

/* 计算最优载重量 */
backtrack(0);
return bestWeight;
}

/// <summary>
/// 搜索子集树的第i层子树
/// </summary>
/// <param name="i"></param>
private static void backtrack(int i)
{
if (i > n) {
if (currentWeight > bestWeight) {
x.CopyTo(bestx, 0);
bestWeight = currentWeight;
}
return;
}

remainWeight -= weight[i];
if (currentWeight + weight[i] <= limitWeight) {
x[i] = 1;
currentWeight += weight[i];
backtrack(i + 1);
currentWeight -= weight[i];
}

if (currentWeight + remainWeight > bestWeight) {
x[i] = 0;
backtrack(i + 1);
}
remainWeight += weight[i];
}
}
}
``````
``````using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 装载问题
{
class Program
{
static void Main(string[] args)
{
// 集装箱重量数组
int[] w = new int[] {10, 40, 40, 23, 41, 12, 6, 78, 44, 154 };

int c1 = 250;
int c2 = 200;
int[] x;

int weight = 0;
foreach(int elem in w)
{
weight += elem;
}

if (c2 < weight - bestc1)
{
Console.WriteLine("无解。");
return;
}

Console.WriteLine("c1可装载{0}", bestc1);
Console.WriteLine("c1包含集装箱：");
for(int i=0; i<x.Length; i++)
{
if (x[i] == 1)
{
Console.Write("{0} ", i + 1);
}
}
Console.WriteLine();
Console.WriteLine();

Console.WriteLine("c2可装载{0}", weight - bestc1);
Console.WriteLine("c2包含集装箱：");
for (int i = 0; i < x.Length; i++)
{
if (x[i] == 0)
{
Console.Write("{0} ", i + 1);
}
}
Console.WriteLine();
}
}
}
``````

原文作者：回溯法
原文地址: https://blog.csdn.net/gouki04/article/details/4665653
本文转自网络文章，转载此文章仅为分享知识，如有侵权，请联系博主进行删除。