Last active
November 17, 2016 17:33
-
-
Save ZTGeng/0c47e4de420d2682e7a27e6a8442e67d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Arrays; | |
/** | |
* 简单测试。 | |
*/ | |
public class Test { | |
public static void main(String[] args) { | |
Double[] terms = new Double[] {8.0, null, 13.0, null, null, null, null, null, 8.0, null, null, 6.0}; | |
double[] solution = FourVariablesLinearEquations.solution(terms); | |
System.out.println(Arrays.toString(solution)); | |
} | |
} | |
/** | |
* 解系数为1的二元一次方程组。 | |
*/ | |
class TwoVariablesLinearEquations { | |
/** | |
* @param apb 方程 a + b = m 的右值 | |
* @param amb 方程 a - b = n 的右值 | |
* 注:可通过方程两边取反将 b - a = m 变为 a - b = -m 。 | |
* @return [a, b] | |
*/ | |
public static double[] solution(double apb, double amb) { | |
double a = (apb + amb) / 2; | |
double b = (apb - amb) / 2; | |
return new double[] {a, b}; | |
} | |
} | |
/** | |
* 解系数为1的三元一次方程组。 | |
*/ | |
class ThreeVariablesLinearEquations { | |
/** | |
* @param terms [apb, amb, apc, amc, bpc, bmc],其中: | |
* apb 是方程 a + b = m 的右值 | |
* amb 是方程 a - b = n 的右值 | |
* apc 是方程 a + c = o 的右值 | |
* amc 是方程 a - c = p 的右值 | |
* bpc 是方程 b + c = q 的右值 | |
* bmc 是方程 b - c = r 的右值 | |
* 以上需有且仅有三项不为null,且不可由其中两项推出第三项。 | |
* 注:可通过方程两边取反将 b - a = m 变为 a - b = -m 。 | |
* @return [a, b, c] 或 null(当方程组没有确定解时) | |
*/ | |
public static double[] solution(Double[] terms) { | |
if (!isParamsValid(terms)) { | |
throw new IllegalArgumentException("参数需有且仅有三项不为null"); | |
} | |
Double apb = terms[0]; | |
Double amb = terms[1]; | |
Double apc = terms[2]; | |
Double amc = terms[3]; | |
Double bpc = terms[4]; | |
Double bmc = terms[5]; | |
boolean simpleSituation = false; | |
Double a = null, b = null, c = null; | |
if (apb != null && amb != null) { | |
double[] temp = TwoVariablesLinearEquations.solution(apb, amb); | |
a = temp[0]; | |
b = temp[1]; | |
apb = amb = null; | |
simpleSituation = true; | |
} else if (apc != null && amc != null) { | |
double[] temp = TwoVariablesLinearEquations.solution(apc, amc); | |
a = temp[0]; | |
c = temp[1]; | |
apc = amc = null; | |
simpleSituation = true; | |
} else if (bpc != null && bmc != null) { | |
double[] temp = TwoVariablesLinearEquations.solution(bpc, bmc); | |
b = temp[0]; | |
c = temp[1]; | |
bpc = bmc = null; | |
simpleSituation = true; | |
} | |
if (simpleSituation) { | |
if (apb != null) { | |
if (a == null) { a = apb - b; } | |
else { b = apb - a; } | |
} else if (amb != null) { | |
if (a == null) { a = amb + b; } | |
else { b = a - amb; } | |
} else if (apc != null) { | |
if (a == null) { a = apc - c; } | |
else { c = apc - a; } | |
} else if (amc != null) { | |
if (a == null) { a = amc + c; } | |
else { c = a - amc; } | |
} else if (bpc != null) { | |
if (b == null) { b = bpc - c; } | |
else { c = bpc - b; } | |
} else if (bmc != null) { | |
if (b == null) { b = bmc + c; } | |
else { c = b - bmc; } | |
} | |
return new double[] {a, b, c}; | |
} | |
if (apb != null) { | |
if (apc != null) { | |
if (bpc != null) { | |
amb = apc - bpc; | |
double[] temp = TwoVariablesLinearEquations.solution(apb, amb); | |
a = temp[0]; | |
b = temp[1]; | |
c = apc - a; | |
} else { // bmc != null | |
return null; // 由其中两项可以推出第三项。下同。 | |
} | |
} else { // amc != null | |
if (bpc != null) { | |
return null; | |
} else { // bmc != null | |
amb = amc - bmc; | |
double[] temp = TwoVariablesLinearEquations.solution(apb, amb); | |
a = temp[0]; | |
b = temp[1]; | |
c = a - amc; | |
} | |
} | |
} else { // amb != null | |
if (apc != null) { | |
if (bpc != null) { | |
return null; | |
} else { // bmc != null | |
apb = apc + bmc; | |
double[] temp = TwoVariablesLinearEquations.solution(apb, amb); | |
a = temp[0]; | |
b = temp[1]; | |
c = apc - a; | |
} | |
} else { // amc != null | |
if (bpc != null) { | |
apb = amc + bpc; | |
double[] temp = TwoVariablesLinearEquations.solution(apb, amb); | |
a = temp[0]; | |
b = temp[1]; | |
c = a - amc; | |
} else { // bmc != null | |
return null; | |
} | |
} | |
} | |
return new double[] {a, b, c}; | |
} | |
private static boolean isParamsValid(Double[] terms) { | |
if (terms == null || terms.length != 6) { | |
return false; | |
} | |
int count = 0; | |
for (Double term : terms) { | |
count += term != null ? 1 : 0; | |
} | |
return count == 3; | |
} | |
} | |
/** | |
* 解系数为1的四元一次方程组。 | |
*/ | |
class FourVariablesLinearEquations { | |
/** | |
* @param terms [apb, amb, apc, amc, apd, amd, bpc, bmc, bpd, bmd, cpd, cmd],其中: | |
* apb 是方程 a + b = m 的右值 | |
* amb 是方程 a - b = n 的右值 | |
* apc 是方程 a + c = o 的右值 | |
* amc 是方程 a - c = p 的右值 | |
* apd 是方程 a + d = q 的右值 | |
* amd 是方程 a - d = r 的右值 | |
* bpc 是方程 b + c = s 的右值 | |
* bmc 是方程 b - c = t 的右值 | |
* bpd 是方程 b + d = u 的右值 | |
* bmd 是方程 b - d = v 的右值 | |
* cpd 是方程 c + d = w 的右值 | |
* cmd 是方程 c - d = x 的右值 | |
* 以上需有且仅有四项不为null,且不可由其中任意两项推出第三项。需涵盖 a b c d 四个变量。 | |
* 注:可通过方程两边取反将 b - a = m 变为 a - b = -m 。 | |
* @return [a, b, c, d] 或 null(当方程组没有确定解时) | |
*/ | |
public static double[] solution(Double[] terms) { | |
if (!isParamsValid(terms)) { | |
throw new IllegalArgumentException("参数需有且仅有四项不为null"); | |
} | |
Double apb = terms[0]; | |
Double amb = terms[1]; | |
Double apc = terms[2]; | |
Double amc = terms[3]; | |
Double apd = terms[4]; | |
Double amd = terms[5]; | |
Double bpc = terms[6]; | |
Double bmc = terms[7]; | |
Double bpd = terms[8]; | |
Double bmd = terms[9]; | |
Double cpd = terms[10]; | |
Double cmd = terms[11]; | |
Double a = null, b = null, c = null, d = null; | |
if (apb != null && amb != null && cpd != null && cmd != null) { | |
double[] temp = TwoVariablesLinearEquations.solution(apb, amb); | |
a = temp[0]; | |
b = temp[1]; | |
temp = TwoVariablesLinearEquations.solution(cpd, cmd); | |
c = temp[0]; | |
d = temp[1]; | |
return new double[] {a, b, c, d}; | |
} | |
if (apc != null && amc != null && bpd != null && bmd != null) { | |
double[] temp = TwoVariablesLinearEquations.solution(apc, amc); | |
a = temp[0]; | |
c = temp[1]; | |
temp = TwoVariablesLinearEquations.solution(bpd, bmd); | |
b = temp[0]; | |
d = temp[1]; | |
return new double[] {a, b, c, d}; | |
} | |
if (apd != null && amd != null && bpc != null && bmc != null) { | |
double[] temp = TwoVariablesLinearEquations.solution(apd, amd); | |
a = temp[0]; | |
d = temp[1]; | |
temp = TwoVariablesLinearEquations.solution(bpc, bmc); | |
b = temp[0]; | |
c = temp[1]; | |
return new double[] {a, b, c, d}; | |
} | |
boolean computed = false; | |
int nonNullCount = 0; | |
Double[] termsWithoutD = new Double[] {apb, amb, apc, amc, bpc, bmc}; | |
nonNullCount = nonNullCount(termsWithoutD); | |
if (nonNullCount == 4) { return null; } | |
if (nonNullCount == 3) { | |
double[] temp = ThreeVariablesLinearEquations.solution(termsWithoutD); | |
if (temp == null) { return null; } | |
a = temp[0]; | |
b = temp[1]; | |
c = temp[2]; | |
apb = amb = apc = amc = bpc = bmc = null; | |
computed = true; | |
} | |
if (!computed) { | |
Double[] termsWithoutC = new Double[] {apb, amb, apd, amd, bpd, bmd}; | |
nonNullCount = nonNullCount(termsWithoutC); | |
if (nonNullCount == 4) { return null; } | |
if (nonNullCount == 3) { | |
double[] temp = ThreeVariablesLinearEquations.solution(termsWithoutC); | |
if (temp == null) { return null; } | |
a = temp[0]; | |
b = temp[1]; | |
d = temp[2]; | |
apb = amb = apd = amd = bpd = bmd = null; | |
computed = true; | |
} | |
} | |
if (!computed) { | |
Double[] termsWithoutB = new Double[] {apc, amc, apd, amd, cpd, cmd}; | |
nonNullCount = nonNullCount(termsWithoutB); | |
if (nonNullCount == 4) { return null; } | |
if (nonNullCount == 3) { | |
double[] temp = ThreeVariablesLinearEquations.solution(termsWithoutB); | |
if (temp == null) { return null; } | |
a = temp[0]; | |
c = temp[1]; | |
d = temp[2]; | |
apc = amc = apd = amd = cpd = cmd = null; | |
computed = true; | |
} | |
} | |
if (!computed) { | |
Double[] termsWithoutA = new Double[] {bpc, bmc, bpd, bmd, cpd, cmd}; | |
nonNullCount = nonNullCount(termsWithoutA); | |
if (nonNullCount == 4) { return null; } | |
if (nonNullCount == 3) { | |
double[] temp = ThreeVariablesLinearEquations.solution(termsWithoutA); | |
if (temp == null) { return null; } | |
b = temp[0]; | |
c = temp[1]; | |
d = temp[2]; | |
bpc = bmc = bpd = bmd = cpd = cmd = null; | |
computed = true; | |
} | |
} | |
if (computed) { | |
if (apb != null) { | |
if (a == null) { a = apb - b; } | |
else { b = apb - a; } | |
} else if (amb != null) { | |
if (a == null) { a = amb + b; } | |
else { b = a - amb; } | |
} else if (apc != null) { | |
if (a == null) { a = apc - c; } | |
else { c = apc - a; } | |
} else if (amc != null) { | |
if (a == null) { a = amc + c; } | |
else { c = a - amc; } | |
} else if (apd != null) { | |
if (a == null) { a = apd - d; } | |
else { d = apd - a; } | |
} else if (amd != null) { | |
if (a == null) { a = amd + d; } | |
else { d = a - amd; } | |
} else if (bpc != null) { | |
if (b == null) { b = bpc - c; } | |
else { c = bpc - b; } | |
} else if (bmc != null) { | |
if (b == null) { b = bmc + c; } | |
else { c = b - bmc; } | |
} else if (bpd != null) { | |
if (b == null) { b = bpd - d; } | |
else { d = bpd - b; } | |
} else if (bmd != null) { | |
if (b == null) { b = bmd + d; } | |
else { d = b - bmd; } | |
} else if (cpd != null) { | |
if (c == null) { c = cpd - d; } | |
else { d = cpd - c; } | |
} else if (cmd != null) { | |
if (c == null) { c = cmd + d; } | |
else { d = c - cmd; } | |
} | |
return new double[] {a, b, c, d}; | |
} | |
if (apb == null && amb == null) { | |
// a - c - b - d 形成环,环上相邻两个未知数之间有且仅有一条方程。下同 | |
if (apc != null) { | |
if (apd != null) { | |
cmd = apc - apd; | |
} else { // amd != null | |
cpd = apc - amd; | |
} | |
} else { // amc != null | |
if (apd != null) { | |
cpd = apd - amc; | |
} else { // amd != null | |
cmd = amd - amc; | |
} | |
} | |
} else if (apc == null && amc == null) { | |
// a - b - c - d 形成环 | |
if (apb != null) { | |
if (apd != null) { | |
bmd = apb - apd; | |
} else { // amd != null | |
bpd = apb - amd; | |
} | |
} else { // amb != null | |
if (apd != null) { | |
bpd = apd - amb; | |
} else { // amd != null | |
bmd = amd - amb; | |
} | |
} | |
} else if (apd == null && amd == null) { | |
// a - b - d - c 形成环 | |
if (apb != null) { | |
if (apc != null) { | |
bmc = apb - apc; | |
} else { // amc != null | |
bpc = apb - amc; | |
} | |
} else { // amb != null | |
if (apc != null) { | |
bpc = apc - amb; | |
} else { // amc != null | |
bmc = amc - amb; | |
} | |
} | |
} | |
Double[] termsWithoutA = new Double[] {bpc, bmc, bpd, bmd, cpd, cmd}; | |
double[] temp = ThreeVariablesLinearEquations.solution(termsWithoutA); | |
if (temp == null) { return null; } | |
b = temp[0]; | |
c = temp[1]; | |
d = temp[2]; | |
if (apb != null || amb != null) { | |
a = apb != null ? apb - b : amb + b; | |
} else { | |
a = apc != null ? apc - c : amc + c; | |
} | |
return new double[] {a, b, c, d}; | |
} | |
private static boolean isParamsValid(Double[] terms) { | |
if (terms == null || terms.length != 12) { | |
return false; | |
} | |
return nonNullCount(terms) == 4; | |
} | |
private static int nonNullCount(Double[] nums) { | |
int count = 0; | |
for (Double num : nums) { | |
count += num != null ? 1 : 0; | |
} | |
return count; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment