数学建模——商人与随从过河问题

# -*- coding: utf-8 -*-
 
"""
①判断当前状态是否合理
     - 得到答案输出
②合理进行 运输

适用于全部
"""

##初始条件, 
U = input("请输入小船容量:\n")# 小船容量
x0 = input("请输入商人数:\n")# 商人数
x0 = int(x0)
U = int(U)
y0 = x0 #随从
sk0 = [x0, y0] #初始sk状态


#记录过程
progress = []
#避免死循环 的标记集合
vis = set()

cnt = 0
ans_list = []



def getD(x):
    """获取容量为x 的D集合"""
    D = []
    for i in range(x+1):
        for j in range(x+1):
            if i+j!=0 and j+i<=x:
                D.append([i,j])
                
    return D

def valid_sk(sk):
    """
    判断当前状态sk是否合理
    """
    if sk[0] > x0 or sk[1] > x0 or sk[0] < 0 or sk[1] < 0:
        return False
    
    if sk[0] == 0 or sk[0] == x0:
        return True
    
    if sk[0] == sk[1]:
        return True
    
    return False


def accord_ans():
    """记录答案"""
    global cnt
    cnt+=1
    ans_list.append((len(progress)+1,progress[0:]+[[0,0]]))
    return
    
    

def DFS(sk, k, D):
    """搜索答案"""
    global progress,vis
    
    if not valid_sk(sk):
        return
    elif len(progress) >1:# 除去死循环, 无用功
        if (k%2, sk[0], sk[1]) in vis: 
            return
    
    if sk[0] ==0 and sk[1] == 0:#记录答案
       accord_ans()
       return
   
        
    #print(k, sk)
    
    progress.append(sk[:])# 加入该状态
    vis.add((k%2, sk[0], sk[1]))#标记
    for dk in D:
        
        if k%2 == 0:
            sk[0]-=dk[0]
            sk[1]-=dk[1]
            
            DFS(sk, k+1, D)
            
            sk[0]+=dk[0]
            sk[1]+=dk[1]
        else:
            sk[0]+=dk[0]
            sk[1]+=dk[1]
            DFS(sk, k+1, D)
            sk[0]-=dk[0]
            sk[1]-=dk[1]
            
    progress.pop()
    vis.remove((k%2, sk[0], sk[1]))
    

if __name__ == "__main__":
    
    #获取D集合
    D = getD(U)
    
    #输出答案
    print("答案:")
    DFS(sk0, 0, D)
    
    ans_list.sort(key=lambda x:x[0])
    for i, j in ans_list:
        print("摆渡次数", i, ", sk的状态", j)
    
    print("\n答案个数:",cnt)
    
    if cnt!= 0:
        min1 = ans_list[0][0]
        min_cnt = 0
        for i, j in ans_list:
            if i == min1:
                min_cnt+=1
        print("最优解的摆渡次数", min1)
        print("最优解有", min_cnt)
    
    
    

你可能感兴趣的:(数学建模)