算法导论三

背包问题

// 1.knapsack 背包问题

#include<iostream>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
const int volume = 100;// 背包容量
const int N = 5;//物品数量
struct OBJECTS{
    int value;
    int weight;
    float rate;
};
OBJECTS objects[N];
void swap(OBJECTS &a,OBJECTS &b)
{
    OBJECTS X;
    X = a;
    a =b;
    b =X;
}
// FOR test 
void init_1()
{
    objects[0].value=20;objects[0].weight=10;objects[0].rate=2;
    objects[1].value=30;objects[1].weight=20;objects[1].rate=1.5;
    objects[2].value=65;objects[2].weight=30;objects[2].rate=2.1;
    objects[3].value=40;objects[3].weight=40;objects[3].rate=1;
    objects[4].value=60;objects[4].weight=50;objects[4].rate=1.2;
}
//正常初始化
/* void init()
{
    float value,weight,r;
    for(int i=0;i<N;i++)
    {
        cin>>value>>weight;
        r=value/weight;
        // cin>>objects[i].value>>objects[i].weight;
        objects[i].value = value;
        objects[i].weight = weight;
        objects[i].rate = r;
    }
} */

//quicksort
//random qk_sort// n l o g n避免了最坏情况
int partition(int p,int r)
{
    float x=objects[r].rate;
    int i=p-1;
    for(int j=p;j<r;j++)
    {
        if(objects[j].rate<=x)
        {
            i+=1;
            OBJECTS X;
            X = objects[i];
            objects[i] = objects[j];
            objects[j] = X;
            //swap(a[i],a[j]);
        }
    }
    OBJECTS Y;
    Y = objects[i+1];
    objects[i+1] = objects[r];
    objects[r] = Y;
    //swap(a[i+1],a[r]);
    return i+1;
}
int random_partition(int p,int r)
{
    int i=p+rand()%(r-p+1);
    OBJECTS X;
    X = objects[i];
    objects[i] = objects[r];
    objects[r] = X;
    //swap(a[i],a[r]);
    int n;
    n=partition(p,r);
    return n;
}
void random_qk_sort(int p,int r)
{
    int q;
    if(p<r)
    {
        q=random_partition(p,r);
        random_qk_sort(p,q-1);
        random_qk_sort(q+1,r);
    }
}
//print objects struct array
void print()
{
    for(int i=0;i<N;i++)
    {
        cout<<objects[i].rate<<" ";
    }
    cout<<endl;
}
// fractional knapsack
void frac_knapsack()
{
    //quicksort nlg(n)
    random_qk_sort(0,N-1);
    float sum=0;
    float count=0;
    //贪心算法 已权值最大的优先
    for(int i=N-1;i>=0;i--)
    {
        if(sum<volume)
        {
            if(objects[i].weight<=(volume-sum))
            {
                sum+=objects[i].weight;
                count+=objects[i].value;
                cout<<i<<" "<<objects[i].value<<" "<<objects[i].weight<<endl;
            }
            else
            {   
                count+=(volume-sum)*objects[i].rate;
                //sum+=(volume-sum);
                cout<<i<<" "<<(volume-sum)*objects[i].rate<<" "<<(volume-sum)<<endl;
                sum=volume;
            }
        }
        else break;
    }
    cout<<count<<endl;
}
//0-1 knapsack 最大值155 ---1 1 1 1 0
int zero_one_knapsack()
{
    int vec[N+1][volume+1];
    for(int i=0;i<=N;i++)
    {
        vec[i][0] = 0;
    }
    for(int j = 0;j<=volume;j++)
    {
        vec[0][j]=0;
    }
    for(int i=1;i<=N;i++)
    {
        for(int j=1;j<=volume;j++)
        {
            if(j<objects[i-1].weight)
            {
                vec[i][j]=vec[i-1][j];
            }
            else{
                vec[i][j]=max(vec[i-1][j],vec[i-1][j-objects[i-1].weight]+objects[i-1].value);
            }
        }
    }
    int x[N+1];
    int j=volume;
    for(int i=N;i>0;i--)
    {
        if(vec[i][j]>vec[i-1][j])
        {
            x[i]=1;
            j=j- objects[i-1].weight;
        }
        else
        {
            x[i]=0;
        }
    }
    for(int i=1;i<=N;i++)
    {
        cout<<x[i]<<" ";
    }
    cout<<endl;
    return vec[N][volume]; 
}
int main()
{
    init_1();
    print();
    random_qk_sort(0,N-1);
    print();
    //分数背包 结果为163 时间复杂度nlg(n)
    frac_knapsack();
    //0-1 背包 最大值155 ---1 1 1 1 0
    // cout<<zero_one_knapsack()<<endl;
    return 0;
}

调度问题

//第2题 一个简单的调度问题 贪心算法
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    vector<int> jobs;
    int N;
    cout<<"please input the number of jobs:"<<endl;
    cin>>N;
    cout<<"please input time of jobs: "<<endl;
    for(int i,j=0;j<N;j++)
    {
        cin>>i;
        jobs.push_back(i);
    }
    sort(jobs.begin(),jobs.end());
    int consume=0;
    int sum=0;
    int n=jobs.size();
    for(int i=0;i<n;i++)
    {
        consume+=jobs[i];
        sum+=consume;
    }
    float average;
    average=float(sum)/float(n);
    cout<<average<<endl;
    return 0;
}
// 3 11 21 36 17.75

