退火求调参数玄关 最高95pts
查看原帖
退火求调参数玄关 最高95pts
933802
ICU152_lowa_IS8楼主2024/1/9 23:38
#include<bits/stdc++.h>
#define down 0.9999
using namespace std;
int a[10005];
int ans[105][105],fin[105][105],cnt=INT_MAX;
int f[105][105];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int n,m,c;
int check(){
	int cnt=0;
	for(short i=1;i<=n;i++){
		for(short j=1;j<=m;j++){
			for(short k=0;k<4;k++){
				int x=i+dx[k],y=j+dy[k];
				if(x>=1&&x<=n&&y>=1&&y<=m&&f[x][y]!=f[i][j])cnt++;
			}
		}
	}
	return cnt/2;
}
void sa(){
	double t=1000;
	while(t>1e-15){
		int x1=rand()%n+1;
		int x2=rand()%n+1;
		int y1=rand()%m+1;
		int y2=rand()%m+1;
//		if(x1>n||y1>m||x2>n||y2>m)cout<<"ERROR\n";
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				f[i][j]=ans[i][j];
			}
		}
		swap(f[x1][y1],f[x2][y2]);
		int v=0;
		v=check();
		int F=v-cnt;
		if(F<0){
			cnt=v;
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					ans[i][j]=fin[i][j]=f[i][j];
				}
			}
		}
		else if(exp(-F/t)*RAND_MAX>rand()*1.005){
            cnt=v;
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					ans[i][j]=f[i][j];
				}
			}
		}
		t*=down;
	}
}
int main(){
	srand(time(NULL));
    srand(rand()*rand());
	cin>>n>>m>>c;
	for(int i=1;i<=c;i++){
		cin>>a[i];
	}
	int nowp=1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[nowp]==0)nowp++;
			ans[i][j]=nowp;
			a[nowp]--;
		}
	}
//	cout<<nowp<<endl;
	for(int i=1;i<=3;i++)sa();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<fin[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}
2024/1/9 23:38
加载中...