هل يمكنك شرح الكود التالي بالتفصيل   % main_initialEncoding.m
% ملف تنفيذ الترميز الأولي

% قراءة البيانات من ملفات CSV
customer_file = 'solomon25_csv/customers/c101customers.csv';
dataInfo_file = 'solomon25_csv/data_info/c101dataInfo.csv';
distanceMatrix_file = 'solomon25_csv/distance_matrix/c101distanceMatrix.csv';

df_customers = readtable(customer_file);
df_distance_matrix = readtable(distanceMatrix_file);
df_dataInfo = readtable(dataInfo_file);

num_customers = height(df_customers);
num_customers_depot = num_customers + 1;
% ترتيب الفهارس من 1 إلى num_customers_depot

% إعداد مصفوفة العملاء
arr_customers = zeros(num_customers, 6);
arr_customers(:,1) = (1:num_customers)';
arr_customers(:,2) = df_customers.demand;
arr_customers(:,3) = df_customers.serviceTime;
arr_customers(:,4) = df_customers.readyTime;
arr_customers(:,5) = df_customers.dueTime;
arr_customers(:,6) = df_customers.completeTime;

% إعداد مصفوفة المسافات
arr_distance_matrix = table2array(df_distance_matrix);

% إعداد المتغيرات
all_customers_list = 1:num_customers;
total_time = df_dataInfo.fleet_max_working_time(1);
total_capacity = df_dataInfo.fleet_capacity(1);

% إعداد عدد السكان والتقسيم
N = 300;
greedy_percent = 0.10;
random_percent = 0.90;
alpha = 100;
beta = 0.001;
radius = (max(arr_distance_matrix(:)) - min(arr_distance_matrix(:))) / 2;

number_random_chromosomes = floor(N * random_percent) - 1;
number_nearest_nn_chromosomes = 1;
number_greedy_chromosomes = N - number_random_chromosomes - 1;

% إنشاء السكان الأوليين
[pop_chromosome_routeList_array, pop_chromosome_distanceList_array, pop_num_routes, pop_total_distance] = initial_population(N, 4, number_random_chromosomes, number_greedy_chromosomes, number_nearest_nn_chromosomes, num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list, radius);

% حفظ النتائج
save('initial_initialPop.mat', 'pop_chromosome_routeList_array');
save('initial_initialDistance.mat', 'pop_chromosome_distanceList_array');

% إنشاء جدول النتائج الأولية
df_initial_results = table(pop_num_routes, pop_total_distance, (alpha * pop_num_routes) + (beta * pop_total_distance), 'VariableNames', {'num_vehicles', 'distance', 'fitness'});

% حفظ جدول النتائج الأولية
writetable(df_initial_results, 'initial_initialResults.csv');

disp('تم إنشاء الترميزات الأولية بنجاح.');





function arr_feasible_customers = feasible_neighbours(num_customers, arr_customers, arr_distance_matrix, available_customers_list, total_time, total_capacity, curr_time, curr_capacity, curr_customer)
    num_available = length(available_customers_list);
    arr_feasible_customers = zeros(num_available, 12);
    
    % 0: customer number
    % 1: Demand
    % 2: serviceTime
    % 3: readyTime
    % 4: dueTime
    % 5: completeTime
    % 6: distance from current customer
    % 7: arrival_time
    % 8: waiting_time
    % 9: start_time
    % 10: finish_time
    % 11: return_time to depot
    
    % ترقيم العملاء بقائمة المتاحين
    arr_feasible_customers(:, 1:6) = arr_customers(available_customers_list, :);
    
    % تحديث السعة الحالية
    arr_feasible_customers(:, 2) = arr_feasible_customers(:, 2) + curr_capacity;
    
    % حساب المسافة من العميل الحالي إلى العملاء المتاحين
    arr_feasible_customers(:, 7) = arr_distance_matrix(curr_customer, available_customers_list);
    
    % حساب زمن الوصول إلى العملاء
    arr_feasible_customers(:, 8) = arr_feasible_customers(:, 7) + curr_time;
    
    % حساب وقت الانتظار
    arr_feasible_customers(:, 9) = arr_feasible_customers(:, 4) - arr_feasible_customers(:, 8);
    arr_feasible_customers(arr_feasible_customers(:, 9) < 0, 9) = 0;
    
    % حساب زمن البدء بعد الانتظار
    arr_feasible_customers(:, 10) = arr_feasible_customers(:, 8) + arr_feasible_customers(:, 9);
    
    % حساب زمن الانتهاء بعد الخدمة
    arr_feasible_customers(:, 11) = arr_feasible_customers(:, 10) + arr_feasible_customers(:, 3);
    
    % حساب زمن العودة إلى المستودع بعد الخدمة
    arr_feasible_customers(:, 12) = arr_distance_matrix(available_customers_list, 1) + arr_feasible_customers(:, 11); % Assuming depot is 0 in MATLAB indexing
    
    % تطبيق القيود
    feasible_idx = (arr_feasible_customers(:,2) <= total_capacity) & ...
                   (arr_feasible_customers(:,12) <= total_time) & ...
                   (arr_feasible_customers(:,10) >= arr_feasible_customers(:,4)) & ...
                   (arr_feasible_customers(:,11) <= arr_feasible_customers(:,6));
    arr_feasible_customers = arr_feasible_customers(feasible_idx, :);
end






function greedy_route_results = greedy_neighbour(num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list, radius)
    available_customers_list = all_customers_list;
    
    chromosome_route_list = {};
    chromosome_distance_list = {};
    route = [0]; 
    curr_capacity = 0;
    curr_time = 0;
    curr_customer = 0;
    curr_distance = 0;
    
    while ~isempty(available_customers_list)
        arr_feasible_neighbours = feasible_neighbours(num_customers, arr_customers, arr_distance_matrix, available_customers_list, total_time, total_capacity, curr_time, curr_capacity, curr_customer);
        if size(arr_feasible_neighbours, 1) ~= 0  % هناك عملاء قابلين للإدراج
            % تقليل مساحة البحث للعملاء ضمن نصف القطر
            within_radius = arr_feasible_neighbours(arr_feasible_neighbours(:,7) <= radius, :);
            if ~isempty(within_radius)
                arr_feasible_neighbours = within_radius;
            end
            feasible_neighbours_list = arr_feasible_neighbours(:,1)';
            rand_idx = randi(length(feasible_neighbours_list));
            curr_customer = feasible_neighbours_list(rand_idx);
            route = [route, curr_customer];
            curr_distance = curr_distance + arr_feasible_neighbours(rand_idx, 7);
            curr_capacity = arr_feasible_neighbours(rand_idx, 2);
            curr_time = arr_feasible_neighbours(rand_idx, 11);
            available_customers_list(available_customers_list == curr_customer) = [];
        else  % إنهاء المسار وإنشاء مسار جديد
            route = [route, 0];
            chromosome_route_list{end+1} = route;
            curr_distance = curr_distance + arr_distance_matrix(curr_customer + 1, 1); % MATLAB indexing
            chromosome_distance_list{end+1} = curr_distance;
            
            % تهيئة مسار جديد
            route = [0]; 
            curr_capacity = 0;
            curr_time = 0;
            curr_customer = 0;
            curr_distance = 0;
        end
    end
    % إنهاء المسار الأخير
    route = [route, 0];
    chromosome_route_list{end+1} = route;
    curr_distance = curr_distance + arr_distance_matrix(curr_customer + 1, 1); % MATLAB indexing
    chromosome_distance_list{end+1} = curr_distance;
    
    num_routes = length(chromosome_distance_list);
    total_distance = sum([chromosome_distance_list{:}]);
    
    greedy_route_results = {chromosome_route_list, chromosome_distance_list, num_routes, total_distance};
end







function [pop_chromosome_routeList_array, pop_chromosome_distanceList_array, pop_num_routes, pop_total_distance] = initial_population(N, num_cores, number_random_chromosomes, number_greedy_chromosomes, number_nearest_nn_chromosomes, num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list, radius)
    % تهيئة المسارات والمسافات والأعداد والمسافات الإجمالية
    pop_chromosome_routeList_array = cell(N,1);
    pop_chromosome_distanceList_array = cell(N,1);
    pop_num_routes = zeros(N,1);
    pop_total_distance = zeros(N,1);
    
    % إنشاء الترميزات العشوائية والجشعة باستخدام التوازي
    parfor i = 1:(number_random_chromosomes + number_greedy_chromosomes)
        if i <= number_random_chromosomes
            [routes, distances, num_routes, total_distance] = random_neighbour(num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list);
        else
            [routes, distances, num_routes, total_distance] = greedy_neighbour(num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list, radius);
        end
        pop_chromosome_routeList_array{i} = routes{1};
        pop_chromosome_distanceList_array{i} = distances{1};
        pop_num_routes(i) = num_routes;
        pop_total_distance(i) = total_distance;
    end
    
    % إضافة فرد باستخدام طريقة الجار الأقرب
    [routes, distances, num_routes, total_distance] = nearest_neighbour(num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list);
    pop_chromosome_routeList_array{number_random_chromosomes + number_greedy_chromosomes + 1} = routes;
    pop_chromosome_distanceList_array{number_random_chromosomes + number_greedy_chromosomes + 1} = distances;
    pop_num_routes(number_random_chromosomes + number_greedy_chromosomes + 1) = num_routes;
    pop_total_distance(number_random_chromosomes + number_greedy_chromosomes + 1) = total_distance;
    
    % ملء باقي السكان بالترميزات الجشوائية والجشعة
    for i = (number_random_chromosomes + number_greedy_chromosomes + 2):N
        % يمكن اختيار طريقة عشوائية أو جشعة هنا حسب الرغبة
        [routes, distances, num_routes, total_distance] = random_neighbour(num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list);
        pop_chromosome_routeList_array{i} = routes{1};
        pop_chromosome_distanceList_array{i} = distances{1};
        pop_num_routes(i) = num_routes;
        pop_total_distance(i) = total_distance;
    end
end





function [pop_chromosome_routeList_array, pop_chromosome_distanceList_array, arr_pop_results] = initial_routing_phase2(num_cores, N, alpha, beta, pop_chromosome_routeList_array, pop_chromosome_distanceList_array, arr_distance_matrix, arr_customers, total_time, total_capacity)
    % تهيئة مصفوفة النتائج
    arr_pop_results = zeros(N, 3); % [num_vehicles, distance, fitness]
    
    % تطبيق تحسين الترابط على جميع الأفراد بشكل متوازي
    parfor i = 1:N
        [chromosome, chromosome_distance_list, num_vehicles, total_distance, fitness] = routing_phase2(alpha, beta, pop_chromosome_routeList_array{i}, pop_chromosome_distanceList_array{i}, total_capacity, total_time, arr_distance_matrix, arr_customers);
        pop_chromosome_routeList_array{i} = chromosome;
        pop_chromosome_distanceList_array{i} = chromosome_distance_list;
        arr_pop_results(i, :) = [num_vehicles, total_distance, fitness];
    end
end





function nearest_route_results = nearest_neighbour(num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list)
    available_customers_list = all_customers_list;
    
    chromosome_route_list = {};
    chromosome_distance_list = {};
    route = [0]; 
    curr_capacity = 0;
    curr_time = 0;
    curr_customer = 0;
    curr_distance = 0;
    
    while ~isempty(available_customers_list)
        arr_feasible_neighbours = feasible_neighbours(num_customers, arr_customers, arr_distance_matrix, available_customers_list, total_time, total_capacity, curr_time, curr_capacity, curr_customer);
        if size(arr_feasible_neighbours, 1) ~= 0  % هناك عملاء قابلين للإدراج
            % اختيار العميل ذو المسافة الأدنى
            [min_dist, min_idx] = min(arr_feasible_neighbours(:,7));
            curr_customer = arr_feasible_neighbours(min_idx, 1);
            route = [route, curr_customer];
            curr_distance = curr_distance + min_dist;
            curr_capacity = arr_feasible_neighbours(min_idx, 2);
            curr_time = arr_feasible_neighbours(min_idx, 11);
            available_customers_list(available_customers_list == curr_customer) = [];
        else  % إنهاء المسار وإنشاء مسار جديد
            route = [route, 0];
            chromosome_route_list{end+1} = route;
            curr_distance = curr_distance + arr_distance_matrix(curr_customer + 1, 1); % MATLAB indexing
            chromosome_distance_list{end+1} = curr_distance;
            
            % تهيئة مسار جديد
            route = [0]; 
            curr_capacity = 0;
            curr_time = 0;
            curr_customer = 0;
            curr_distance = 0;
        end
    end
    % إنهاء المسار الأخير
    route = [route, 0];
    chromosome_route_list{end+1} = route;
    curr_distance = curr_distance + arr_distance_matrix(curr_customer + 1, 1); % MATLAB indexing
    chromosome_distance_list{end+1} = curr_distance;
    
    num_routes = length(chromosome_distance_list);
    total_distance = sum([chromosome_distance_list{:}]);
    
    nearest_route_results = {chromosome_route_list, chromosome_distance_list, num_routes, total_distance};
end





function random_route_results = random_neighbour(num_customers, arr_customers, arr_distance_matrix, total_capacity, total_time, all_customers_list)
    available_customers_list = all_customers_list;
    
    chromosome_route_list = {};
    chromosome_distance_list = {};
    route = [0]; 
    curr_capacity = 0;
    curr_time = 0;
    curr_customer = 0;
    curr_distance = 0;
    
    while ~isempty(available_customers_list)
        arr_feasible_neighbours = feasible_neighbours(num_customers, arr_customers, arr_distance_matrix, available_customers_list, total_time, total_capacity, curr_time, curr_capacity, curr_customer);
        if size(arr_feasible_neighbours, 1) ~= 0  % هناك عملاء قابلين للإدراج
            feasible_neighbours_list = arr_feasible_neighbours(:,1)';
            rand_idx = randi(length(feasible_neighbours_list));
            curr_customer = feasible_neighbours_list(rand_idx);
            route = [route, curr_customer];
            curr_distance = curr_distance + arr_feasible_neighbours(rand_idx, 7);
            curr_capacity = arr_feasible_neighbours(rand_idx, 2);
            curr_time = arr_feasible_neighbours(rand_idx, 11);
            available_customers_list(available_customers_list == curr_customer) = [];
        else  % إنهاء المسار وإنشاء مسار جديد
            route = [route, 0];
            chromosome_route_list{end+1} = route;
            curr_distance = curr_distance + arr_distance_matrix(curr_customer + 1, 1); % MATLAB indexing
            chromosome_distance_list{end+1} = curr_distance;
            
            % تهيئة مسار جديد
            route = [0]; 
            curr_capacity = 0;
            curr_time = 0;
            curr_customer = 0;
            curr_distance = 0;
        end
    end
    % إنهاء المسار الأخير
    route = [route, 0];
    chromosome_route_list{end+1} = route;
    curr_distance = curr_distance + arr_distance_matrix(curr_customer + 1, 1); % MATLAB indexing
    chromosome_distance_list{end+1} = curr_distance;
    
    num_routes = length(chromosome_distance_list);
    total_distance = sum([chromosome_distance_list{:}]);
    
    random_route_results = {chromosome_route_list, chromosome_distance_list, num_routes, total_distance};
end





