Mathematical Modeling-Merchants Crossing the River (Matlab)

Problem Description

Each of the three merchants took a boat to cross the river. A small boat could only accommodate two people, and they rowed by themselves. The servants made a secret appointment. On any bank of the river, if there were more followers than merchants, they would kill people and sell them. But The power of how to cross the river by boat is in the hands of the merchants. How can the merchants cross the river safely?
For this type of intellectual game, after some logical thinking, a solution can be found. Here, a mathematical model is used to solve the problem. The first is to give The second example of modeling is because this type of model can solve a wide range of problems and is easier to generalize than the result of logical thinking.

problem analysis

The problem has been idealized, so it can be abstracted into a multi-step decision-making problem, that is, to ensure that the number of merchants on both sides of the strait and on the ship is greater than or equal to the number of entourage during the round trip. The allowable safe state variable is used to represent the status of the personnel on the shore, and the allowable decision variable represents the status of the personnel on the ship. The law of the state changing with the decision can be found, and the problem is transformed into a decision in the allowed state to achieve safe crossing of the river.

Modeling

Here I refer to the fourth edition of "Mathematical Model" by Jiang Qiyuan-a case of how businessmen can safely cross the river

The flow chart of the code implementation is given below
Insert picture description here

Code

main.m

%% 商人安全过河问题
close, clear, clc
%% 声明全局变量
% setOfAllowedStates 允许状态集合
% setOfDecisionVariables 允许决策集合
% collectionOfStatusMarkers 状态标记集合
% numberOfBusinessmen 商人的总人数
% numberOfFollowers 随从的总人数
% maximumLoadCapacity 船的最大承载人数
% totalSetOfDecisionVariables 允许决策个数
% totalSetOfAllowedStates 允许状态个数
% 0ollectionOfStatusMarkersBegin 初始编号
% collectionOfStatusMarkersProcess 中间编号
% collectionOfStatusMarkersEnd 终止编号
global setOfAllowedStates setOfDecisionVariables collectionOfStatusMarkers numberOfBusinessmen collectionOfStatusMarkersProcess cnt k;
global collectionOfStatusMarkersBegin collectionOfStatusMarkersEnd numberOfFollowers maximumLoadCapacity totalSetOfDecisionVariables totalSetOfAllowedStates;
setOfAllowedStates = [];
setOfDecisionVariables = [];
totalSetOfDecisionVariables = 0;
totalSetOfAllowedStates = 0; 

%% 输入
fprintf('输入大于3 3 2时候将不再作图\n')
numberOfBusinessmen = input('请输入商人的人数:');
numberOfFollowers = input('请输入随从的人数:');
maximumLoadCapacity = input('请输入船的最大承载人数:');

%% 作图属性
axis([0 numberOfBusinessmen 0 numberOfBusinessmen]);
set(gca, 'XTick', 0 : 1 : numberOfBusinessmen), set(gca, 'YTick', 0 : 1 : numberOfFollowers);
xlabel('此岸商人数'), ylabel('此岸随从数'), title('允许状态集合')
grid on

%% 允许状态集合
for businessmen = 0 : numberOfBusinessmen
    for followers = 0 : numberOfFollowers
        if(businessmen == 0 || businessmen == numberOfBusinessmen || (businessmen >= followers && numberOfBusinessmen - businessmen >= numberOfFollowers - followers))
            totalSetOfAllowedStates = totalSetOfAllowedStates + 1;
            setOfAllowedStates(totalSetOfAllowedStates, :) = [businessmen, followers];
            hold on
            plot(businessmen, followers, 'b*', 'MarkerSize', 10);
        end
    end
end

setOfAllowedStates = [setOfAllowedStates, ones(totalSetOfAllowedStates, 1); setOfAllowedStates, zeros(totalSetOfAllowedStates, 1)];
totalSetOfAllowedStates = totalSetOfAllowedStates * 2;
fprintf('共有%d种允许状态\n', totalSetOfAllowedStates)
printfAllowedStates = input('是否打印允许状态集合y/n?','s');
if printfAllowedStates == 'y'
    fprintf('允许状态集合:')
    setOfAllowedStates
end
%% 允许决策集合
for businessmen = 0 : numberOfBusinessmen
    for followers = 0 : numberOfFollowers
        if(businessmen + followers >= 1 && businessmen + followers <= maximumLoadCapacity)
            totalSetOfDecisionVariables = totalSetOfDecisionVariables + 1;
            setOfDecisionVariables(totalSetOfDecisionVariables, :) = [businessmen, followers];
        end
    end
