mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	rogueviz::sag:: modernized, also made the animation possible again
This commit is contained in:
		
							
								
								
									
										409
									
								
								rogueviz/sag.cpp
									
									
									
									
									
								
							
							
						
						
									
										409
									
								
								rogueviz/sag.cpp
									
									
									
									
									
								
							| @@ -22,98 +22,82 @@ namespace sag { | |||||||
|   const char *sagmodes[3] = {"off", "HC", "SA"}; |   const char *sagmodes[3] = {"off", "HC", "SA"}; | ||||||
|    |    | ||||||
|   ld temperature = -4; |   ld temperature = -4; | ||||||
|   const int INSNAKE = 117; |  | ||||||
|   int numsnake; |  | ||||||
|   const char *loadfname; |   const char *loadfname; | ||||||
|    |    | ||||||
|   #define MAXSNAKETAB 1000 |   int vizsa_start; | ||||||
|   int sdist[MAXSNAKETAB][MAXSNAKETAB]; |   int vizsa_len; | ||||||
|   int insnaketab = 0; |  | ||||||
|    |    | ||||||
|   vector<cell*> snakecells; |   /** all the SAG cells */ | ||||||
|   vector<int> snakefirst, snakelast; |   vector<cell*> sagcells; | ||||||
|   vector<int> snakenode; |  | ||||||
|   vector<int> snakeid; |  | ||||||
|   vector<int> lpbak; |  | ||||||
|   vector<int> wpbak; |  | ||||||
|  |  | ||||||
|   bool snake_enabled; |   /** table of distances between SAG cells */ | ||||||
|  |   vector<vector<int>> sagdist; | ||||||
|  |  | ||||||
|   void setsnake(cellwalker& cw, int i) { |   /** what node is on sagcells[i] */ | ||||||
|     lpbak[i] = cw.at->landparam; |   vector<int> sagnode; | ||||||
|     wpbak[i] = cw.at->wparam; |  | ||||||
|     cw.at->landparam = i; cw.at->wparam = INSNAKE; |  | ||||||
|     // cw.at->monst = moWormtail; cw.at->mondir = cw.spin; |  | ||||||
|     snakecells[i] = cw.at; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   void snakeswitch() {  |   /** node i is on sagcells[sagid[i]] */ | ||||||
|     for(int i=0; i<numsnake; i++) { |   vector<int> sagid; | ||||||
|       cell *c = snakecells[i]; |  | ||||||
|       int x; |  | ||||||
|       x = lpbak[i]; lpbak[i] = c->landparam; c->landparam = x; |  | ||||||
|       x = wpbak[i]; wpbak[i] = c->wparam; c->wparam = x; |  | ||||||
|       } |  | ||||||
|     snake_enabled = !snake_enabled; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   void enable_snake() { if(!snake_enabled) snakeswitch(); } |   /** sagcells[ids[c]]] == c */ | ||||||
|  |   map<cell*, int> ids; | ||||||
|  |  | ||||||
|   void disable_snake() { if(snake_enabled) snakeswitch(); } |   /** if i in neighbors[j], sagcells[i] is a neighbor of sagcells[j] */ | ||||||
|  |   vector<vector<int>> neighbors; | ||||||
|    |    | ||||||
|   int snakedist(int i, int j) { |   void compute_dists() { | ||||||
|     if(i < insnaketab && j < insnaketab) return sdist[i][j]; |     int N = isize(sagcells); | ||||||
|     if(closed_manifold) return celldistance(snakecells[i], snakecells[j]); |  | ||||||
|     int i0 = i, i1 = i, j0 = j, j1 = j; |     neighbors.clear(); | ||||||
|     int cost = 0; |     neighbors.resize(N); | ||||||
|     // intersect |  | ||||||
|     while(true) { |     for(int i=0; i<N; i++) | ||||||
|       if(j0 > i1+1) { j0 = snakefirst[j0], j1 = snakelast[j1]; cost++; } |       for(cell *c1: adj_minefield_cells(sagcells[i])) | ||||||
|       else if(i0 > j1+1) { i0 = snakefirst[i0], i1 = snakelast[i1]; cost++; } |         if(ids.count(c1)) neighbors[i].push_back(ids[c1]); | ||||||
|       else if(j1+1 == i0) return cost+1; |  | ||||||
|       else if(i1+1 == j0) return cost+1; |     sagdist.clear(); | ||||||
|       else return cost; |     sagdist.resize(N); | ||||||
|  |     for(int i=0; i<N; i++) { | ||||||
|  |       auto &sdi = sagdist[i]; | ||||||
|  |       sdi.resize(N, N); | ||||||
|  |       vector<int> q; | ||||||
|  |       auto visit = [&] (int j, int dist) { if(sdi[j] < N) return; sdi[j] = dist; q.push_back(j); }; | ||||||
|  |       visit(i, 0); | ||||||
|  |       for(int j=0; j<isize(q); j++) for(int k: neighbors[q[j]]) visit(k, sdi[q[j]]+1); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   void initSnake(int n) { |   bool legacy; | ||||||
|     if(closed_or_bounded) n = isize(currentmap->allcells()); |  | ||||||
|     numsnake = n; |   /* legacy method */ | ||||||
|     snakecells.resize(numsnake); |   void init_snake(int n) { | ||||||
|     snakefirst.resize(numsnake); |     sagcells.clear(); | ||||||
|     snakelast.resize(numsnake); |     ids.clear(); | ||||||
|     snakenode.resize(numsnake); |  | ||||||
|     lpbak.resize(numsnake); |     auto enlist = [&] (cellwalker cw) { | ||||||
|     wpbak.resize(numsnake); |       ids[cw.at] = isize(sagcells); | ||||||
|     if(closed_or_bounded) { |       sagcells.push_back(cw.at); | ||||||
|       for(int i=0; i<n; i++) { |       }; | ||||||
|         cellwalker cw(currentmap->allcells()[i], 0); |  | ||||||
|         setsnake(cw, i); |     cellwalker cw = cwt; | ||||||
|         } |     enlist(cw); | ||||||
|       } |     cw += wstep; | ||||||
|     else { |     enlist(cw); | ||||||
|       cellwalker cw = cwt; |     for(int i=2; i<n; i++) { | ||||||
|       setsnake(cw, 0); |  | ||||||
|       cw += wstep; |       cw += wstep; | ||||||
|       setsnake(cw, 1); |       while(ids.count(cw.at)) { | ||||||
|       for(int i=2; i<=numsnake; i++) { |         cw = cw + wstep + 1 + wstep; | ||||||
|         if(i == numsnake && sphere) break; |  | ||||||
|         cw += wstep; |  | ||||||
|         snakefirst[i-1] = cw.at->landparam; |  | ||||||
|         while(cw.at->wparam == INSNAKE) { |  | ||||||
|           snakelast[i-1] = cw.at->landparam; |  | ||||||
|           cw = cw + wstep + 1 + wstep; |  | ||||||
|           } |  | ||||||
|         if(i == numsnake) break; |  | ||||||
|         setsnake(cw, i); cw += 1; |  | ||||||
|         } |         } | ||||||
|  |       enlist(cw); cw += 1; | ||||||
|       } |       } | ||||||
|     int stab = min(numsnake, MAXSNAKETAB); |     } | ||||||
|     for(int i=0; i<stab; i++) |  | ||||||
|     for(int j=0; j<stab; j++) |   void init_sag_cells() { | ||||||
|       sdist[i][j] = snakedist(i,j); |     sagcells = currentmap->allcells(); | ||||||
|     insnaketab = stab; |     int N = isize(sagcells); | ||||||
|     snake_enabled = true; |  | ||||||
|  |     ids.clear(); | ||||||
|  |     for(int i=0; i<N; i++) ids[sagcells[i]] = i; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   ld hub_penalty; |   ld hub_penalty; | ||||||
| @@ -127,27 +111,17 @@ namespace sag { | |||||||
|     for(int j=0; j<isize(vd.edges); j++) { |     for(int j=0; j<isize(vd.edges); j++) { | ||||||
|       edgeinfo *ei = vd.edges[j].second; |       edgeinfo *ei = vd.edges[j].second; | ||||||
|       int t2 = vd.edges[j].first; |       int t2 = vd.edges[j].first; | ||||||
|       if(snakeid[t2] != -1) cost += snakedist(sid, snakeid[t2]) * ei->weight2; |       if(sagid[t2] != -1) cost += sagdist[sid][sagid[t2]] * ei->weight2; | ||||||
|       } |       } | ||||||
|      |      | ||||||
|     if(!hubval.empty()) { |     if(!hubval.empty()) { | ||||||
|       cell *c = snakecells[sid]; |       for(auto sid2: neighbors[sid]) { | ||||||
|       for(int i=0; i<c->type; i++) { |         int vid2 = sagnode[sid2]; | ||||||
|         cell *c2 = c->move(i); |         if(vid2 >= 0 && (hubval[vid] & hubval[vid]) == 0) | ||||||
|         if(c2 && c2->wparam == INSNAKE) { |           cost += hub_penalty; | ||||||
|           int vid2 = snakenode[c2->landparam]; |  | ||||||
|           if(vid2 >= 0 && (hubval[vid] & hubval[snakenode[c2->landparam]]) == 0) |  | ||||||
|             cost += hub_penalty; |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|      |      | ||||||
|     /* cell *c = snakecells[id]; |  | ||||||
|     for(int i=0; i<c->type; i++) { |  | ||||||
|       cell *c2 = c->move(i); |  | ||||||
|       if(c2 && c2->wparam == INSNAKE && snakenode[c2->landparam] >= 0) |  | ||||||
|         cost += 100; |  | ||||||
|       } */ |  | ||||||
|     return cost; |     return cost; | ||||||
|     } |     } | ||||||
|    |    | ||||||
| @@ -156,7 +130,6 @@ namespace sag { | |||||||
|   bool infullsa; |   bool infullsa; | ||||||
|    |    | ||||||
|   double cost; |   double cost; | ||||||
|   int N; |  | ||||||
|  |  | ||||||
|   vector<double> chgs;   |   vector<double> chgs;   | ||||||
|    |    | ||||||
| @@ -177,91 +150,62 @@ namespace sag { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   void saiter() { |   void saiter() { | ||||||
|     aiter: |     int DN = isize(sagid); | ||||||
|  |     int t1 = hrand(DN); | ||||||
|     int t1 = hrand(N); |     int sid1 = sagid[t1]; | ||||||
|     int sid1 = snakeid[t1]; |  | ||||||
|      |      | ||||||
|     int sid2; |     int sid2; | ||||||
|      |      | ||||||
|     int s = hrand(6); |     int s = hrand(4)+1; | ||||||
|      |  | ||||||
|     if(s == 3) s = 2; |  | ||||||
|     if(s == 4) s = 5; |  | ||||||
|      |  | ||||||
|     if((sagpar&1) && (s == 2 || s == 3 || s == 4)) return; |  | ||||||
|      |  | ||||||
|     if(s == 5) sid2 = hrand(numsnake); |  | ||||||
|      |      | ||||||
|  |     if(s == 4) sid2 = hrand(isize(sagcells)); | ||||||
|     else { |     else { | ||||||
|       cell *c; |       sid2 = sid1; | ||||||
|       if(s>=2 && isize(vdata[t1].edges)) c = snakecells[snakeid[hrand(isize(vdata[t1].edges))]]; |       for(int ii=0; ii<s; ii++) sid2 = hrand_elt(neighbors[sid2]); | ||||||
|       else c = snakecells[sid1]; |  | ||||||
|        |  | ||||||
|       int it = s<2 ? (s+1) : s-2; |  | ||||||
|       for(int ii=0; ii<it; ii++) { |  | ||||||
|         int d = hrand(c->type); |  | ||||||
|         c = c->move(d); |  | ||||||
|         if(!c) goto aiter; |  | ||||||
|         if(c->wparam != INSNAKE) goto aiter; |  | ||||||
|         } |  | ||||||
|       sid2 = c->landparam; |  | ||||||
|       } |       } | ||||||
|     int t2 = snakenode[sid2]; |     int t2 = sagnode[sid2]; | ||||||
|      |      | ||||||
|     snakenode[sid1] = -1; snakeid[t1] = -1; |     sagnode[sid1] = -1; sagid[t1] = -1; | ||||||
|     snakenode[sid2] = -1; if(t2 >= 0) snakeid[t2] = -1; |     sagnode[sid2] = -1; if(t2 >= 0) sagid[t2] = -1; | ||||||
|      |      | ||||||
|     double change =  |     double change =  | ||||||
|       costat(t1,sid2) + costat(t2,sid1) - costat(t1,sid1) - costat(t2,sid2); |       costat(t1,sid2) + costat(t2,sid1) - costat(t1,sid1) - costat(t2,sid2); | ||||||
|      |      | ||||||
|     snakenode[sid1] = t1; snakeid[t1] = sid1; |     sagnode[sid1] = t1; sagid[t1] = sid1; | ||||||
|     snakenode[sid2] = t2; if(t2 >= 0) snakeid[t2] = sid2; |     sagnode[sid2] = t2; if(t2 >= 0) sagid[t2] = sid2; | ||||||
|      |  | ||||||
|     if(change < 0) chgs.push_back(-change); |  | ||||||
|      |      | ||||||
|     if(change > 0 && (sagmode == sagHC || !chance(exp(-change * exp(-temperature))))) return; |     if(change > 0 && (sagmode == sagHC || !chance(exp(-change * exp(-temperature))))) return; | ||||||
|  |  | ||||||
|     snakenode[sid1] = t2; snakenode[sid2] = t1; |     sagnode[sid1] = t2; sagnode[sid2] = t1; | ||||||
|     snakeid[t1] = sid2; if(t2 >= 0) snakeid[t2] = sid1; |     sagid[t1] = sid2; if(t2 >= 0) sagid[t2] = sid1; | ||||||
|     if(vdata[t1].m) vdata[t1].m->base = snakecells[sid2]; |  | ||||||
|     if(t2 >= 0 && vdata[t2].m) vdata[t2].m->base = snakecells[sid1]; |  | ||||||
|     cost += 2*change; |     cost += 2*change; | ||||||
|      |  | ||||||
|     if(t1 >= 0) forgetedges(t1); |  | ||||||
|     if(t2 >= 0) forgetedges(t2); |  | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   void organize() { |   void create_sagnode() { | ||||||
|     for(int i=0; i<numsnake; i++) snakenode[i] = -1; |     sagnode.clear(); | ||||||
|     vector<int> freenodes; |     sagnode.resize(isize(sagcells), -1); | ||||||
|     for(int i=0; i<N; i++)  |     int DN = isize(sagid); | ||||||
|       if(snakeid[i] != -1) |     for(int i=0; i<DN; i++) | ||||||
|         snakenode[snakeid[i]] = i; |       sagnode[sagid[i]] = i; | ||||||
|  |     cost = 0; | ||||||
|     for(int i=0; i<N; i++)  |     for(int i=0; i<DN; i++) | ||||||
|       if(snakeid[i] != -1) |       cost += costat(i, sagid[i]); | ||||||
|         if(snakenode[snakeid[i]] != i) |  | ||||||
|           snakeid[i] = -1; |  | ||||||
|  |  | ||||||
|     for(int i=0; i<numsnake; i++)  |  | ||||||
|       if(snakenode[i] == -1) |  | ||||||
|         freenodes.push_back(i); |  | ||||||
|      |  | ||||||
|     int j = 0; |  | ||||||
|     for(int i=0; i<N; i++)  |  | ||||||
|       if(snakeid[i] == -1) { |  | ||||||
|         snakeid[i] = freenodes[j]; |  | ||||||
|         snakenode[freenodes[j]] = i; |  | ||||||
|         j++; |  | ||||||
|         } |  | ||||||
|     cost = 0; for(int i=0; i<N; i++) cost += costat(i, i); |  | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   void loadsnake(const string& fname) { |   void reassign() { | ||||||
|  |     int DN = isize(sagid); | ||||||
|  |     for(int i=0; i<DN; i++) { | ||||||
|  |       vdata[i].m->base = sagcells[sag::sagid[i]]; | ||||||
|  |       forgetedges(i); | ||||||
|  |       } | ||||||
|  |     shmup::fixStorage(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   void load_sag_solution(const string& fname) { | ||||||
|     printf("Loading the sag from: %s\n", fname.c_str()); |     printf("Loading the sag from: %s\n", fname.c_str()); | ||||||
|     FILE *sf = fopen(fname.c_str(), "rt"); |     FILE *sf = fopen(fname.c_str(), "rt"); | ||||||
|     if(!sf) { printf("Failed to open file.\n"); exit(1); } |     if(!sf) { printf("Failed to open file.\n"); exit(1); } | ||||||
|  |     int SN = isize(sagcells); | ||||||
|     if(sf) while(true) { |     if(sf) while(true) { | ||||||
|       string lab; |       string lab; | ||||||
|       while(true) { |       while(true) { | ||||||
| @@ -273,33 +217,24 @@ namespace sag { | |||||||
|         } |         } | ||||||
|       int sid = -1; |       int sid = -1; | ||||||
|       int err = fscanf(sf, "%d", &sid); |       int err = fscanf(sf, "%d", &sid); | ||||||
|       if(sid < 0 || sid >= numsnake || err < 1) sid = -1; |       if(sid < 0 || sid >= SN || err < 1) sid = -1; | ||||||
|       if(!labeler.count(lab)) { |       if(!labeler.count(lab)) { | ||||||
|         printf("unknown vertex: %s\n", lab.c_str()); |         printf("unknown vertex: %s\n", lab.c_str()); | ||||||
|         } |         } | ||||||
|       else { |       else { | ||||||
|         int id = getid(lab); |         int id = getid(lab); | ||||||
|         snakeid[id] = sid; |         sagid[id] = sid; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     afterload:  |     afterload:  | ||||||
|     if(sf) fclose(sf); |     if(sf) fclose(sf); | ||||||
|  |  | ||||||
|     organize(); |     create_sagnode(); | ||||||
|     for(int i=0; i<N; i++) { |     reassign(); | ||||||
|       if(vdata[i].m) vdata[i].m->base = snakecells[sag::snakeid[i]]; |  | ||||||
|       forgetedges(i); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|     shmup::fixStorage(); |  | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   vector<edgeinfo> sagedges; |   vector<edgeinfo> sagedges; | ||||||
|    |    | ||||||
|   /* bool totcmp(int i, int j) { |  | ||||||
|     return totwei[i] > totwei[j]; |  | ||||||
|     } */ |  | ||||||
|    |  | ||||||
|   int ipturn = 100; |   int ipturn = 100; | ||||||
|   int numiter = 0; |   int numiter = 0; | ||||||
|    |    | ||||||
| @@ -308,7 +243,6 @@ namespace sag { | |||||||
|    |    | ||||||
|   void dofullsa(int satime) { |   void dofullsa(int satime) { | ||||||
|     sagmode = sagSA; |     sagmode = sagSA; | ||||||
|     enable_snake(); |  | ||||||
|     int t1 = SDL_GetTicks(); |     int t1 = SDL_GetTicks(); | ||||||
|      |      | ||||||
|     while(true) { |     while(true) { | ||||||
| @@ -321,48 +255,48 @@ namespace sag { | |||||||
|         numiter++; |         numiter++; | ||||||
|         sag::saiter(); |         sag::saiter(); | ||||||
|         } |         } | ||||||
|       DEBB(DF_LOG, (format("it %8d temp %6.4f [1/e at %13.6f] cost = %f ",  |        | ||||||
|  |       print(hlog, format("it %8d temp %6.4f [1/e at %13.6f] cost = %f ",  | ||||||
|         numiter, double(sag::temperature), (double) exp(sag::temperature), |         numiter, double(sag::temperature), (double) exp(sag::temperature), | ||||||
|         double(sag::cost)))); |         double(sag::cost))); | ||||||
|        |        | ||||||
|       sort(chgs.begin(), chgs.end()); |       sort(chgs.begin(), chgs.end()); | ||||||
|       int cc = chgs.size() - 1; |       int cc = chgs.size() - 1; | ||||||
|       DEBB(DF_LOG, (format("%9.4f .. %9.4f .. %9.4f .. %9.4f .. %9.4f\n",  |       println(hlog, format("%9.4f .. %9.4f .. %9.4f .. %9.4f .. %9.4f",  | ||||||
|         double(chgs[0]), double(chgs[cc/4]), double(chgs[cc/2]), double(chgs[cc*3/4]), double(chgs[cc])))); |         double(chgs[0]), double(chgs[cc/4]), double(chgs[cc/2]), double(chgs[cc*3/4]), double(chgs[cc]))); | ||||||
|       fflush(stdout); |  | ||||||
|       } |       } | ||||||
|      |      | ||||||
|     temperature = -5; |     temperature = -5; | ||||||
|     disable_snake(); |  | ||||||
|     sagmode = sagOff; |     sagmode = sagOff; | ||||||
|  |     reassign(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   void iterate() { |   void iterate() { | ||||||
|     if(!sagmode) return; |     if(!sagmode) return; | ||||||
|     int t1 = SDL_GetTicks(); |     int t1 = SDL_GetTicks(); | ||||||
|     enable_snake(); |  | ||||||
|     for(int i=0; i<ipturn; i++) { |     for(int i=0; i<ipturn; i++) { | ||||||
|       numiter++; |       numiter++; | ||||||
|       sag::saiter(); |       sag::saiter(); | ||||||
|       } |       } | ||||||
|     disable_snake(); |  | ||||||
|     int t2 = SDL_GetTicks(); |     int t2 = SDL_GetTicks(); | ||||||
|     int t = t2 - t1; |     int t = t2 - t1; | ||||||
|     if(t < 50) ipturn *= 2; |     if(t < 50) ipturn *= 2; | ||||||
|     else if(t > 200) ipturn /= 2; |     else if(t > 200) ipturn /= 2; | ||||||
|     else ipturn = ipturn * 100 / t; |     else ipturn = ipturn * 100 / t; | ||||||
|     DEBB(DF_LOG, ("it %8d temp %6.4f [2:%8.6f,10:%8.6f,50:%8.6f] cost = %f\n",  |     print(hlog, format("it %8d temp %6.4f [2:%8.6f,10:%8.6f,50:%8.6f] cost = %f\n",  | ||||||
|       numiter, double(sag::temperature),  |       numiter, double(sag::temperature),  | ||||||
|       (double) exp(-2 * exp(-sag::temperature)), |       (double) exp(-2 * exp(-sag::temperature)), | ||||||
|       (double) exp(-10 * exp(-sag::temperature)), |       (double) exp(-10 * exp(-sag::temperature)), | ||||||
|       (double) exp(-50 * exp(-sag::temperature)), |       (double) exp(-50 * exp(-sag::temperature)), | ||||||
|       (double) sag::cost)); |       (double) sag::cost)); | ||||||
|  |  | ||||||
|  |     reassign(); | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   void savesnake(const string& fname) { |   void save_sag_solution(const string& fname) { | ||||||
|     FILE *f = fopen(fname.c_str(), "wt"); |     FILE *f = fopen(fname.c_str(), "wt"); | ||||||
|     for(int i=0; i<N; i++) |     for(int i=0; i<isize(sagid); i++) | ||||||
|       fprintf(f, "%s;%d\n", vdata[i].name.c_str(), snakeid[i]); |       fprintf(f, "%s;%d\n", vdata[i].name.c_str(), sagid[i]); | ||||||
|     fclose(f); |     fclose(f); | ||||||
|     } |     } | ||||||
|    |    | ||||||
| @@ -370,19 +304,16 @@ namespace sag { | |||||||
|     int indist[30], pedge[30]; |     int indist[30], pedge[30]; | ||||||
|     for(int d=0; d<30; d++) indist[d] = 0, pedge[d] = 0; |     for(int d=0; d<30; d++) indist[d] = 0, pedge[d] = 0; | ||||||
|      |      | ||||||
|  |     int N = isize(sagid); | ||||||
|     for(int i=0; i<N; i++) |     for(int i=0; i<N; i++) | ||||||
|     for(int j=0; j<i; j++) |     for(int j=0; j<i; j++) | ||||||
|       indist[snakedist(snakeid[i], snakeid[j])]++; |       indist[sagdist[sagid[i]][sagid[j]]]++; | ||||||
|        |        | ||||||
|     for(int i=0; i<isize(sagedges); i++) { |     for(int i=0; i<isize(sagedges); i++) { | ||||||
|       edgeinfo& ei = sagedges[i]; |       edgeinfo& ei = sagedges[i]; | ||||||
|       if(snakedist(snakeid[ei.i], snakeid[ei.j]) == 0) { |       if(ei.i != ei.j) | ||||||
|         printf("zero between %d (%s) and %d (%s)\n",  |  | ||||||
|           snakeid[ei.i], vdata[ei.i].name.c_str(), |  | ||||||
|           snakeid[ei.j], vdata[ei.j].name.c_str()); |  | ||||||
|         } |  | ||||||
|       if(ei.weight >= sag_edge->visible_from) |       if(ei.weight >= sag_edge->visible_from) | ||||||
|         pedge[snakedist(snakeid[ei.i], snakeid[ei.j])]++; |         pedge[sagdist[sagid[ei.i]][sagid[ei.j]]]++; | ||||||
|       } |       } | ||||||
|      |      | ||||||
|     for(int d=0; d<30; d++)  |     for(int d=0; d<30; d++)  | ||||||
| @@ -434,8 +365,10 @@ namespace sag { | |||||||
|     maxweight = 0; |     maxweight = 0; | ||||||
|     sag_edge = add_edgetype("SAG edge"); |     sag_edge = add_edgetype("SAG edge"); | ||||||
|     fhstream f(fname, "rt"); |     fhstream f(fname, "rt"); | ||||||
|     if(!f.f) { printf("Failed to open SAG file: %s\n", fname); exit(1); } |     if(!f.f) { | ||||||
|     // while(fgetc(f) != 10 && fgetc(f) != 13 && !feof(f)) ; |       printf("Failed to open SAG file: %s\n", fname); | ||||||
|  |       throw "failed to open SAG file"; | ||||||
|  |       } | ||||||
|     while(!feof(f.f)) { |     while(!feof(f.f)) { | ||||||
|       string l1, l2; |       string l1, l2; | ||||||
|       while(true) { |       while(true) { | ||||||
| @@ -485,53 +418,39 @@ namespace sag { | |||||||
|     if(hub_filename != "") |     if(hub_filename != "") | ||||||
|       read_hubs(hub_filename); |       read_hubs(hub_filename); | ||||||
|      |      | ||||||
|     N = isize(vdata); |     int DN = isize(vdata); | ||||||
|     // totwei.resize(N); |  | ||||||
|     // for(int i=0; i<N; i++) totwei[i] = 0; |  | ||||||
|      |      | ||||||
|     for(int i=0; i<N; i++) vdata[i].data = 0; |     for(int i=0; i<DN; i++) vdata[i].data = 0; | ||||||
|     /* for(int i=0; i<isize(sagedges); i++) { |  | ||||||
|       edgeinfo& ei = sagedges[i]; |  | ||||||
|       // maxwei[ei.i] = max(maxwei[ei.i], ei.weight); |  | ||||||
|       // maxwei[ei.j] = max(maxwei[ei.j], ei.weight); |  | ||||||
|       // totwei[ei.i] += ei.weight; |  | ||||||
|       // totwei[ei.j] += ei.weight; |  | ||||||
|       } */ |  | ||||||
|     for(int i=0; i<isize(sagedges); i++) { |     for(int i=0; i<isize(sagedges); i++) { | ||||||
|       edgeinfo& ei = sagedges[i]; |       edgeinfo& ei = sagedges[i]; | ||||||
|       // (ei.weight >= maxwei[ei.i] / 5 || ei.weight >= maxwei[ei.j] / 5); |  | ||||||
|  |  | ||||||
|       ei.weight2 = pow((double) ei.weight, (double) edgepower) * edgemul; |       ei.weight2 = pow((double) ei.weight, (double) edgepower) * edgemul; | ||||||
|       // LANG:: pow(ei.weight, .4) / 50;       |  | ||||||
|        |        | ||||||
|       // ei.weight2 = 0; int w = ei.weight; while(w) { w >>= 1; ei.weight2++; }       |  | ||||||
|       /* if(totwei[ei.i] <= 0 || totwei[ei.j] <= 0) { |  | ||||||
|         printf("BAD TOTWEI\n"); |  | ||||||
|         exit(1); |  | ||||||
|         } |  | ||||||
|       ei.weight2 = 3 * ( |  | ||||||
|         sqrt(ei.weight * 1. / totwei[ei.i]) * log(totwei[ei.i]) * log(totwei[ei.i]) + |  | ||||||
|         sqrt(ei.weight * 1. / totwei[ei.j]) * log(totwei[ei.j]) * log(totwei[ei.j])); */ |  | ||||||
|       // printf("%f\n", ei.weight2); |  | ||||||
|       addedge0(ei.i, ei.j, &ei); |       addedge0(ei.i, ei.j, &ei); | ||||||
|       } |       } | ||||||
|    |    | ||||||
|     initSnake(N*2); |     if(legacy) | ||||||
|     printf("numsnake = %d\n", numsnake); |       init_snake(2 * DN); | ||||||
|     if(numsnake < N) { |     else | ||||||
|       printf("Error: snake does not fit\n"); |       init_sag_cells(); | ||||||
|  |  | ||||||
|  |     compute_dists(); | ||||||
|  |  | ||||||
|  |     int SN = isize(sagcells); | ||||||
|  |     if(SN < DN) { | ||||||
|  |       println(hlog, "SN = ", SN, " DN = ", DN); | ||||||
|  |       throw hr_exception("not enough cells for SAG"); | ||||||
|       exit(1); |       exit(1); | ||||||
|       } |       } | ||||||
|     snakeid.resize(N); |     sagid.resize(DN); | ||||||
|     for(int i=0; i<N; i++) snakeid[i] = -1; |     for(int i=0; i<DN; i++) sagid[i] = i; | ||||||
|     organize(); |     create_sagnode(); | ||||||
|     disable_snake(); |  | ||||||
|  |  | ||||||
|     for(int i=0; i<N; i++) { |     for(int i=0; i<DN; i++) { | ||||||
|       int ii = i; |       int ii = i; | ||||||
|       vertexdata& vd = vdata[ii]; |       vertexdata& vd = vdata[ii]; | ||||||
|       vd.cp = colorpair(dftcolor); |       vd.cp = colorpair(dftcolor); | ||||||
|       createViz(ii, sag::snakecells[sag::snakeid[i]], Id); |       createViz(ii, sagcells[sagid[i]], Id); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     storeall(); |     storeall(); | ||||||
| @@ -556,7 +475,7 @@ int readArgs() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
| // (1) configure edge weights | // (1) configure edge weights | ||||||
|   else if(argis("-edgepower")) { |   else if(argis("-sag-edgepower")) { | ||||||
|     shift_arg_formula(sag::edgepower); |     shift_arg_formula(sag::edgepower); | ||||||
|     shift_arg_formula(sag::edgemul); |     shift_arg_formula(sag::edgemul); | ||||||
|     } |     } | ||||||
| @@ -582,27 +501,48 @@ int readArgs() { | |||||||
|     shift(); hub_filename = args(); |     shift(); hub_filename = args(); | ||||||
|     } |     } | ||||||
| // (3) load the initial positioning | // (3) load the initial positioning | ||||||
|   else if(argis("-gload")) { |   else if(argis("-sagload")) { | ||||||
|     PHASE(3); shift(); sag::loadsnake(args()); |     PHASE(3); shift(); sag::load_sag_solution(args()); | ||||||
|     } |     } | ||||||
| // (4) perform simulated annealing: -fullsa <time in seconds> | // (4) perform simulated annealing: -fullsa <time in seconds> | ||||||
|   else if(argis("-fullsa")) { |   else if(argis("-sagfull")) { | ||||||
|     shift(); sag::dofullsa(argi()); |     shift(); sag::dofullsa(argi()); | ||||||
|     } |     } | ||||||
|  |   else if(argis("-sagviz")) { | ||||||
|  |     sag::vizsa_start = SDL_GetTicks(); | ||||||
|  |     shift(); sag::vizsa_len = argi(); | ||||||
|  |     } | ||||||
| // (5) save the positioning | // (5) save the positioning | ||||||
|   else if(argis("-gsave")) { |   else if(argis("-sagsave")) { | ||||||
|     PHASE(3); shift(); sag::savesnake(args()); |     PHASE(3); shift(); sag::save_sag_solution(args()); | ||||||
|     } |     } | ||||||
| // (6) output loglikelihood | // (6) output loglikelihood | ||||||
|   else if(argis("-lik")) { |   else if(argis("-sagloglik")) { | ||||||
|     sag::loglik(); |     sag::loglik(); | ||||||
|     } |     } | ||||||
|  |   else if(argis("-sagmode")) { | ||||||
|  |     shift(); | ||||||
|  |     sagmode = (eSagmode) argi(); | ||||||
|  |     if(sagmode == sagSA) { | ||||||
|  |       shift(); temperature = argf(); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   else return 1; |   else return 1; | ||||||
| #endif | #endif | ||||||
|   return 0; |   return 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| bool turn(int delta) { | bool turn(int delta) { | ||||||
|  |   if(vizsa_start) { | ||||||
|  |     auto t = ticks; | ||||||
|  |     double d = (t-vizsa_start) / (1000. * vizsa_len); | ||||||
|  |     if(d > 1) sagmode = sagOff; | ||||||
|  |     else { | ||||||
|  |       temperature = hightemp - (d*(hightemp-lowtemp)); | ||||||
|  |       sagmode = sagSA; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   iterate(); | ||||||
|   return false; |   return false; | ||||||
|   // shmup::pc[0]->rebase(); |   // shmup::pc[0]->rebase(); | ||||||
|   } |   } | ||||||
| @@ -634,9 +574,10 @@ int ah = addHook(hooks_args, 100, readArgs) | |||||||
|           drawthemap(); |           drawthemap(); | ||||||
|           gmatrix0 = gmatrix; |           gmatrix0 = gmatrix; | ||||||
|      |      | ||||||
|  |           slide_backup(rogueviz::sag::legacy, true); | ||||||
|           rogueviz::sag::read(RVPATH "roguelikes/edges.csv"); |           rogueviz::sag::read(RVPATH "roguelikes/edges.csv"); | ||||||
|           rogueviz::readcolor(RVPATH "roguelikes/color.csv"); |           rogueviz::readcolor(RVPATH "roguelikes/color.csv"); | ||||||
|           rogueviz::sag::loadsnake(RVPATH "roguelikes/" + cname()); |           rogueviz::sag::load_sag_solution(RVPATH "roguelikes/" + cname()); | ||||||
|           })     |           })     | ||||||
|         } |         } | ||||||
|       ); |       ); | ||||||
| @@ -654,9 +595,10 @@ int ah = addHook(hooks_args, 100, readArgs) | |||||||
|       drawthemap(); |       drawthemap(); | ||||||
|       gmatrix0 = gmatrix; |       gmatrix0 = gmatrix; | ||||||
|  |  | ||||||
|  |       slide_backup(rogueviz::sag::legacy, true); | ||||||
|       rogueviz::sag::read(RVPATH "lang/edges.csv"); |       rogueviz::sag::read(RVPATH "lang/edges.csv"); | ||||||
|       rogueviz::readcolor(RVPATH "lang/color.csv"); |       rogueviz::readcolor(RVPATH "lang/color.csv"); | ||||||
|       rogueviz::sag::loadsnake(RVPATH "lang/" + cname()); |       rogueviz::sag::load_sag_solution(RVPATH "lang/" + cname()); | ||||||
|       if(euclid) rogueviz::legend.clear(); |       if(euclid) rogueviz::legend.clear(); | ||||||
|       }) |       }) | ||||||
|     }); |     }); | ||||||
| @@ -675,9 +617,10 @@ int ah = addHook(hooks_args, 100, readArgs) | |||||||
|       drawthemap(); |       drawthemap(); | ||||||
|       gmatrix0 = gmatrix; |       gmatrix0 = gmatrix; | ||||||
|  |  | ||||||
|  |       slide_backup(rogueviz::sag::legacy, true); | ||||||
|       rogueviz::sag::read(RVPATH "boardgames/edges.csv"); |       rogueviz::sag::read(RVPATH "boardgames/edges.csv"); | ||||||
|       rogueviz::readcolor(RVPATH "boardgames/color.csv"); |       rogueviz::readcolor(RVPATH "boardgames/color.csv"); | ||||||
|       rogueviz::sag::loadsnake(RVPATH "boardgames/" + cname()); |       rogueviz::sag::load_sag_solution(RVPATH "boardgames/" + cname()); | ||||||
|       }) |       }) | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue