概念
- 扩展节点:一个正在产生儿子的结点
- 活节点:一个自身已生产但其儿子还没有全部生成的结点
- 死结点:一个所有儿子已经产生的结点
回溯法解决0/1背包问题
BackTracking_zzk.cpp
#include "BackTracking_zzk.hpp"
#include <iostream>
using namespace std;
int n;
double c;
double* value;
double* weight;
int *order;
double cw = 0.0;
double cp = 0.0;
int *best_item_list;
int *item_list;
int best_value = 0;
double bound(int i) {
double capacity_left = c - cw;
double total_value = cp;
while (i <= n && weight[i] <= capacity_left) {
capacity_left -= weight[i];
total_value += value[i];
i++;
}
if (i <= n) {
total_value += value[i]/weight[i] * capacity_left;
}
return total_value;
}
double knapsack(double *pp,
double *ww,
double cc
) {
int i = 0,j;
UnitValue *unitValueList = new UnitValue[n+1];
double ws = 0.0;
double ps = 0.0;
for (int i = 1; i <= n; i++) {
unitValueList[i] = UnitValue(i,pp[i]/ww[i]);
ps = ps + pp[i];
ws = ws + ww[i];
}
if(ws <= c) {return ps;}
double temp = 0.0;
for (i = 1; i <= n ; i ++) {
for (j = 1; j<= n - i;j++ ){
if (unitValueList[j].unit_value < unitValueList[j+1].unit_value) {
UnitValue unitValueTemp = unitValueList[j];
unitValueList[j+1] = unitValueList[j];
unitValueList[j] = unitValueTemp;
temp = order[j];
order[j+1] = order[j];
order[j] = temp;
temp = value[j+1];
value[j+1] = value[j];
value[j] = temp;
temp = weight[j+1];
weight[j+1] = weight[j];
weight[j] = temp;
}
}
}
return 0;
}
void backtrack(int i) {
if (i > n) {
best_value = cp;
for (int _i=1; _i < i; _i++) {
best_item_list[_i] = item_list[_i];
}
return;
}
if (cw + weight[i] <= c) {
cw += weight[i];
cp += value[i];
item_list[i] = 1;
backtrack(i+1);
cw -= weight[i];
cp -= value[i];
item_list[i] = 0;
}
if(bound(i+1) > best_value) {
backtrack(i+1);
}
}
int backtrack_main() {
int i;
n = 3;c = 30;
value = new double[n+1];
weight = new double[n+1];
order = new int[n+1];
best_item_list = new int[n+1];
item_list = new int[n+1];
weight[1] = 15;weight[2] = 16;weight[3] = 15;
order[1] = 1;order[2]= 2;order[3] = 3;
value[1] = 25;value[2] = 45;value[3] = 25;
knapsack(value, weight, c);
backtrack(1);
cout << "最优价值为:" << best_value;
cout << "\n需要装入的物品编号是:";
for(i=1;i<=n;i++)
{
if(best_item_list[i]==1) {
cout << order[i]<< " ";
}
}
return 0;
}
BackTracking_zzk.hpp
#ifndef BackTracking_zzk_hpp
#define BackTracking_zzk_hpp
#include <stdio.h>
#include <iostream>
using namespace std;
class UnitValue {
public:
int id;
double unit_value;
UnitValue() {
}
UnitValue(int _id,double _unit_value) {
id = _id;
unit_value = _unit_value;
}
int compareTo(UnitValue x) {
double x_unit_value = x.unit_value;
if (unit_value < x_unit_value ) {
return -1;
}
if (unit_value == x_unit_value) {
return 0;
}
return 0;
}
bool equals (UnitValue x) {
return unit_value == x.unit_value;
}
};
double bound(int i);
double knapsack(double *pp,double *ww,double cc);
void backtrack(int i);
int backtrack_main();
#endif
N-Queens problem
NQueens.cpp
#include "part5backtrace.hpp"
Queen::Queen() {
sum = 0; n = 0; x = NULL;
}
Queen::~Queen() {
delete x;
}
void Queen::setn(int num)
{
n=num;
x=new int[num+1];
}
bool Queen::Place(int t) {
int i;
for (i = 1; i < t; i++) {
if ((abs(t - i) == abs(x[i] - x[t])) || (x[i] == x[t])) {
return false;
}
}
return true;
}
void Queen::Backtrack(int t) {
int i;
if (t > n) {
sum++;
outputX();
}else {
for (i = 1; i <= n; i++) {
x[t] = i;
if (Place(t)) {
Backtrack(t + 1);
}
}
}
}
void Queen::outputX()
{ int i;
for (i=1; i<=n; i++) {
cout<<x[i]<<" ";
}
cout<<endl;
}
void Queen::outputsum()
{
cout<<"Total="<<sum<<endl;
}
int queen_main()
{
Queen MyQueen;
int number;
cout<<"input the number of queens: ";
cin>>number;
MyQueen.setn(number);
MyQueen.Backtrack(1);
MyQueen.outputX();
MyQueen.outputsum();
return 0;
}
NQueens.hpp
#ifndef part5backtrace_hpp
#define part5backtrace_hpp
#include <stdio.h>
#include <iostream>
#include <cmath>
using namespace std;
class Queen{
private:
int n;
int *x;
int sum;
public:
Queen();
~Queen();
void setn(int num);
bool Place(int t);
void Backtrack(int t);
void outputX();
void outputsum();
};
int queen_main();
#endif