end
fprintf('共%d个允许决策\n',totalSetOfDecisionVariables);
printfDecisionVariables = input('是否打印允许决策集合y/n?','s');
if printfDecisionVariables == 'y'
    fprintf('允许决策集合:');
    setOfDecisionVariables
end
%% 状态标记集合
% 初始状态利用哈希表
collectionOfStatusMarkers = zeros(totalSetOfAllowedStates, 1);
collectionOfStatusMarkersBegin = find(ismember(setOfAllowedStates, [numberOfBusinessmen, numberOfBusinessmen, 1], 'rows') == 1); % 初始状态编号
collectionOfStatusMarkersEnd = find(ismember(setOfAllowedStates, [0, 0, 0], 'rows') == 1); % 终止状态编号
cnt = 0;
k = 1;
collectionOfStatusMarkers(collectionOfStatusMarkersBegin) = 1;
collectionOfStatusMarkersProcess(1) = collectionOfStatusMarkersBegin;

%% 模拟过河(递归实现)
crossTheRiver(collectionOfStatusMarkersBegin);
if cnt == 0
    fprintf('This question currently has no answer.\n')
else
    fprintf('共有%d个方法\n', cnt)
end

crossTheRiver.m

function crossTheRiver(present)
    global setOfAllowedStates setOfDecisionVariables collectionOfStatusMarkers collectionOfStatusMarkersProcess k  numberOfBusinessmen;
    global collectionOfStatusMarkersEnd totalSetOfDecisionVariables cnt;
    if present == collectionOfStatusMarkersEnd
        printCurrentResults();
        if numberOfBusinessmen <= 3
            plotCurrentResults(cnt + 1);
        end
    else
        for i = 1 : totalSetOfDecisionVariables
            possible(1, [1 2]) = setOfAllowedStates(present, [1 2]) + ((-1)^(setOfAllowedStates(present, 3))) * setOfDecisionVariables(i, :);
            possible(1, 3) = 1 - setOfAllowedStates(present, 3);
            tag = ismember(setOfAllowedStates, possible, 'rows');
            if sum(tag) == 1
                next = find(tag == 1);
                if collectionOfStatusMarkers(next) == 0
                    collectionOfStatusMarkers(next) = 1;
                    k = k + 1;
                    collectionOfStatusMarkersProcess(k) = next;
                    crossTheRiver(next);
                    collectionOfStatusMarkers(next) = 0;
                    k = k - 1;
                end
            end
        end
    end
end

printCurrentResults.m

function printCurrentResults()
    global setOfAllowedStates numberOfBusinessmen collectionOfStatusMarkersProcess cnt k numberOfFollowers
    cnt = cnt + 1;
    fprintf('方法 %d:\n',cnt);
    fprintf('\t\t\t\t此\t岸\t\t\t\t\n');
    fprintf('\t商人数\t\t\t随从数\t\t\t船的位置\n');
    for i=1:k
        fprintf('%d:\t %d\t\t\t\t %d',i,setOfAllowedStates(collectionOfStatusMarkersProcess(i),1),setOfAllowedStates(collectionOfStatusMarkersProcess(i),2));
        if setOfAllowedStates(collectionOfStatusMarkersProcess(i),3)==1 % 船在此岸
            fprintf('\t\t\t\t\t此岸\n');
        else
            fprintf('\t\t\t\t\t彼岸\n');
        end
    end
    fprintf('\n');
end

plotCurrentResults.m

function plotCurrentResults(cntPicture)
    global setOfAllowedStates collectionOfStatusMarkersProcess k numberOfBusinessmen numberOfFollowers;
    figure(cntPicture)
    axis([0 numberOfBusinessmen 0 numberOfBusinessmen]);
    set(gca, 'XTick', 0 : 1 : numberOfBusinessmen), set(gca, 'YTick', 0 : 1 : numberOfFollowers);
    xlabel('此岸商人数'), ylabel('此岸随从数'), title(['方法', num2str(cntPicture)])
    grid on
    for i = 2 : k
        hold on
        plot([setOfAllowedStates(collectionOfStatusMarkersProcess(i - 1),1), setOfAllowedStates(collectionOfStatusMarkersProcess(i),1)],...
            [setOfAllowedStates(collectionOfStatusMarkersProcess(i - 1),2), setOfAllowedStates(collectionOfStatusMarkersProcess(i),2)], 'LineWidth',3)
        pause(0.2)
    end
end

Dynamic display

Insert picture description here


If there are any mistakes and improvements, please leave a message in the comment area below!

Guess you like

Origin blog.csdn.net/zy440458/article/details/114271787