代码比对法,求助
查看原帖
代码比对法,求助
297555
Zlc晨鑫楼主2023/11/11 09:32

如下两份代码一模一样,为何跑出来结果大相径庭?

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
using namespace std;
const int N=12;
double p[N][N];
int n,m;
double dist(double a[],double b[]){//不是欧几里得距离,最后没有开根(为了精度
    double res=0;
    for(int i=1;i<=n;i++)
        res+=1.0*(a[i]-b[i])*(a[i]-b[i]);
    return res;
}
double rand(double l,double r){
    l=max(l,-2e4);
    l=min(l,2e4);
    r=max(r,-2e4);
    r=min(r,2e4);
    return 1.0*rand()/RAND_MAX*(r-l)+l;
}
double ans[N],Md=1e18;
double calc(double k[]){
    double dis[N];
    for(int i=1;i<=m;i++)
        dis[i]=dist(k,p[i]);
    double avg=0;
    for(int i=1;i<=m;i++)
        avg+=dis[i];
    avg/=m;
    double res=0;
    for(int i=1;i<=m;i++)
        res+=(avg-dis[i])*(avg-dis[i]);
    if(res<Md){
        Md=res;
        for(int i=1;i<=n;i++)
            ans[i]=k[i];
    }
    return res;
}
void simulate_anneal(){
    double k[N],q[N];
    double now=calc(k);
    double nex;
    for(double T=2e4;T>=1e-6;T*=0.9996){
        for(int i=1;i<=n;i++)
            q[i]=rand(k[i]-T,k[i]+T);
        nex=calc(q);
        double dt=nex-now;
        if(exp(-dt/T)>rand(0,1)){
            for(int i=1;i<=n;i++)
                k[i]=q[i];
            now=nex;
        }
    }
}
int main(){
    scanf("%d",&n);
    m=n+1;
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
            scanf("%lf",p[i]+j);
    while(1.0*clock()/CLOCKS_PER_SEC<0.9)
        simulate_anneal();
    for(int i=1;i<=n;i++)
        printf("%.3lf ",ans[i]);
    return 0;
}
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int N = 15;

int n;
double p[N][N], cur[N], ne[N], ans[N], minv = 1e18;

double rand(double l, double r) {
    l = min(l, 2e4);
    r = min(r, 2e4);
    l = max(l, -2e4);
    r = max(r, -2e4);
    return (double)rand() / RAND_MAX * (r - l) + l;
}

double dist(double a[], double b[]) {
    double res = 0;
    for (int i = 0; i < n; i ++ )
        res += (a[i] - b[i]) * (a[i] - b[i]);
    return res;
}

int m;
double calc(double k[]){
    double dis[N];
    for(int i=0;i<m;i++)
        dis[i]=dist(k,p[i]);
    double avg=0;
    for(int i=0;i<m;i++)
        avg+=dis[i];
    avg/=m;
    double res=0;
    for(int i=0;i<m;i++)
        res+=(avg-dis[i])*(avg-dis[i]);
    if(res<minv){
        minv=res;
        for(int i=0;i<n;i++)
            ans[i]=k[i];
    }
    return res;
}


// double calc(double a[]) {
//     double avg = 0;
//     for (int i = 0; i <= n; i ++ ) {
//         double sum = 0;
//         for (int j = 0; j < n; j ++ )
//             sum += (p[i][j] - a[j]) * (p[i][j] - a[j]);
//         dist[i] = sum;
//         avg += sum;
//     }
//     avg /= n + 1;
//     double res = 0;
//     for (int i = 0; i <= n; i ++ ) 
//         res += (avg - dist[i]) * (avg - dist[i]);
//     if (res < minv) {
//         minv = res;
//         for (int i = 0; i < n; i ++ )
//             ans[i] = a[i];
//     }
//     return res;
// }

void saa() {
    for (int i = 0; i < n; i ++ ) cur[i] = rand(-2e4, 2e4);
    for (double t = 2e4; t > 1e-15; t *= 0.9997) {
        for (int i = 0; i < n; i ++ )
            ne[i] = rand(cur[i] - t, cur[i] + t);
        
        double x = calc(cur), y = calc(ne);
        double dt = y - x;
        if (exp(-dt / t) > rand(0, 1)) 
            for (int i = 0; i < n; i ++ )
                cur[i] = ne[i];
    }
}

int main() {
    srand(time(0));
    scanf("%d", &n);
    m=n+1;
    for (int i = 0; i <= n; i ++ ) 
        for (int j = 0; j < n; j ++ )
            scanf("%lf", &p[i][j]);
    
    while ((double)clock() / CLOCKS_PER_SEC < 0.9) saa();
    
    for (int i = 0; i < n; i ++ ) printf("%.3lf ", ans[i]);
    
    return 0;
}
2023/11/11 09:32
加载中...