单源节点

//第三题 single-source 最短路径
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int n=5;//the number of vertex
// const int E = 8;//the number of edge
const int s = 0;//source
int matrix[n][n];
struct VEX{
    int d;
    int pi;
};
VEX vex[n]; 
//初始化邻接矩阵,from to edge
void init()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            matrix[i][j]=INT_MAX;
        }
    }
    for(int i=0;i<n;i++)
    {
        matrix[i][i]=0;
    }
    matrix[0][1]=-1;matrix[0][2]=3;
    matrix[1][2]=3;matrix[1][3]=2;matrix[1][4]=2;
    matrix[3][1]=1;matrix[3][2]=5;
    matrix[4][3]=-3;
}
void print()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            cout<<matrix[i][j]<<" ";
        }
        cout<<endl;
    }
}
//对最短路径估计与前驱结点进行初始化
void init_single_source(int s)
{
    for(int i=0;i<n;i++)
    {
        vex[i].d=INT_MAX;
    }
    vex[s].d=0;
}
//松弛操作
void relax(int u,int v,int w )
{
    if(vex[v].d>(vex[u].d+w))
    {
        vex[v].d=vex[u].d+w;
        vex[v].pi=u;
    }
}
bool Bellman_ford(int s)
{
    init_single_source(s);
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            for(int k=0;k<n;k++)
            {
                if(matrix[j][k]!=INT_MAX)
                {
                    relax(j,k,matrix[j][k]);
                }
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(matrix[i][j]!=INT_MAX)
            {
                if(vex[j].d>(vex[i].d+matrix[i][j])) return false;
            }
        }
    }
    return true;
}
void out(int target)
{
    if(target>0)
    {
        target=vex[target].pi;//前驱
        out(target);
        cout<<target<<"->";
    }
}
int main()
{
    init();//初始化邻接矩阵
    // print();
    int target;
    cout<<"please input the vertex you wana to get:"<<endl;
    cin>>target;
    /* cout<<"input the source:"<<endl;
    cin>>s; */
    if(Bellman_ford(s))
    {
        cout<<"最短路径:"<<endl;
        out(target);//输出最短路径经过的结点
        cout<<target<<endl;
        cout<<"最短路径权重值之和"<<endl;
        cout<<vex[target].d<<endl;//输出最短路径权重值之和
    }
    return 0;
}

多源点路径

//第四题 多元点路径
#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
const int n=5;//the number of vertex
int matrix[n][n];
int P[n][n];
int D[n][n];
// #define INT_MAX 9999
//初始化邻接矩阵,from to edge
void init()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            matrix[i][j]=INT_MAX;
        }
    }
    for(int i=0;i<n;i++)
    {
        matrix[i][i]=0;
    }
    matrix[0][1]=-1;matrix[0][2]=3;
    matrix[1][2]=3;matrix[1][3]=2;matrix[1][4]=2;
    matrix[3][1]=1;matrix[3][2]=5;
    matrix[4][3]=-3;
}
void print(int m[n][n])
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            cout<<m[i][j]<<" ";
        }
        cout<<endl;
    }
}


void floyd_warshall()
{
    //int D[n][n];//路径代价矩阵
    //int P[n][n];//前驱矩阵
    //初始化D
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            D[i][j]=matrix[i][j];
        }
    }
    /* print(matrix);
    cout<<endl;
    print(D);
    cout<<endl; */
    //初始化P
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(matrix[i][j]!=0&&matrix[i][j]!=INT_MAX)
            {
                P[i][j]=i;
            }
            else{
                P[i][j]=INT_MAX;
            }
        }
    }
    // print(P);
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(D[i-1][j-1]>(D[i-1][k-1]+D[k-1][j-1])&&D[i-1][k-1]!=INT_MAX&&D[k-1][j-1]!=INT_MAX) 
                {
                    P[i-1][j-1]=P[k-1][j-1];//前驱
                    D[i-1][j-1]=D[i-1][k-1]+D[k-1][j-1];
                }
                //D[i-1][j-1]=min(D[i-1][j-1],D[i-1][k-1]+D[k-1][j-1]);
            }
        }
    }
    print(D);
}
void out(int s,int e)
{
    /* cout<<P[s][e];
    cout<<endl; */
    if(P[s][e]!=s)
    {
        out(s,P[s][e]);
        cout<<P[s][e]<<"->";
    }

}
int main()
{
    int start,end;
    init();
    //int D[n][n];
    floyd_warshall();
    cout<<"please input start and end pots:"<<endl;
    cin>>start>>end;
    if(D[start][end]!=INT_MAX||D[start][end]!=0)
    {
        cout<<"最短路径代价:";
        cout<<D[start][end]<<endl;
        cout<<"最短路径:";
        cout<<start<<"->";
        out(start,end);
        cout<<end<<endl;
    }
    else{
        cout<<"不存在最短路径"<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值