2 분 소요

개요

travelsalesman 최단거리 머신러닝 계산하기 하다 세일즈맨의 최단 거리 계산하는 것을 머신러닝을 이용해보자

이 클래스는 시뮬레이션 어닐링 최적화 알고리즘에 사용되는 시스템 상태에 대한 예제 인터페이스를 선언합니다.

실행 화면

프로그램 설명

전체 코드

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>

using namespace cv;

class TravelSalesman 
{
private:
    const std::vector<Point>& posCity;
    std::vector<int>& next;
    RNG rng;
    int d0, d1, d2, d3;

public:
    TravelSalesman(std::vector<Point>& p, std::vector<int>& n) :
        posCity(p), next(n)
    {
        rng = theRNG();
    }
    /** Give energy value for a state of system.*/
    double energy() const;
    /** Function which change the state of system (random perturbation).*/
    void changeState();
    /** Function to reverse to the previous state.*/
    void reverseState();

};

void TravelSalesman::changeState()
{
    d0 = rng.uniform(0, static_cast<int>(posCity.size()));
    d1 = next[d0];
    d2 = next[d1];
    d3 = next[d2];

    next[d0] = d2;
    next[d2] = d1;
    next[d1] = d3;
}


void TravelSalesman::reverseState()
{
    next[d0] = d1;
    next[d1] = d2;
    next[d2] = d3;
}

double TravelSalesman::energy() const
{
    double e = 0;
    for (size_t i = 0; i < next.size(); i++)
    {
        e += norm(posCity[i] - posCity[next[i]]);
    }
    return e;
}


static void DrawTravelMap(Mat& img, std::vector<Point>& p, std::vector<int>& n)
{
    for (size_t i = 0; i < n.size(); i++)
    {
        circle(img, p[i], 5, Scalar(0, 0, 255), 2);
        line(img, p[i], p[n[i]], Scalar(0, 255, 0), 2);
    }
}
int main(void)
{
    int nbCity = 40;  //도시 갯수
    Mat img(500, 500, CV_8UC3, Scalar::all(0));
    RNG rng(123456);  //램덤 숫자 생성 

    int radius = static_cast<int>(img.cols * 0.45);
    Point center(img.cols / 2, img.rows / 2);

    std::vector<Point> posCity(nbCity);
    std::vector<int> next(nbCity);
    for (size_t i = 0; i < posCity.size(); i++) // 도시들 위치와 다음 도시 선택
    {
        double theta = rng.uniform(0., 2 * CV_PI);
        posCity[i].x = static_cast<int>(radius * cos(theta)) + center.x;
        posCity[i].y = static_cast<int>(radius * sin(theta)) + center.y;
        next[i] = (i + 1) % nbCity;
    }
    TravelSalesman ts_system(posCity, next);  //도시 와 다음 도시 배열 생성

    DrawTravelMap(img, posCity, next);  //도시 이동 지도 그리기
    imshow("Map", img);
    waitKey(10);
    double currentTemperature = 100.0;
    for (int i = 0, zeroChanges = 0; zeroChanges < 10; i++)
    {
        int changesApplied = ml::simulatedAnnealingSolver(ts_system, currentTemperature, currentTemperature * 0.97, 0.99, 10000 * nbCity, &currentTemperature, rng);
        img.setTo(Scalar::all(0));
        DrawTravelMap(img, posCity, next);
        imshow("Map", img);
        int k = waitKey(10);
        std::cout << "i=" << i << " changesApplied=" << changesApplied << " temp=" << currentTemperature << " result=" << ts_system.energy() << std::endl;
        if (k == 27 || k == 'q' || k == 'Q')
            return 0;
        if (changesApplied == 0)
            zeroChanges++;
    }
    std::cout << "Done" << std::endl;
    waitKey(0);
    return 0;
}



사용 OpenCV 함수

int simulatedAnnealingSolver(SimulatedAnnealingSolverSystem& solverSystem, double initialTemperature, double finalTemperature, double coolingRatio, size_t iterationsPerStep, CV_OUT double* lastTemperature, cv::RNG& rngEnergy )

mulatedAnnealingSolverSystem& solverSystem,

첫번쨰 함수는 3가지 멤버 함수가 필요한다 /** Give energy value for a state of system./ double energy() const; 소모 되는 것 /** Function which change the state of system (random perturbation)./ void changeState(); 변동 사항 /** Function to reverse to the previous state.*/ 이전 값 저장 void reverseState();

참조 링크

https://docs.opencv.org/3.4/dc/db4/structcv_1_1ml_1_1SimulatedAnnealingSolverSystem.html

댓글남기기