import numpy as np
def select_r(y_k,x_b):
# print(y_k,x_b)
index_1=np.where(y_k>0)[0]#挑选y_k中大于0的元素的下标
# print(x_b[index_1]/y_k[index_1])
index_2=np.argmin(x_b[index_1]/y_k[index_1])#对应相除得到确定r的集合,取该集合元素最小的下标
# print(index_1,index_2)
r=index_1[index_2]
return r#这里的r起始坐标为0,若要带入手算需要+1
def select_k(w,index_N,c,P):
q=np.dot(w,P[:,index_N])-c[index_N]#计算判别数
if np.all(q<=0):
print("已经为最优解")
return 1,True
else:
index_1=np.argmax(q)
k=index_N[index_1]
return k,False
def swap(index_N,index_B,r,k):
index_N[np.where(index_N==k)[0]]=index_B[r]
index_B[r]=k
return index_N,index_B
def LP(A,b,c):
aux = np.eye(A.shape[0]) # 加入松弛变量
c = np.concatenate((c, np.zeros(A.shape[0]))) # 目标函数系数扩增松弛变量系数
P = np.concatenate((A, aux), axis=1)
index_B = np.arange(A.shape[1],A.shape[1]+A.shape[0]) # 基变量的下标
index_N = np.arange(A.shape[1]) # 非基变量下标
# c=np.concatenate((c,np.zeros(3)),axis=1)
flag=True
while flag:
c_b = c[index_B] # 基变量的目标函数系数
B = P[:, index_B]
B_1 = np.linalg.inv(B)
x_b = np.dot(B_1, b)
w = np.dot(c_b, B_1)
# 计算判别数
# judge_array= np.zeros(A.shape[1]+c_b.shape[0])
# judge_array[0]=np.dot(w,P[:,0])-c[0]
# judge_array[1]=np.dot(w,P[:,1])-c[1]
# if np.all(judge_array<=0) :
# # return x_b,N+1#现行解是最优解
# pass
k,end = select_k(w, index_N, c, P)
if end:
return np.dot(B_1,b),index_B+1
# 确定k之后
# k=np.argmax(judge_array)
# print(k)
# 进行y_k计算
y_k = np.dot(B_1, P[:, k])
if np.all(y_k <= 0): # 如果y_k的每个分量均为小于等于0,则问题不存在最优解
print("此问题不存在最优解")
return 0,0
r = select_r(y_k, x_b)
index_N, index_B = swap(index_N, index_B, r, k)
A = np.array([[1,-1],[3,2],[-2,1]])
b = np.array([0,5,1]).T#小于
c = np.array([-3,- 1])#min最小值
print(LP(A,b,c))#返回的是(array([1., 1., 2.]), array([1, 2, 5])),代表第1,2,5个变量的值为1,1,2,其余变量为0
自己尝试看课本单纯形法步骤实现的,目前有些不是很完善的地方,比如当我把x1范围限制在2-4之间,求解出来的x1结果不符合约束要求。。。