【算法】拍卖算法(最优分配问题)--启发式算法_wuxiaoxiao2021的博客-CSDN博客
竞拍算法(Auction Algorithm)原理及工作过程分析_拍卖算法_一方灯火的博客-CSDN博客
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #define NLINKS 65536
- using namespace std;
- void CreatRandomEdge(char* filePath, int n1, int n2);
-
- typedef struct {
- unsigned u;//first node
- unsigned v;//second node
- unsigned w;//weight of the edge
- } edge;
-
- typedef struct {
-
- //edge list
- unsigned n1;//number of nodes
- unsigned n2;//number of nodes
- unsigned e;//number of edges
- edge *edges;//list of edges
-
- bool b;//b=1 iff n1>n2
- //graph
- unsigned *cd;//cumulative degree: (start with 0) length=dim+1
- unsigned *adj;//list of neighbors
- unsigned *w;//weight of the edges
-
- } bipgraph;
-
- void freebg(bipgraph *g) {
- free(g->edges);
- free(g->cd);
- free(g->adj);
- free(g->w);
- free(g);
- }
-
- //compute the maximum of two unsigned
- inline unsigned max2u(unsigned a, unsigned b) {
- return (a > b) ? a : b;
- }
-
- //reading the edgelist of bipartit weighted graph from file
- //从文件中读取二维加权图的边表
- bipgraph* readedgelist(char* edgelist) {
- unsigned e1 = NLINKS;
- bipgraph *g = (bipgraph*)malloc(sizeof(bipgraph));
- FILE *file;
- g->n1 = 0;
- g->n2 = 0;
- g->e = 0;
-
- file = fopen(edgelist, "r");
- g->edges = (edge*)malloc(e1 * sizeof(edge));
- //e1 += NLINKS;
- //g->edges = (edge*)realloc(g->edges, e1 * sizeof(edge));
- while (fscanf(file, "%u %u %u\n", &(g->edges[g->e].u), &(g->edges[g->e].v), &(g->edges[g->e].w)) == 3) {
- g->n1 = max2u(g->n1, g->edges[g->e].u);
- g->n2 = max2u(g->n2, g->edges[g->e].v);
- if (g->e++ == e1) {
- e1 += NLINKS;
- g->edges = (edge*)realloc(g->edges, e1 * sizeof(edge));
- }
- }
- fclose(file);
- g->n1++;
- g->n2++;
- g->edges = (edge*)realloc(g->edges, g->e * sizeof(edge));
- return g;
- }
-
- //Building a special sparse graph structure
- //构建一个特殊的稀疏图结构
- void mkbg(bipgraph *g)
- {
- unsigned int i, u;
- unsigned int *d;
-
- if (g->n1 <= g->n2)
- {
- g->b = 0;
- d = (unsigned int*)calloc(g->n1, sizeof(unsigned));
- g->cd = (unsigned int*)malloc((g->n1 + 1) * sizeof(unsigned));
- g->adj = (unsigned int*)malloc((g->e) * sizeof(unsigned));
- g->w = (unsigned int*)malloc((g->e) * sizeof(unsigned));
- for (i = 0; i < g->e; i++) {
- d[g->edges[i].u]++;
- }
- g->cd[0] = 0;
- for (i = 1; i < g->n1 + 1; i++) {
- g->cd[i] = g->cd[i - 1] + d[i - 1];
- d[i - 1] = 0;
- }
- for (i = 0; i < g->e; i++) {
- u = g->edges[i].u;
- g->adj[g->cd[u] + d[u]] = g->edges[i].v;
- g->w[g->cd[u] + d[u]++] = g->edges[i].w;
- }
- }
- else
- {
- g->b = 1;
- d = (unsigned int*)calloc(g->n2, sizeof(unsigned));
- g->cd = (unsigned int*)malloc((g->n2 + 1) * sizeof(unsigned));
- g->adj = (unsigned int*)malloc((g->e) * sizeof(unsigned));
- g->w = (unsigned int*)malloc((g->e) * sizeof(unsigned));
-
- //计算n2中每个节点有多少边
- for (i = 0; i < g->e; i++) {
- d[g->edges[i].v]++;
- }
- g->cd[0] = 0;
- for (i = 1; i < g->n2 + 1; i++) {
- g->cd[i] = g->cd[i - 1] + d[i - 1];
- d[i - 1] = 0;
- }
- for (i = 0; i < g->e; i++) {
- u = g->edges[i].v;
- g->adj[g->cd[u] + d[u]] = g->edges[i].u;
- g->w[g->cd[u] + d[u]++] = g->edges[i].w;
- }
- i = g->n1;
- g->n1 = g->n2;
- g->n2 = i;
- }
- free(d);
- free(g->edges);
- }
-
- //bidding towards convergence
- unsigned bidding(bipgraph *g, double eps)
- {
- unsigned u, v, w, i, j, k, res;
- double *p = (double*)calloc(g->n2, sizeof(double));//p[i]=price of object i
- unsigned *a = (unsigned int*)malloc(g->n2 * sizeof(unsigned));//a[target]=-1 if not assigned = source if assigned
- unsigned *aw = (unsigned int*)malloc(g->n2 * sizeof(unsigned));//aw[target]=? if not assigned = weigth of edge source-target if assigned
- for (v = 0; v < g->n2; v++) {
- a[v] = -1;
- }
- //set data structure
- unsigned n_set = g->n1;//
- unsigned *l_set = (unsigned int*)malloc(g->n1 * sizeof(unsigned));//
- //bool *t_set=malloc(g->n1*sizeof(bool));//
- for (u = 0; u < n_set; u++) {
- l_set[u] = u;
- //t_set[u]=1;
- }
-
- //double eps=0.1;//1./((double)(g->n1)+1.);///
- double max, max2;
- unsigned wmax;
-
- res = 0;
- while (n_set > 0)
- {
- u = l_set[n_set - 1];
- //printf("n_set, u, w = %u, %u, %u\n",n_set,u,res);
-
- //找权重最大的一个u(火力点)
- max = 0;
- for (i = g->cd[u]; i < g->cd[u + 1]; i++) {
- v = g->adj[i];
- w = g->w[i];
- //printf("w=%u\n",w);
- if ((double)w - p[v] > max) {
- max = (double)w - p[v];
- wmax = w;
- k = v;
- }
- }
- //printf("max=%f\n",max);
- if (max == 0) {
- n_set--;
- continue;
- }
-
- //找次大的一个u(火力点)
- max2 = 0;
- for (i = g->cd[u]; i < g->cd[u + 1]; i++) {
- v = g->adj[i];
- if (v != k) {
- w = g->w[i];
- if ((double)w - p[v] > max2) {
- max2 = (double)w - p[v];
- }
- }
- }
-
- //printf("max2=%f\n",max2);
- p[k] += max - max2 + eps;
- //printf("k=%u\n",k);
- //printf("p[k]=%f\n",p[k]);
- if (a[k] != -1) {
- l_set[n_set - 1] = a[k];
- res -= aw[k];
- }
- else {
- n_set--;
- }
- a[k] = u;
- aw[k] = wmax;
- res += wmax;
- }
-
- g->edges = (edge*)malloc(g->n1 * sizeof(edge));
- j = 0;
- for (i = 0; i < g->n2; i++) {
- if (a[i] != -1) {
- g->edges[j].u = a[i];
- g->edges[j].v = i;
- g->edges[j++].w = aw[i];
- }
- }
- g->edges = (edge*)realloc(g->edges, j * sizeof(edge));
- g->e = j;
- return res;
- }
-
- void printres(bipgraph *g, char *output) {
- unsigned i;
- edge ed;
- FILE* file = fopen(output, "w");
- if (g->b) {
- for (i = 0; i < g->e; i++) {
- ed = g->edges[i];
- fprintf(file, "%u %u %u\n", ed.v, ed.u, ed.w);
- }
- }
- else {
- for (i = 0; i < g->e; i++) {
- ed = g->edges[i];
- fprintf(file, "%u %u %u\n", ed.u, ed.v, ed.w);//输出:人序号 任务序号 代价
- }
- }
- fclose(file);
- }
-
-
- int main(void)
- {
- bipgraph* g;
- unsigned w;
- time_t t0, t1, t2;
-
- char* argv[4];
-
- argv[1] = "testEdgesList.txt";
- argv[2] = "testRes.txt";
-
- //随机生成n x n个矩阵对,保存在testEdgesList.txt中
- CreatRandomEdge("testEdgesList.txt", 60, 60);//6 6
-
-
- double eps = 0.01;
-
- printf("Reading edgelist from file %s\n", argv[1]);
- //将矩阵读入矩阵图结构g中
- g = readedgelist(argv[1]);
-
- printf("Number of left nodes: %u\n", g->n1);
- printf("Number of right nodes: %u\n", g->n2);
- printf("Number of edges: %u\n", g->e);
-
- printf("Building datastructure\n");
-
- mkbg(g);
-
-
- printf("计算最优分配\n");
-
- //投标
- w = bidding(g, eps);
-
- printf("最优分配值 = %u\n", w);
-
- printf("Writting the results in file %s\n", argv[2]);
- printres(g, argv[2]);
- freebg(g);
-
- return 0;
- }
-
- void CreatRandomEdge(char* filePath, int n1, int n2)
- {
- ofstream fout;
- fout.open(filePath);
- int edgesNum = n1 * n2;//36
-
- int pI = n1 - 1;//人索引
- for (int i = 0; i < n1; i++)
- {
- for (int j = 0; j < n2; j++)//物品索引
- {
- fout << pI << " " << j << " " << (rand() % edgesNum) << "\n"; //随机生成0~35的随机数
- }
- pI--;
- }
- fout.close();
- }
-

