Я получаю ошибку преобразования в моем решении C ++ для TSP - PullRequest
1 голос
/ 16 июня 2019

Я пытаюсь решить TSP в C ++ с помощью многомерного массива и получаю сообщение об ошибке преобразования типов.

Я устал от C ++, так как не использовал его несколько лет, поэтому, чтобы переучиться, я решил попробовать несколько решений Traveling Salesman. Первое, что я использую, использует многомерный массив для хранения точек, которые назначаются случайным образом. Эта часть работала нормально, поэтому я перешел к формуле расстояния. Я создал вспомогательную функцию для базовой формулы расстояния, которая принимает 2 массива в качестве входных данных, которая прекрасно работает самостоятельно, а затем создал функцию, чтобы найти общее расстояние для полного массива городов. Он принимает массив значений типа double и целое число, представляющее общее количество городов, затем перебирает массив, находя расстояние для каждой точки и складывая их вместе.

Вот объявление переменной и случайное присвоение точки

    int numCities = 10;
    double cities[numCities][2];

    //Creates random(unseeded) points
    for(int i = 0; i < numCities; i++){
        for(int j = 0; j < 2; j++){
            cities[i][j] = (rand() % 100) + 1;
        }
    }

Вот строка, используемая для вызова функции

    cout << distTotal(cities, numCities) << endl;

А вот функция и вспомогательная функция

    //basic distance formula
    double cityDist(double cityA[], double cityB[]){
        return sqrt(pow((cityB[0]-cityA[0]), 2.0)+
                    pow((cityB[1]-cityA[1]), 2.0));
    }

    //calculate total distance of group of cities
    double distTotal(double* points[], int num){
        double total = 0;
        for(int i = 0; i < num-1; i++){
            total=total+cityDist(points[i], points[i+1]);
        }
        return total;
    }

Так что в идеале это должно дать мне общее расстояние между всеми точками в базовом порядке, указанном здесь. Однако в настоящее время я получаю следующую ошибку:

ошибка: невозможно преобразовать 'double (*) [2] "в" double ** "для аргумента" 1 "в" double distTotal (double **, int) "

Если я правильно помню, это может быть связано с указателями, но я, честно говоря, недостаточно помню об указателях C ++, чтобы знать, как это исправить.

Любая помощь приветствуется, спасибо

Ответы [ 2 ]

1 голос
/ 16 июня 2019

Ваше объявление должно быть double* points, поскольку C-массивы распадаются на указатели. Если вы делаете c ++, вы можете вместо этого использовать std::vector<double>& в качестве ввода.

Редактировать: если вы в конечном итоге используете c-массивы, вам придется разместить их в куче и освободить ресурсы.

0 голосов
/ 17 июня 2019
int numCities = 10;
double cities[numCities][2];

Вместо наличия анонимной пары double с позициями x и y каждого города, создайте для нее class / struct. Это облегчит расширение вашего решения позже. Если вы хотите сохранить название города с указанием его позиции, например:

struct position_t {
    double x;
    double y;
};

struct city_t {
    position_t position;
    std::string name;
};

Тогда вместо фиксированного числа городов в массиве рассмотрите возможность использования vector, который может динамически увеличиваться и уменьшаться во время выполнения:

std::vector<city_t> cities;

С добавлением некоторых вспомогательных функций:

#include <cmath>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>

struct position_t {
    position_t(double X, double Y) : x(X), y(Y) {}

    double dist(const position_t& other) const {
        return std::sqrt(std::pow(x - other.x, 2.) + std::pow(y - other.y, 2.));
    }

    // a function to print the position
    friend std::ostream& operator<<(std::ostream&, const position_t&);

    double x;
    double y;
};

std::ostream& operator<<(std::ostream& os, const position_t& p) {
    return os << '{' << p.x << ',' << p.y << '}';
}

struct city_t {
    city_t(const position_t& p, const std::string_view& n) : position(p), name(n) {}

    double dist(const city_t& other) const {
        // this distance function just calls the function in the position_t
        return position.dist(other.position);
    }

    // a function to print the values of the city    
    friend std::ostream& operator<<(std::ostream&, const city_t&);

    position_t position;
    std::string name;
};

std::ostream& operator<<(std::ostream& os, const city_t& c) {
    return os << c.position << ' ' << c.name;
}

int main() {
    std::vector<city_t> cities = {{{10., 20.}, "Ankeborg"},
                                  {{11., 12.}, "Gothenburg"}};
    for(const auto& c : cities) {
        std::cout << c << "\n";
    }
    std::cout << "distance: " << cities[0].dist(cities[1]) << "\n";
}

Выход:

{10,20} Ankeborg
{11,12} Gothenburg
distance: 8.06226
...