博弈论--背包拍卖

1.问题描述

在博弈论中,存在一种背包拍卖,每一个竞拍者i都有一个公开的规模(size) wi 和一个私有的估值vi。设卖家有总容量W。可行集合X是一个0-1向量(x1,x2,…,xn),且Σwixi<=W(i∈N) 。(xi=1 表示i是赢家) 设计一个诚实的拍卖机制,计算其社会福利。
转化为算法中的背包问题即:0-1完全背包问题。一个背包总容量为W,现在有N个物品,第i个 物品体积为weight[i],价值为value[i],现在往背包里面装东西,怎么装能使背包的内物品价值最大。
卖家的总容量C对应0-1完全背包问题中的能放入的总容量。
竞拍者i对应物品i;竞拍者i拥有的公开wi和私有估值vi对应物品i的体积weight[i]和价值value[i]。背包拍卖中的社会福利对应0-1完全背包问题中的价值最大。

拍卖机制设计:
步骤1:按照正常的贪婪法求解,得到一个解,设其价值为Vr;
步骤2:挑选价值最大的物品装入背包,设其价值为Vs;
步骤3:选择Vr、Vs两者最大的作为算法的输出。
上述算法主要的计算时间在于对n个物品排序,排序的复杂度为o(nlogn)

2.代码实现

根据0-1背包贪心算法改编,背包拍卖的近似算法:

//贪心算法的改编 
#include<bits/stdc++.h>
#include<string.h>
#define N 100
using namespace std;
struct thing{
	int item;
	float w;//weight
	float v;//value
}things;
bool cmp(thing a,thing b)
{
	return ((a.v/a.w)>(b.v/b.w));
}
int g,n;
int x[N];
int main(){
	float sum=0;
	float weight=0;
	float Max_value=0;
	int Max_value_item;
	//cin>>g>>n;
	FILE* fpread;
	fpread = fopen("./shuju/1.txt", "r");
	int b[1000];//用于存入读入的字符 
	int c[1000];//用于统计字符数 
	int count_sum = 0;
	if (fpread == NULL)
	{
		printf("file is error.");
		return -1;
	}
    
    while(fscanf(fpread, "%s", c) == 1)
    {
        count_sum++;
    }
    fclose(fpread);
    printf("count_sum = %d\n", count_sum);

    fpread = fopen("./shuju/1.txt", "r");
    for (int j = 0; j < count_sum; j++)
		{
			fscanf(fpread, "%d", &b[j]);
		}
	fclose(fpread);

	for (int j = 0; j < count_sum; j++)
		{
			printf("%d ",b[j]);
		}
	printf("\n");
	//printf("背包容量C:");
	//printf("物品种类n:");
    g=b[0];
    printf("背包容量C:%d\n",g);
    n=b[1];
	printf("物品数量n:%d\n",n);
    thing things[n];
//	for(int i=0;i<n;i++){
//		cin>>things[i].w>>things[i].v;
//		
//	}
    for(int i = 2,j=0; i < (count_sum-1)&&j<n;i=i+2,j++){
    	things[j].item=j;
        things[j].w=b[i];
        printf("第%d个物品重量%f ",j,things[j].w);
        things[j].v=b[i+1];
        printf("第%d个物品价值%f ",j,things[j].v);
        if(Max_value<=things[j].v&&things[j].w<=g){
            Max_value=things[j].v;
            Max_value_item=things[j].item;
			}
    }
    printf("\n----在满足容量条件下报价最高的物品%d与其报价%f\n",Max_value_item,Max_value);
	sort(things,things+n,cmp);
	for(int i =0;i<n;i++){
		printf("第%d个物品单位价值%f\n",things[i].item,things[i].v/things[i].w);
	}
	
	for(int i=0;i<n;i++){
		weight=weight+things[i].w;
		if(weight<=g){
			sum=sum+things[i].v;
			x[things[i].item]=1;
		}
		else{
			x[things[i].item]=0;
			//sum=sum+(g+things[i].w-weight)*(things[i].v/things[i].w);
			//break;
		}	
	}
	
    if(Max_value<=sum){
	    printf("近似算法求解0/1背包问题:\nX=[");
	    for(int i = 0; i < n; i++)
        cout<<x[i]<<" ";//输出所求X[n]矩阵
        printf("]");
        printf("\n装入的总价值:%f ",sum);
		}
//	else if(Max_value=sum){
//		printf("\n装入的总价值与报价最高的物品报价相等,物品%d,报价为%f,装入总价值%f",Max_value_item,Max_value,sum);
//	}
	else
	    printf("\n在满足容量条件下装入的总价值为报价最高的物品%d,报价为%f ",Max_value_item,Max_value);
	    
	return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chrisyyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值