| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 406 人关注过本帖
标题:分支限界法实例编程
只看楼主 加入收藏
ptuhawk
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2009-10-3
收藏
 问题点数:0 回复次数:0 
分支限界法实例编程
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int **c,*a;
char *s;
int len,n;
template<class T>
class Queue;
class OutOfBounds
{
public:
    OutOfBounds(){}
};
template<class T>
class Node{
    friend Queue<T>;
    private:
        T data;
        Node<T> * next;
};
template<class T>
class Queue{
    public:
        Queue(){front=rear=0;}
        ~Queue();
        bool Empty() const
        {
            return (front==rear);
        }

        Queue<T>& EnQueue(const T& x);
        Queue<T>& DeQueue(T& x);
    private:
        Node<T> * front;
        Node<T> * rear;
};
template<class T>
Queue<T>:: ~Queue()
{
    Node<T> * next;
    while(front)
    {
        next=front->next;
        delete front;
        front=next;
    }
}

template<class T>
Queue<T>& Queue<T>::EnQueue(const T& x)
{
    Node<T> *p=new Node<T>;
    p->data=x;
    p->next=0;
    if(front)
        rear->next=p;
    else front=p;
    rear=p;
    return *this;
}
template<class T>
Queue<T>& Queue<T>::DeQueue(T& x)
{
    if(Empty()) throw OutOfBounds();
    x=front->data;
    Node<T> *p=front;
    front=front->next;
    delete p;
    return *this;
}

class QueueNode
{
   
    friend int move(int );
private:
        int level;
        int space;
        int ball;        
};


void compute(int t)         //compute c[i][j]
{
    for(int i=1;i<t;i++)
    {
        c[i][0]=1;
        c[i][1]=i;
        c[i][i-1]=i;
        c[i][i]=1;
        for(int j=2;j<i-1;j++)
            c[i][j]=c[i-1][j-1]+c[i-1][j];
    }     
}
int init()      //delete space,search place of a and space
{
    int j=-1,i,t=1;
    for(i=0;i<2*n;i++)
    {
        if(s[i]=='.')  
        {
            j=i;
            break;
        }
        if(s[i]=='a') a[t++]=i;
    }
    for(i=j;i<2*n-2;i++)
    {
        s[i]=s[i+2];
        if(s[i]=='a') a[t++]=i;
    }
    return j;
}
int change(int *aa)       //change string to int
{
   aa[0]=-1;
   int i,j,value=0;
   for(i=1;i<n;i++)
      for(j=aa[i-1]+1;j<aa[i];j++)
          value+=c[len-j][n-1-i];
   return value;
}
void changeback(int v,int *aa)
{
    aa[0]=-1;
    int i=1,j=0,d;
    while(i<n)
    {
        d=v-c[len-j][n-1-i];
        if(d>=0)
        {
            v=d;
            j++;
        }
        else aa[i++]=j++;
    }
}
int move(int space)
{
    int t=change(a);
    if(t==0) return 0;
    int sf,i,j,l,lev=0,sp=space,number=1;
    for(i=2;i<=n;i++)
        number+=c[2*n-i][n-2];

    int *v=new int[number];
    for(i=0;i<number;i++)
        v[i]=0;

    Queue<QueueNode> Q;
    QueueNode N;
    int *aa=new int [n];

    while(true)
    {
        changeback(t,aa);
        sf=n;
        for(i=1;i<n;i++)    //search the first a after space
        {
            if(aa[i]>=sp)  
            {
                sf=i;
                break;
            }
        }

        bool *m=new bool[len];
        for(i=0;i<len;i++)
        {
            m[i]=true;
        }
        m[len-1]=false;            // ball can not move
        if(sp>0) m[sp-1]=false;
        
        for(i=1;i<n;i++)   // the first moveball is a
        {
            if(m[aa[i]])
            {
                m[aa[i]]=false;
                int *bb=new int[n];
                for(l=1;l<n;l++)
                   bb[l]=aa[l];
                     
                if(i<sf)              // move right
                {
                    N.space=aa[i];
                    bb[i]=sp-2;
                    j=i+1;
                    if(j<sf && aa[j]==aa[i]+1) // the moveballs is aa
                    {
                        bb[j]=sp-1;
                        j++;
                    }
                    while(j<sf) bb[j++]-=2;               
                }
                else         // move left
                {
                    N.space=aa[i]+2;
                    bb[i]=sp;
                    if(i<n-1 && aa[i+1]==aa[i]+1) bb[i+1]=sp+1; // the moveballs is aa
                    for(j=sf;j<i;j++)
                        bb[j]+=2;
                }

                sort(bb+1,bb+n);
                t=change(bb);
                delete []bb;
                if(t==0)           //find the result
                {
                    delete []v;
                    delete []aa;
                    return lev+1;
                }

                if(!(v[t] & (1<<N.space)))
                {                          //have not reach this state
                    v[t]|= (1<<N.space);
                    N.ball=t;
                    N.level=lev+1;
                    Q.EnQueue(N);
                }
           
            }
        }
        // the first moveball is b
        j=1;
        for(i=0;i<len;i++)
        {
            if(m[i])
            {
                while(j<n && aa[j]<i) j++;
                int *bb=new int[n];
                for(l=1;l<n;l++)
                    bb[l]=aa[l];
                if(i<sp)            //move right
                {
                    N.space=i;
                    if(j<n && aa[j]==i+1) // the moveballs is ba
                    {
                        bb[j]=sp-1;
                        l=j+1;
                    }
                    else l=j;
                    while(l<sf) bb[l++]-=2;
                }
                else                   //move left
                {
                    N.space=i+2;
                    if(j<n && aa[j]==i+1) bb[j]=sp+1;// the moveballs is ba
                    for(l=sf;l<j;l++)
                        bb[l]+=2;   
                }

                sort(bb+1,bb+n);
                t=change(bb);
                delete []bb;
                if(t==0)     //find the result
                {
                    delete []v;
                    delete []aa;
                    return lev+1;
                }

                if(!(v[t] & (1<<N.space)))
                {
                    v[t]|= (1<<N.space);
                    N.ball=t;
                    N.level=lev+1;
                    Q.EnQueue(N);
                }
            }
        }
        delete []m;
        if(Q.Empty()) break;
        Q.DeQueue(N);
        lev=N.level;
        sp=N.space;
        t=N.ball;
    }

    delete []v;
    delete []aa;
    return -1;
}
void main()
{
    int k,i;
    cin>>k;
    while(k>0)
    {

        cin>>n;
        s=new char[2*n];
        i=0;
        cin.get();
        char t;
        while(cin.get(t)&&t!='\n')
        {
            s[i++]=t;
        }
        if(i<2*n) cout<<"No Solution"<<endl;
        else
        {
            len=2*n-2;
            int q=len+1;
            c=new int *[q];
            for(i=0;i<q;i++)
                c[i]=new int [q];
            compute(q);
            a=new int[n];
            int space=init();
            i=move(space);
            
            if(i<0) cout<<"No Solution"<<endl;
            else cout<<i<<endl;
            for(i=0;i<q;i++)
                delete [] c[i];
            delete []c;
        }
        delete []s;
        k--;
    }

}

能否在此基础上对程序进行修改优化,或者将某些程序用其他语句代替?算法不变...
搜索更多相关主题的帖子: 实例 分支 
2009-10-03 20:06
快速回复:分支限界法实例编程
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017500 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved