分支定界算法实现

时间:2012-02-21 00:04:55

标签: c++ nodes branch-and-bound

我需要实现分支定界算法,以证明我的学士论文中存储管理分配策略的有效性。 我不是程序员,我在C中有一些小知识,但我可以意识到这个算法不能马上编写,因为它是一种人工智能,需要做出决策。

我想知道解决这个问题的方法是什么。

我有迭代1的工作代码,因此它计算每个节点所需的一切,但我将数据存储在一个简单的结构数组中,代表了1级节点。问题是现在,如果x是级别节点的数量,我必须分别从节点1,2,3,...创建x-1,x-2,x-3,......新节点。

所以我在问,是否有人能够以正确的方式解决问题。

这是我到目前为止的代码,第一次迭代工作,对不起,但评论是意大利语:

//
//  main.cpp
//  prova1
//
//  Created by Marco Braglia on 13/02/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

// definizione nuova struttura per i nodi dell'albero decisionale
struct nodo{
  int last_prod;
  int last_slot;
  float Z_L;
  float Z_U;
  float g;
  bool fathomed;
 };

// dichiarazione variabili
float distanze[361];
int   slot[112];
int slot_cum[112];
float COIp[112];
int domanda[112];
struct nodo n_0;
struct nodo n_1[112];
struct nodo n_2[111][111];
float Zb;

float LowerBound(struct nodo n);
float UpperBound(struct nodo n);

int main()
{



// lettura dati input
// distanze slot

ifstream dist_file ( "/Users/MarcoBi/Desktop/TESI di LAUREA/Xcode/dati/distanze.txt" );


if ( !dist_file.is_open() ) {
    // il file non può essere aperto
}
else {
    // leggi i dati nell'array distanze[]
    for(int i=1; !dist_file.eof(); i++){
        dist_file >> distanze[i];
    }

   // visualizza l'array per controllo
   //for(int i=0; i<360; i++){
     //cout << distanze[i] << "\n ";
    //}
}

//slot necessari per prodotto

ifstream slot_file ( "/Users/MarcoBi/Desktop/TESI di LAUREA/Xcode/dati/slot.txt" );

if ( !slot_file.is_open() ) {
    // il file non può essere aperto
}
else {
    // leggi i dati nell'array slot[]
    for(int i=1; !slot_file.eof(); i++){
        slot_file >> slot[i];
    }

    for(int i=0; i<112; i++){
        slot_cum[i]=0;
    }

    for(int i=1; i<112; i++){
        slot_cum[i]=slot_cum[i-1]+slot[i];
    }
    // visualizza l'array per controllo
  //  for(int i=0; i<111; i++){
  //  cout << slot[i] << "\n ";
  // }
 //   cin.get();
}

// COIp

ifstream coi_file ( "/Users/MarcoBi/Desktop/TESI di LAUREA/Xcode/dati/COIp.txt" );

if ( !coi_file.is_open() ) {
    // il file non può essere aperto
}
else {
    // leggi i dati nell'array COIp[]
    for(int i=1; !coi_file.eof(); i++){
        coi_file >> COIp[i];
    }

    // visualizza l'array per controllo
    //for(int i=0; i<111; i++){
    //    cout << COIp[i] << "\n ";
  //  }
}

ifstream d_file ( "/Users/MarcoBi/Desktop/TESI di LAUREA/Xcode/dati/domanda.txt" );

if ( !d_file.is_open() ) {
    // il file non può essere aperto
}
else {
    // leggi i dati nell'array COIp[]
    for(int i=1; !d_file.eof(); i++){
        d_file >> domanda[i];
    }
}


//inizializzazione nodi
n_0.last_prod=0;
n_0.last_slot=0;
n_0.Z_L = 0;
n_0.Z_U = 0;
n_0.g = 0;
n_0.fathomed = false;
    for (int j=0; j<112; j++){

            n_1[j].last_prod = 0;
            n_1[j].last_slot = 0;
            n_1[j].Z_L = 0;
            n_1[j].Z_U = 0;
            n_1[j].g = 0;
            n_1[j].fathomed = false;
        }


//inizializzazione soluzione obiettivo ad infinito
Zb=999999999999;

//calcolo bounds per nodi al livello 1
for(int i=1;i<112;i++){
        n_1[i].last_prod=i;
        n_1[i].last_slot=slot_cum[i];
        n_1[i].Z_L=LowerBound(n_1[i]);
        n_1[i].Z_U=UpperBound(n_1[i]);

    //calcolo g_c
    float dm;
    int D;
    for(int i=1;i<112;i++){
        dm=0;
        for(int j=1;j<=slot_cum[i];j++){
            dm=dm+distanze[j];
        }
        dm=dm/slot_cum[i];
        D=0;
        for(int k=1;k<=n_1[i].last_prod;k++){
            D=D+domanda[k];
        }            
        n_1[i].g=2*dm*D;
    }
    if (i==111) (n_1[i].fathomed=true);                         //fathoming Rule 1 (ultimo prodotto)
    if (n_1[i].Z_L>n_1[i].Z_U) (n_1[i].fathomed=true);          //fathoming Rule 3 (LB > UB)
    if (n_1[i].Z_U<Zb) (Zb=n_1[i].Z_U);                         //aggiorna UB migliore

}

ofstream livello1 ( "/Users/MarcoBi/Desktop/TESI di LAUREA/Xcode/risultati/livello1.txt" );

for(int i=1; i<112; i++){
   if (n_1[i].fathomed==false)
        (livello1 <<"("<< i <<","<<n_1[i].last_slot<<")"<< " LB=" << n_1[i].Z_L << " UB=" << n_1[i].Z_U << " g=" << n_1[i].g <<'\n');
}

}

float LowerBound(struct nodo n){
 int S[112];
 float d[112];
 float dmin[112];
 int q[112];
 float D;
 float LB;

 for(int i=1; i<112; i++){
    q[i]=q[i-1]+slot[i];
 }

//Calcolo S_pigreco
for(int i=0;i<112;i++){
    S[i]=0;
}

for(int i=n.last_prod +2;i<112;i++){
    for(int j=n.last_prod +1;j<=i;j++){
        S[j]=S[j-1]+slot[j];
    }
}
S[110]=S[109] + slot[110];
S[111]=S[110] + slot[111];

//calcolo somma distanze da slot j+1 a q
for(int i=0;i<112;i++){
    d[i]=0;
}

for(int j=n.last_prod + 1;j<112;j++){
    for(int i=n.last_slot + 1; i<n.last_slot + 1 + S[j]; i++){
        d[j]=d[j]+distanze[i];
    }
}

//calcolo dmin_pigreco
for(int i=n.last_prod +1; i<112; i++){
    dmin[i]= d[i]/S[i];
}

D=0;
for(int i=n.last_prod +1; i<112; i++){
    D=D+dmin[i]*domanda[i];
}
LB=(2*D);
    return LB;
}

float UpperBound(struct nodo n){
 float Ud;
 float Ur;
 int S[112];
 float d[112];
 float dm;
 int D;

for(int i=0;i<112;i++){
    S[i]=0;
}
for(int i=n.last_prod +2;i<112;i++){
    for(int j=n.last_prod +1;j<=i;j++){
        S[j]=S[j-1]+slot[j];
    }
}

//calcolo Ud
for(int i=0;i<112;i++){
    d[i]=0;
}

int t=n.last_slot;

for(int i=n.last_prod +1;i<112;i++){
    for(int j=t + 1; j<=t + slot[i]; j++){
        d[i]=d[i]+distanze[j];
    }
    t=t+slot[i];
    d[i]=d[i]/slot[i];
}
Ud=0;
Ur=0;

for(int i=n.last_prod +1;i<112;i++){
    Ud=Ud + 2*(d[i]*domanda[i]);
}

//calcolo Ur
dm=0;
for(int i=n.last_slot +1; i<361; i++){
    dm=dm+distanze[i];
}

dm=dm/(360-n.last_slot);

D=0;

for(int i=n.last_prod +1; i<112; i++){
    D=D+domanda[i];
}

Ur=2*dm*D;

return min(Ur,Ud);
} 

1 个答案:

答案 0 :(得分:1)

听起来你需要动态分配结构的数组,然后将它们链接到结构中的节点。为此,you would add a pointer to the struct type in the struct itself,然后分配一个新的结构数组和assign the resulting address to the pointer in your original struct。然后,您可以在浏览搜索空间时navigate from node to node as necessary

您的示例比上面的链接列表示例复杂一点,因为它会在您搜索空间时成为树,但您可以使用它来获取C中动态数据结构的基础知识,那么您应该是能够适应你的情况。