function [route_validity_status, curr_dist] = route_validity(route, arr_distance_matrix, arr_customers, total_time, total_capacity)
    route_validity_status = true;
    curr_dist = arr_distance_matrix(route(1)+1, route(2)+1); % MATLAB indexing
    curr_capacity = arr_customers(route(2), 2); % demand
    ready_time = arr_customers(route(2), 4);
    due_time = arr_customers(route(2), 5);
    curr_time = arr_distance_matrix(route(1)+1, route(2)+1); 
    waiting_time = max(0, ready_time - curr_time);
    curr_time = curr_time + waiting_time + arr_customers(route(2), 3); % service time
    
    route_customers = route(2:end-1);
    for i = 1:length(route_customers)-1
        curr_dist = curr_dist + arr_distance_matrix(route_customers(i)+1, route_customers(i+1)+1);
        curr_time = curr_time + arr_distance_matrix(route_customers(i)+1, route_customers(i+1)+1);
        
        ready_time = arr_customers(route_customers(i+1), 4);
        due_time = arr_customers(route_customers(i+1), 5);
        service_time = arr_customers(route_customers(i+1), 3);
        curr_capacity = curr_capacity + arr_customers(route_customers(i+1), 2);
        
        if (curr_time <= due_time) && (curr_capacity <= total_capacity)
            waiting_time = max(0, ready_time - curr_time);
            if ((curr_time + waiting_time >= ready_time) && (curr_time + waiting_time + service_time <= total_time))
                curr_time = curr_time + waiting_time + service_time;
            else
                route_validity_status = false;
                break;
            end
        else
            route_validity_status = false;
            break;
        end
    end
    
    if route_validity_status
        curr_dist = curr_dist + arr_distance_matrix(route(end-1)+1, route(end)+1);
        curr_time = curr_time + arr_distance_matrix(route(end-1)+1, route(end)+1);
        if curr_time > total_time
            route_validity_status = false;
        end
    end
end





function [chromosome, chromosome_distance_list, num_vehicles, total_distance, fitness] = routing_phase2(alpha, beta, chromosome, chromosome_distance_list, total_capacity, total_time, arr_distance_matrix, arr_customers)
    index_list = 1:length(chromosome)+1;
    index_list(end) = 1; % Assuming depot is at index 1
    
    for i = 1:length(index_list)-1
        r1_index = index_list(i);
        r2_index = index_list(i+1);
        route_r1 = chromosome{r1_index};
        route_r2 = chromosome{r2_index};
        dist_r1 = chromosome_distance_list{r1_index};
        dist_r2 = chromosome_distance_list{r2_index};
        customer_r1 = route_r1(end-1);
        
        % إدراج العميل في بداية المسار الثاني
        route_r2 = [route_r2(1), customer_r1, route_r2(2:end)];
        
        % التحقق من صلاحية المسار الجديد
        [route_validity_status, new_r2_dist] = route_validity(route_r2, arr_distance_matrix, arr_customers, total_time, total_capacity);
        
        if route_validity_status
            if length(route_r1) > 3
                new_r1_dist = dist_r1 - arr_distance_matrix(route_r1(end-1)+1, 1) + arr_distance_matrix(route_r1(end-2)+1, 1);
                if (dist_r1 + dist_r2) > (new_r1_dist + new_r2_dist)
                    % تحديث المسارات والمسافات
                    route_r1(end) = [];
                    chromosome{r1_index} = route_r1;
                    chromosome{r2_index} = route_r2;
                    chromosome_distance_list{r1_index} = new_r1_dist;
                    chromosome_distance_list{r2_index} = new_r2_dist;
                end
            else
                % حذف المسار الأول وتحديث المسار الثاني
                chromosome(r1_index) = [];
                chromosome{r2_index} = route_r2;
                chromosome_distance_list(r1_index) = [];
                chromosome_distance_list{r2_index} = new_r2_dist;
            end
        end
    end
    
    total_distance = sum(cellfun(@(x) x, chromosome_distance_list));
    num_vehicles = length(chromosome_distance_list);
    fitness = alpha * num_vehicles + beta * total_distance;
end